package model

import (
	"database/sql/driver"
)

type (
	DeployType string
	// Cloud is the cloud DBaaS runs in. The laptop is "local"
	CloudProviderStatus string
	ProviderStatus      string
	RegionStatus        string
	ComponentName       string
	EventStatus         string
	TierChangeStatus    string
	ArchType            string
)

const (
	DeployTypeDedicated DeployType = "dedicated"
	DeployTypeShared    DeployType = "shared"

	ProviderStatusActive   CloudProviderStatus = "active"
	ProviderStatusInactive CloudProviderStatus = "inactive"
	RegionStatusActive     RegionStatus        = "active"
	RegionStatusInactive   RegionStatus        = "inactive"

	PD      ComponentName = "pd"      // Placement Driver
	TiKV    ComponentName = "tikv"    // TiKV
	TiDB    ComponentName = "tidb"    // TiDB
	TiFlash ComponentName = "tiflash" // TiFlash
	TiCDC   ComponentName = "ticdc"   // TiCDC
	TiProxy ComponentName = "tiproxy" // TiProxy

	TierChangeStatusCreated TierChangeStatus = "created" // this tier change has been created but some action need to be done
	TierChangeStatusApplied TierChangeStatus = "applied" // this tier change has been applied

	EventStatusCreated EventStatus = "created"
	EventStatusSent    EventStatus = "sent"

	// cluster have Readable/Writeable status in db record
	// uint64 means we can use this flag to control 64 unrelative status
	// 1 (1 << 0) means cluster is read only (from cluster to db). 2 (1 << 1) means cluster need to force to read only (from db to cluster)
	ForceReadOnlyStatus uint64 = 1 << 1
	ReadOnlyStatus      uint64 = 1 << 0

	// SaltLength is the length of salt
	SaltLength = 8
)

type (
	// enum
	TenantStatus          string
	ProjectStatus         string
	TenantPlan            string
	NotificationScene     string
	TenantKind            string
	ClusterStatus         string
	UserStatus            string
	UserRole              string
	ImportStatus          string
	ClusterConnectionType string
	TrafficFilterStatus   string

	PeeringType             string
	PrivateLinkEndpointType string

	TrialType         string
	DevTierIdleStage  string // the idle stage of dev tier, such as: warning, shutdown
	DevTierTrialStage string // the ending stage of dev tier, such as: one-month before end
	DataFormat        uint32
	DataSource        uint32
	PeeringStatus     string // the status of aws/gcp vpc peering

	ClusterOperationType                       string
	ClusterOperationStatus                     string
	ScaleOperationTrackingStatus               string
	XAccountDeployStatus                       string
	MaintenanceTaskStatus                      string
	MaintenanceTaskExecutionStatus             string
	MaintenanceTaskNotificationPhase           string
	MaintenanceTaskExecutionCancellationReason string

	DiscountType      uint32
	KafkaProtocolType string
	// Cloud is the cloud DBaaS runs in. The laptop is "local"
	Cloud string

	// Integration types
	IntegrationType    string
	IntegrationStatus  string
	IntegrationPayload string
	DatadogSite        string
)

func (s ImportStatus) String() string {
	return string(s)
}

// enums
const (
	ClusterConnectionTypePrivate ClusterConnectionType = "private"
	ClusterConnectionTypePublic  ClusterConnectionType = "public"

	TrafficFilterStatusSynced   TrafficFilterStatus = "synced"
	TrafficFilterStatusUnsynced TrafficFilterStatus = "unsynced"

	// ClusterStatusInitializing initialize the infra.
	ClusterStatusInitializing ClusterStatus = "initializing"
	// ClusterStatusPreparing provisioning nodes
	ClusterStatusPreparing               ClusterStatus = "preparing"
	ClusterStatusVolumeSnapshotRestoring ClusterStatus = "volume_snapshot_restoring"
	// ClusterStatusLaunching set up the tidb cluster
	ClusterStatusLaunching ClusterStatus = "launching"
	ClusterStatusNormal    ClusterStatus = "normal"
	// Deprecated: This status is no longer used
	ClusterStatusHibernated ClusterStatus = "hibernated"
	ClusterStatusPausing    ClusterStatus = "pausing"
	ClusterStatusPaused     ClusterStatus = "paused"
	ClusterStatusResuming   ClusterStatus = "resuming"
	ClusterStatusScaling    ClusterStatus = "scaling"
	// ClusterStatusUpgrading  ClusterStatus = "upgrading"
	ClusterStatusRecovering ClusterStatus = "recovering"
	// ClusterStatusDeleted indicate cluster is deleting, cluster
	// worker will list cluster in deleted status, then delete all resources
	ClusterStatusDeleted ClusterStatus = "deleted"
	// ClusterStatusCleared indicate all reosurce already clean up
	ClusterStatusCleared ClusterStatus = "cleared"
	// ClusterStatusDeletecomplete indicate cluster resources already deleted, but backup cleanup worker still in the process
	ClusterStatusDeletecomplete ClusterStatus = "deletecomplete"

	TenantStatusPending  TenantStatus = "pending"
	TenantStatusActive   TenantStatus = "active"
	TenantStatusInactive TenantStatus = "inactive"
	TenantStatusDeleted  TenantStatus = "deleted"
	TenantStatusCleared  TenantStatus = "cleared"

	TenantPlanNewUser   TenantPlan = "new_user"
	TenantPlanFreeTrial TenantPlan = "free_trial"
	TenantPlanPOC       TenantPlan = "poc"
	TenantPlanOnDemand  TenantPlan = "on_demand"

	ProjectStatusActive  ProjectStatus = "active"
	ProjectStatusDeleted ProjectStatus = "deleted"
	ProjectStatusCleared ProjectStatus = "cleared"

	DevTierTrialStageNormal           DevTierTrialStage = "normal" // farthest to end
	DevTierTrialStageCloseToEndStage1 DevTierTrialStage = "close_to_end_stage1"
	DevTierTrialStageCloseToEndStage2 DevTierTrialStage = "close_to_end_stage2"
	DevTierTrialStageEnd              DevTierTrialStage = "end"

	DevTierIdleStageActive    DevTierIdleStage = "active"
	DevTierIdleStageEncourage DevTierIdleStage = "encourage"
	DevTierIdleStageWarning   DevTierIdleStage = "warning"
	DevTierIdleStageShutdown  DevTierIdleStage = "shutdown"

	NotificationSceneOptional                 NotificationScene = "optional"
	NotificationSceneOptional2                NotificationScene = "optional2" // secondary welcome email
	NotificationScenePocWillEnd               NotificationScene = "poc_will_end"
	NotificationScenePocClusterWillEndIn3Days NotificationScene = "poc_cluster_will_end_in_3_days"
	NotificationScenePocClusterEnd            NotificationScene = "poc_cluster_end"
	NotificationScenePocEndBackupWillDelete   NotificationScene = "poc_end_backup"
	NotificationSceneClusterNetworkThreshold  NotificationScene = "cluster_network_threshold"
	NotificationSceneDevTierTrial             NotificationScene = "dev_tier_trial"
	NotificationSceneDevTierIdle              NotificationScene = "dev_tier_idle"
	TenantKindInternal                        TenantKind        = "internal"
	TenantKindExternal                        TenantKind        = "external"

	DataSourceTypeUnknown DataSource = 0
	DataSourceTypeS3      DataSource = 1
	DataSourceTypeGCS     DataSource = 2

	PingCAPTenantID ID = 1

	ClusterOperationTypeScale       ClusterOperationType         = "scale"
	ClusterOperationStatusCreated   ClusterOperationStatus       = "created"
	ClusterOperationStatusDone      ClusterOperationStatus       = "done"
	ScaleOperationTrackingScaleInit ScaleOperationTrackingStatus = "scale-init"
	ScaleOperationTrackingScalePod  ScaleOperationTrackingStatus = "scale-pod"
	ScaleOperationTrackingScaleNode ScaleOperationTrackingStatus = "scale-node"
	ScaleOperationTrackingDone      ScaleOperationTrackingStatus = "done"

	XAccountDeployStatusActive   XAccountDeployStatus = "active"
	XAccountDeployStatusDeleting XAccountDeployStatus = "deleting"

	//Peering Type
	PeeringTypeDBaaS            PeeringType = "dbaas"
	PeeringTypeCustomer         PeeringType = "customer"
	PeeringTypeCustomerReadOnly PeeringType = "customer_readonly"

	// Private link endpoint type
	PrivateLinkEndpointDBaaS    PrivateLinkEndpointType = "dbaas"
	PrivateLinkEndpointCustomer PrivateLinkEndpointType = "customer"

	MaintenanceTaskStatusPending MaintenanceTaskStatus = "pending"
	MaintenanceTaskStatusRunning MaintenanceTaskStatus = "running"
	MaintenanceTaskStatusDone    MaintenanceTaskStatus = "done"

	MaintenanceTaskNotificationPhase2WeeksAgo  MaintenanceTaskNotificationPhase = "2_weeks_ago"
	MaintenanceTaskNotificationPhase72HoursAgo MaintenanceTaskNotificationPhase = "72_hours_ago"
	MaintenanceTaskNotificationPhaseStarted    MaintenanceTaskNotificationPhase = "started"
	MaintenanceTaskNotificationPhaseCompleted  MaintenanceTaskNotificationPhase = "completed"
	MaintenanceTaskNotificationPhaseNone       MaintenanceTaskNotificationPhase = ""

	MaintenanceTaskExecutionStatusPending   MaintenanceTaskExecutionStatus = "pending"
	MaintenanceTaskExecutionStatusRunning   MaintenanceTaskExecutionStatus = "running"
	MaintenanceTaskExecutionStatusDone      MaintenanceTaskExecutionStatus = "done"
	MaintenanceTaskExecutionStatusCancelled MaintenanceTaskExecutionStatus = "canceled"

	MaintenanceTaskExecutionCancellationReasonOpsCanceled    MaintenanceTaskExecutionCancellationReason = "ops_canceled"
	MaintenanceTaskExecutionCancellationReasonClusterDeleted MaintenanceTaskExecutionCancellationReason = "cluster_deleted"
)

const (
	// Gcp is the GCP cloud
	Gcp = Cloud("gcp")

	// Aws is the AWS cloud
	Aws = Cloud("aws")
)

// Scan is for gorm
func (u *Cloud) Scan(value interface{}) error {
	*u = Cloud(value.([]byte))
	return nil
}

// Value is for gorm
func (u Cloud) Value() (driver.Value, error) { return string(u), nil }

func (u Cloud) String() string {
	return string(u)
}

func IsValidProvider(provider Cloud) bool {
	switch provider {
	case Aws, Gcp:
		return true
	default:
		return false
	}
}
