package schema

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

	"gorm.io/gorm"
)

type Cluster struct {
	Versioned

	ID               uint64 `gorm:"primaryKey;not null"`
	CreatedAt        time.Time
	UpdatedAt        time.Time
	DeletedAt        gorm.DeletedAt `gorm:"index"`
	CreateFinishedAt sql.NullTime

	TenantId  uint64 `gorm:"index:name_tenant;not null"`
	ProjectId uint64 `gorm:"not null;default:0"`

	CreationFinishedAt                *time.Time        `gorm:"type:TIMESTAMP NULL;creation_finished_at; default '0000-00-00 00:00:00'"`
	EncryptedPlatformAdminPassword    string            `gorm:"type:VARCHAR(1024);not null;default ''"`
	EncryptedMaintenanceAdminPassword string            `gorm:"type:VARCHAR(1024);not null;default ''"`
	EncryptedCloudAdminPassword       string            `gorm:"type:VARCHAR(1024);not null;default ''"`
	EncryptedRootPassword             string            `gorm:"type:VARCHAR(1024);default ''"`
	HasSetPwd                         bool              `gorm:"default:false"`
	Attributes                        ClusterAttributes `gorm:"type:JSON;not null"`

	ProviderId uint64 `gorm:"not null"`
	// Provider   *Provider `gorm:"foreignkey:ProviderId"`
	RegionId uint64 `gorm:"not null"`
	// Region   *Region `gorm:"foreignkey:RegionId"`
	EncryptionKeyId uint64 `gorm:"not null;default:0"`

	State                      string `gorm:"index"`
	Version                    string `gorm:"type:VARCHAR(255)"`
	ServicePlan                string `gorm:"type:VARCHAR(255);default:''"`
	HighAvailabilityType       string `gorm:"type:VARCHAR(255);default:''"`
	SharedPoolId               string `gorm:"index;type:VARCHAR(255);default:''"`
	ReservedCapacityTemplateId uint64 `gorm:"not null;default:0;index"`

	MinRcu               int64      `gorm:"default:0"`
	MaxRcu               int64      `gorm:"default:0"`
	CapacityUpdatedAt    *time.Time `gorm:"type:TIMESTAMP NULL;capacity_updated_at"`
	PlanReplayerExpireAt *time.Time `gorm:"type:TIMESTAMP(3) NULL;index"`

	RuVersion int32 `gorm:"not null;default:1"` // DB default 1 for existing clusters; new clusters get value from request

	Provider *Provider `gorm:"foreignkey:ProviderId"`
	Region   *Region   `gorm:"foreignkey:RegionId"`
}

type ClusterAttributes struct {
	TokenBasedAuthEnabled   bool `json:"token_based_auth_enabled"`
	WithBuiltinCDCAdminRole bool `json:"with_builtin_cdc_admin_role"`
}

// Value marshal json
func (c ClusterAttributes) Value() (driver.Value, error) {
	b, err := json.Marshal(c)
	return string(b), err
}

// Scan unmarshal json
func (c *ClusterAttributes) Scan(input any) error {
	return json.Unmarshal(input.([]byte), c)
}
