package schema

import (
	"database/sql/driver"
	"encoding/json"

	"gorm.io/gorm"
)

// AuditLogSetting represents the audit log configuration for a cluster
type AuditLogSetting struct {
	gorm.Model

	ClusterID         uint64 `gorm:"index:,unique"`
	Enabled           bool   `gorm:"default:false"`
	BucketURI         string
	BucketRegion      string
	CloudRoleIdentity string
	ExternalID        string
	BucketManager     string `gorm:"type:ENUM('CUSTOMER','PINGCAP');default:'CUSTOMER'"`
	Redacted          bool   `gorm:"default:false"`
	Format            string `gorm:"type:ENUM('TEXT','JSON');default:'TEXT'"`
	MaxSizeMib        int32
	MaxAgeSecond      int32

	Cluster *Cluster // Association with the Cluster model
}

// AuditLogFilterRule represents a filtering rule for audit logs
type AuditLogFilterRule struct {
	gorm.Model

	ClusterID   uint64 `gorm:"index:cluster_user_expr,unique"`
	UserExpr    string `gorm:"index:cluster_user_expr,unique;index"`
	DisplayName string
	Enabled     bool           `gorm:"default:true"`
	TableExpr   stringLiterals `gorm:"type:JSON"`
	EventTypes  stringLiterals `gorm:"type:JSON"`
	StatusCodes numbers        `gorm:"type:JSON"`

	Cluster *Cluster // Association with the Cluster model
}

// EventTypes represents the list of event types to be audited
type stringLiterals []string

// Value implements the driver.Valuer interface for EventTypes
func (e stringLiterals) Value() (driver.Value, error) {
	b, err := json.Marshal(e)
	return string(b), err
}

// Scan implements the sql.Scanner interface for EventTypes
func (e *stringLiterals) Scan(input any) error {
	return json.Unmarshal(input.([]byte), e)
}

type numbers []int32

func (e numbers) Value() (driver.Value, error) {
	b, err := json.Marshal(e)
	return string(b), err
}

func (e *numbers) Scan(input any) error {
	return json.Unmarshal(input.([]byte), e)
}
