package k8supgrade

import (
	"fmt"
	"time"
)

type K8sInfoList struct {
	Items []*K8sInfo `json:"items"`
	// Timestamp is the time when the list is generated.
	Timestamp int64 `json:"timestamp"`
	// Total is the number of items.
	Total int `json:"total"`
}

type K8sInfo struct {
	CloudProvider        string                  `json:"cloud_provider"`
	CloudAccount         string                  `json:"cloud_account"`
	Region               string                  `json:"region"`
	ProjectID            string                  `json:"project_id"`
	TenantID             string                  `json:"tenant_id"`
	TenantName           string                  `json:"tenant_name"`
	TenantKind           string                  `json:"tenant_kind"`
	BusinessRegion       string                  `json:"business_region"`
	K8sName              string                  `json:"k8s_name"`
	ControlPlaneVersion  Version                 `json:"control_plane_version"`
	TiDBClusters         []*TiDBClusterInfraInfo `json:"clusters"`
	NumberOfTiDBClusters int                     `json:"number_of_tidb_clusters"`
	AdminNodes           []*Node                 `json:"admin_nodes"`
	Is3LayerArch         bool                    `json:"is_3_layer_arch"`
	AppboxName           string                  `json:"appbox_name"`
	AppboxNamespace      string                  `json:"appbox_namespace"`
	O11YK8SNodes         []*Node                 `json:"o11y_k8s_nodes"`
}

func (info *K8sInfo) GetNetworkName() string {
	switch info.CloudProvider {
	case "aws":
		return fmt.Sprintf("eks-%s", info.Region)
	case "gcp":
		return fmt.Sprintf("gke-%s", info.Region)
	}
	return ""
}

type TiDBClusterInfraInfo struct {
	ID      string `json:"id"`
	Version string `json:"version"`
	Status  string `json:"status"`
	Name    string `json:"name"`

	// key: component type, value: replicas
	Topology       map[string]int `json:"topology"`
	ComponentNodes []*Node        `json:"component_nodes"`
	Notes          []string       `json:"notes"`
}

type Node struct {
	// admin-nodes, tidb-nodes, cdc-nodes, dm-nodes, o11y-k8s-nodes, o11y-tidb-nodes
	Kind    string  `json:"kind"`
	Count   int     `json:"count"`
	Version Version `json:"version"`
	// MaxSkewVersion is the max version of the node group behind the control plane's version.
	MaxSkewVersion int `json:"max_skew_version"`
}

func (n *Node) DeepCopy() *Node {
	return &Node{
		Kind:           n.Kind,
		Count:          n.Count,
		Version:        n.Version,
		MaxSkewVersion: n.MaxSkewVersion,
	}
}

const (
	MaintenancePolicyModeLegacy             = "legacy"
	MaintenancePolicyModeClusterMaintenance = "cluster-maintenance"
)

type UpgradeOperation struct {
	Name                  string                  `yaml:"name"`
	Namespace             string                  `yaml:"namespace"`
	AppboxName            string                  `yaml:"appboxName"`
	Schedule              string                  `yaml:"schedule"`
	Duration              string                  `yaml:"duration"`
	TTL                   string                  `yaml:"ttl"`
	MaintenancePolicyMode string                  `yaml:"maintenancePolicyMode,omitempty"`
	Annotations           map[string]string       `yaml:"annotations,omitempty"`
	Steps                 []*UpgradeStep          `yaml:"steps,omitempty"`
	Status                *UpgradeOperationStatus `yaml:"status,omitempty"`
}

type UpgradeStep struct {
	Target    string            `yaml:"target"`
	Version   string            `yaml:"version"`
	ClusterId string            `yaml:"cluster_id,omitempty"`
	Options   map[string]string `yaml:"options,omitempty"`
}

type UpgradeOperationStatus struct {
	Phase     string     `yaml:"phase"`
	Reason    string     `yaml:"reason"`
	BeginTime *time.Time `yaml:"begin_time,omitempty"`
	EndTime   *time.Time `yaml:"end_time,omitempty"`
}
