package client

import (
	"time"

	prometheusv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
	EventTypeClusterCreated = "CLUSTER_CREATED"
	EventTypeClusterUpdated = "CLUSTER_UPDATED"
	EventTypeClusterDeleted = "CLUSTER_DELETED"
	EventTypeUnknown        = "UNKNOWN"
	EventStatusPending      = "PENDING"
	EventStatusProcessing   = "PROCESSING"
	EventStatusDone         = "DONE"
)

type ClusterEvent struct {
	EventID         uint64     `gorm:"primaryKey;autoIncrement"`
	Namespace       string     `gorm:"column:namespace;index:idx_namespace_name,priority:1;type:varchar(64)"`
	Name            string     `gorm:"column:name;index:idx_namespace_name,priority:2;type:varchar(64)"`
	EventType       string     `gorm:"column:event_type;type:varchar(32)"`                                    // CLUSTER_CREATED, CLUSTER_UPDATED, CLUSTER_DELETED, UNKNOWN
	Status          string     `gorm:"column:status;index:idx_status_created_at,priority:1;type:varchar(32)"` // PENDING, PROCESSING, DONE
	CreatedAt       time.Time  `gorm:"column:created_at;index:idx_status_created_at,priority:2;autoCreateTime"`
	UpdatedAt       time.Time  `gorm:"column:updated_at;autoUpdateTime"`
	TTLExpiration   *time.Time `gorm:"column:ttl_expiration;index:idx_ttl_expiration"`
	SourceComponent string     `gorm:"column:source_component;type:varchar(64)"`
	ResourceVersion uint64     `gorm:"column:resource_version;type:bigint unsigned"`
}

// Cluster contains the primary and basic fields of a cluster.
type Cluster struct {
	ClusterID         string     `gorm:"column:cluster_id;type:varchar(64);primaryKey" json:"cluster_id"`
	Namespace         string     `gorm:"column:namespace;type:varchar(64)" json:"namespace"`
	Region            string     `gorm:"column:region;type:varchar(64)" json:"region"`
	BizType           string     `gorm:"column:biz_type;type:varchar(64);uniqueIndex:idx_biz_tenant_project_app,priority:1" json:"biz_type"`
	Tenant            string     `gorm:"column:tenant;type:varchar(64);uniqueIndex:idx_biz_tenant_project_app,priority:2" json:"tenant"`
	ProjectID         string     `gorm:"column:project_id;type:varchar(64);uniqueIndex:idx_biz_tenant_project_app,priority:3" json:"project_id"`
	ApplicationID     string     `gorm:"column:application_id;type:varchar(64);uniqueIndex:idx_biz_tenant_project_app,priority:4;index:idx_application_id" json:"application_id"`
	RuleTemplateID    string     `gorm:"column:rule_template_id;type:varchar(64);index:idx_rule_template_id" json:"rule_template_id"`
	DeletionTimestamp *time.Time `gorm:"column:deletion_timestamp;type:timestamp(6);default:null" json:"deletion_timestamp,omitempty"`

	// Updated by mysql
	CreationTimestamp time.Time `gorm:"column:creation_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6)" json:"creation_timestamp"`
	UpdateTimestamp   time.Time `gorm:"column:update_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" json:"update_timestamp"`

	Spec   ClusterSpec   `gorm:"foreignKey:ClusterID;references:ClusterID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"spec"`
	Status ClusterStatus `gorm:"foreignKey:ClusterID;references:ClusterID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"status"`
}

// ClusterSpec contains all spec related fields
type ClusterSpec struct {
	// Primary Key reference to Cluster
	ClusterID string `gorm:"column:cluster_id;type:varchar(64);primaryKey" json:"cluster_id"`

	Labels      map[string]string `gorm:"column:labels;type:json;serializer:json" json:"labels"`
	Annotations map[string]string `gorm:"column:annotations;type:json;serializer:json" json:"annotations"`

	EndpointServiceName    string `gorm:"column:endpoint_service_name;type:varchar(64)" json:"endpoint_service_name"`
	EndpointServiceUserARN string `gorm:"column:endpoint_service_user_arn;type:varchar(64)" json:"endpoint_service_user_arn"`
	EndpointServiceShared  bool   `gorm:"column:endpoint_service_shared" json:"endpoint_service_shared"`

	MuteAlert            bool                                 `gorm:"column:mute_alert" json:"mute_alert"`
	VMAccountID          int32                                `gorm:"column:vm_account_id" json:"vm_account_id"`
	VMProjectID          int32                                `gorm:"column:vm_project_id" json:"vm_project_id"`
	VMSupportServerless  bool                                 `gorm:"column:vm_support_serverless" json:"vm_support_serverless"`
	VMAlertMaxQueueSize  int32                                `gorm:"column:vm_alert_max_queue_size" json:"vm_alert_max_queue_size"`
	VMClusterName        string                               `gorm:"column:vm_cluster_name;type:varchar(64)" json:"vm_cluster_name"`
	VMAvailabilityZone   string                               `gorm:"column:vm_availability_zone;type:varchar(64)" json:"vm_availability_zone"`
	VMRuleSelector       metav1.LabelSelector                 `gorm:"column:vm_rule_selector;type:json;serializer:json" json:"vm_rule_selector,omitempty"`
	VMAlertCPURequest    string                               `gorm:"column:vm_alert_cpu_request;type:varchar(32)" json:"vm_alert_cpu_request,omitempty"`
	VMAlertCPULimit      string                               `gorm:"column:vm_alert_cpu_limit;type:varchar(32)" json:"vm_alert_cpu_limit,omitempty"`
	VMAlertMemoryRequest string                               `gorm:"column:vm_alert_memory_request;type:varchar(32)" json:"vm_alert_memory_request,omitempty"`
	VMAlertMemoryLimit   string                               `gorm:"column:vm_alert_memory_limit;type:varchar(32)" json:"vm_alert_memory_limit,omitempty"`
	VMAlertManagers      []prometheusv1.AlertmanagerEndpoints `gorm:"column:vm_alert_managers;type:json;serializer:json" json:"vm_alert_managers,omitempty"`

	// Updated by mysql
	CreationTimestamp time.Time `gorm:"column:creation_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6)" json:"creation_timestamp"`
	UpdateTimestamp   time.Time `gorm:"column:update_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" json:"update_timestamp"`
}

// ClusterStatus contains all status related fields
type ClusterStatus struct {
	// Primary Key reference to Cluster
	ClusterID       string `gorm:"column:cluster_id;type:varchar(64);primaryKey" json:"cluster_id"`
	Phase           string `gorm:"column:phase;type:varchar(64)" json:"phase"`
	ServiceName     string `gorm:"column:service_name;type:varchar(255)" json:"service_name"`
	DNSName         string `gorm:"column:dns_name;type:varchar(255)" json:"dns_name"`
	UpdateAt        string `gorm:"column:update_at;type:varchar(64)" json:"update_at"`
	ResourceVersion uint64 `gorm:"column:resource_version;type:bigint unsigned" json:"resource_version"`

	// Updated by mysql
	CreationTimestamp time.Time `gorm:"column:creation_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6)" json:"creation_timestamp"`
	UpdateTimestamp   time.Time `gorm:"column:update_timestamp;type:timestamp(6);not null;default:CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)" json:"update_timestamp"`
}
