package schema

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

	"gorm.io/gorm"
)

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

	ClusterID     uint64 `gorm:"index:,unique"`
	Enabled       bool   `gorm:"default:false"`
	BucketURI     string
	BucketRegion  string
	AWSRoleARN    string
	AzureSASToken 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)
}
