package message

import (
	"time"

	o11yv1 "github.com/tidbcloud/observability/api/regionalserver/resourceworker/v1"
)

// Cluster Upgrade Request/Response structures

// NodeGroupUpgradeConfig binds node group tag selector with upgrade strategy
type NodeGroupUpgradeConfig struct {
	// NodeGroupName is the name of the node group to upgrade
	NodeGroupName string `json:"nodeGroupName" validate:"required"`

	// RuntimeType is the current Kubernetes runtime type of the node group
	RuntimeType string `json:"runtimeType,omitempty"`

	// TargetRuntimeVersion is the target Kubernetes runtime version to upgrade to
	TargetRuntimeVersion string `json:"targetRuntimeVersion,omitempty"`

	// NewNodeGroupName is the name for the new node group in blue-green upgrade. Optional; if empty, a random 8-char lowercase name is used.
	NewNodeGroupName string `json:"newNodeGroupName,omitempty"`

	// RequiresVMStorageRollout indicates if this blue-green node group upgrade should trigger the VMStorage rollout flow
	RequiresVMStorageRollout bool `json:"requiresVMStorageRollout" validate:"required,boolean" default:"false"`

	// Strategy is the upgrade strategy for nodegroups ("blue-green" or "in-place")
	Strategy o11yv1.NodeGroupUpgradeStrategy `json:"strategy" validate:"required,oneof=blue-green in-place"`

	// VMStorageSTSName is the name of the vmstorage StatefulSet to observe rollout status
	VMStorageSTSName string `json:"vmstorageSTSName,omitempty" default:"vmstorage-vmcluster"`

	// VMStorageSTSNamespace is the namespace of the vmstorage StatefulSet to observe rollout status
	VMStorageSTSNamespace string `json:"vmstorageSTSNamespace,omitempty" default:"observability"`

	// VMClusterHelmValues contains a VMCluster.spec overlay to apply during VMStorage rollout.
	// Use an empty object when the rollout should not change VMCluster spec.
	VMClusterHelmValues map[string]interface{} `json:"vmClusterHelmValues,omitempty"`

	// LaunchTemplateVersion is required for EKS in-place upgrades when the node group's launch template specifies a custom AMI.
	LaunchTemplateVersion string `json:"launchTemplateVersion,omitempty"`
	// LaunchTemplateId identifies the EKS launch template to use for the in-place upgrade.
	LaunchTemplateId string `json:"launchTemplateId,omitempty"`
	// LaunchTemplateName identifies the EKS launch template when launchTemplateId is not provided.
	LaunchTemplateName string `json:"launchTemplateName,omitempty"`
}

// CreateClusterUpgradeReq represents the request to create a cluster upgrade operation
type CreateClusterUpgradeReq struct {
	// K8sClusterName is the name of the target Kubernetes cluster
	K8sClusterName string `json:"k8sClusterName" validate:"required"`

	// Region is the cloud region where the cluster is located
	Region string `json:"region" validate:"required"`

	// CloudProvider is the cloud provider type (eks, gke, aks, ack, mock)
	CloudProvider o11yv1.CloudProvider `json:"cloudProvider" validate:"required,oneof=eks gke aks ack mock"`

	// TargetVersion is the target K8s version to upgrade to
	TargetVersion string `json:"targetVersion" validate:"required"`

	// Schedule is the time to start the upgrade (optional, defaults to now)
	Schedule *time.Time `json:"schedule,omitempty"`

	// NodeGroupUpgrade configures node group upgrade with node group name and strategy bound together
	NodeGroupUpgrades []NodeGroupUpgradeConfig `json:"nodeGroupUpgrades,omitempty"`

	// ClusterAddons is the list of addons to upgrade
	ClusterAddons []AddonUpgradeConfig `json:"clusterAddons,omitempty"`
}

// AddonUpgradeConfig defines an addon to upgrade
type AddonUpgradeConfig struct {
	Name    string `json:"name" validate:"required"`
	Version string `json:"version" validate:"required"`

	// ConfigurationValues is a string containing the set of configuration values for the add-on.
	// Values are validated against the schema returned by DescribeAddonConfiguration.
	ConfigurationValues string `json:"configurationValues,omitempty"`

	// ResolveConflicts specifies how to handle field value conflicts if you've changed a value from the AWS EKS default.
	// NONE means AWS EKS doesn't change the value (update might fail)
	// OVERWRITE means AWS EKS overwrites the changed value back to the default
	// PRESERVE means AWS EKS preserves the changed value
	ResolveConflicts string `json:"resolveConflicts,omitempty" validate:"omitempty,oneof=NONE OVERWRITE PRESERVE"`

	// ServiceAccountRoleArn is the Amazon Resource Name (ARN) of an existing IAM role to bind to the add-on's service account.
	// The role must have the IAM permissions required by the add-on.
	ServiceAccountRoleArn string `json:"serviceAccountRoleArn,omitempty"`
}

// CreateClusterUpgradeResp represents the response after creating a cluster upgrade
type CreateClusterUpgradeResp struct {
	ID      string `json:"id"`
	Status  string `json:"status"`
	Message string `json:"message"`
}

// GetClusterUpgradeReq represents the request to get a specific cluster upgrade
type GetClusterUpgradeReq struct {
	ID string `json:"id" validate:"required"`
}

// GetClusterUpgradeResp represents the response with cluster upgrade details
type GetClusterUpgradeResp struct {
	ID             string       `json:"id"`
	Name           string       `json:"name"`
	K8sClusterName string       `json:"k8sClusterName"`
	Region         string       `json:"region"`
	CloudProvider  string       `json:"cloudProvider"`
	CurrentVersion string       `json:"currentVersion"`
	TargetVersion  string       `json:"targetVersion"`
	Status         string       `json:"status"`
	CurrentStep    *StepStatus  `json:"currentStep,omitempty"`
	SucceededSteps []StepStatus `json:"succeededSteps,omitempty"`
	NextSteps      []StepStatus `json:"nextSteps,omitempty"`
	BeginTime      *time.Time   `json:"beginTime,omitempty"`
	EndTime        *time.Time   `json:"endTime,omitempty"`
	Duration       string       `json:"duration,omitempty"`
}

// StepStatus represents the status of an upgrade step
type StepStatus struct {
	Processor string     `json:"processor"`
	Status    string     `json:"status,omitempty"`
	BeginTime *time.Time `json:"beginTime,omitempty"`
	EndTime   *time.Time `json:"endTime,omitempty"`
	Duration  string     `json:"duration,omitempty"`
}

// ListClusterUpgradesReq represents the request to list cluster upgrades
type ListClusterUpgradesReq struct {
	K8sClusterName string `json:"k8sClusterName,omitempty" form:"k8sClusterName"`
	Status         string `json:"status,omitempty" form:"status"`
	ContinueRequest
}

// ListClusterUpgradesResp represents the response with a list of cluster upgrades
type ListClusterUpgradesResp struct {
	ClusterUpgrades []ClusterUpgradeSummary `json:"clusterUpgrades"`
	ContinueResponse
}

// ClusterUpgradeSummary represents a summary of cluster upgrade info for listing
type ClusterUpgradeSummary struct {
	ID             string     `json:"id"`
	Name           string     `json:"name"`
	K8sClusterName string     `json:"k8sClusterName"`
	CloudProvider  string     `json:"cloudProvider"`
	CurrentVersion string     `json:"currentVersion"`
	TargetVersion  string     `json:"targetVersion"`
	Status         string     `json:"status"`
	BeginTime      *time.Time `json:"beginTime,omitempty"`
	EndTime        *time.Time `json:"endTime,omitempty"`
}

// PauseClusterUpgradeReq represents the request to pause a cluster upgrade
type PauseClusterUpgradeReq struct {
	ID string `json:"id" validate:"required"`
}

// PauseClusterUpgradeResp represents the response after pausing a cluster upgrade
type PauseClusterUpgradeResp struct {
	Message string `json:"message"`
}

// ResumeClusterUpgradeReq represents the request to resume a cluster upgrade
type ResumeClusterUpgradeReq struct {
	ID string `json:"id" validate:"required"`
}

// ResumeClusterUpgradeResp represents the response after resuming a cluster upgrade
type ResumeClusterUpgradeResp struct {
	Message string `json:"message"`
}

// DeleteClusterUpgradeReq represents the request to delete a cluster upgrade
type DeleteClusterUpgradeReq struct {
	ID string `json:"id" validate:"required"`
}

// DeleteClusterUpgradeResp represents the response after deleting a cluster upgrade
type DeleteClusterUpgradeResp struct {
	Message string `json:"message"`
}

// DryRunClusterUpgradeResp represents the response after dry-running a cluster upgrade request
// It returns the ClusterUpgradeOperation CR that would be created without actually creating it
type DryRunClusterUpgradeResp struct {
	ClusterUpgradeOperation *o11yv1.ClusterUpgradeOperation `json:"clusterUpgradeOperation"`
}

// GetNodeGroupsReq represents the request to get all node groups and their versions for a cluster
type GetNodeGroupsReq struct {
	// K8sClusterName is the name of the target Kubernetes cluster
	K8sClusterName string `json:"k8sClusterName" form:"k8sClusterName" validate:"required"`

	// Region is the cloud region where the cluster is located
	Region string `json:"region" form:"region" validate:"required"`

	// CloudProvider is the cloud provider type (eks, gke, aks, ack, mock)
	CloudProvider o11yv1.CloudProvider `json:"cloudProvider" form:"cloudProvider" validate:"required,oneof=eks gke aks ack mock"`
}

// NodeGroupInfo represents a node group with its version for API response
type NodeGroupInfo struct {
	ID             string `json:"id"`
	Name           string `json:"name"`
	Version        string `json:"version"`
	RuntimeVersion string `json:"runtimeVersion,omitempty"`
	Status         string `json:"status"`
	NodeCount      int    `json:"nodeCount"`
	// LaunchTemplateVersion is set for EKS node groups that use a launch template.
	LaunchTemplateVersion string `json:"launchTemplateVersion,omitempty"`
	// LaunchTemplateId is set for EKS node groups that use a launch template with an ID.
	LaunchTemplateId string `json:"launchTemplateId,omitempty"`
	// LaunchTemplateName is set for EKS node groups that use a launch template with a name.
	LaunchTemplateName string `json:"launchTemplateName,omitempty"`
}

// GetNodeGroupsResp represents the response with all node groups and their versions
type GetNodeGroupsResp struct {
	NodeGroups []NodeGroupInfo `json:"nodeGroups"`
}

// ListAddonsReq represents the request to list cluster addons
type ListAddonsReq struct {
	// K8sClusterName is the name of the target Kubernetes cluster
	K8sClusterName string `json:"k8sClusterName" form:"k8sClusterName" validate:"required"`

	// Region is the cloud region where the cluster is located
	Region string `json:"region" form:"region" validate:"required"`

	// CloudProvider is the cloud provider type (eks, gke, aks, ack, mock)
	CloudProvider o11yv1.CloudProvider `json:"cloudProvider" form:"cloudProvider" validate:"required,oneof=eks gke aks ack mock"`
}

// AddonInfo represents an addon with its version and status for API response
type AddonInfo struct {
	Name    string `json:"name"`
	Version string `json:"version"`
	Status  string `json:"status"`
}

// ListAddonsResp represents the response with all cluster addons
type ListAddonsResp struct {
	Addons []AddonInfo `json:"addons"`
}

// Cluster upgrade status constants
const (
	ClusterUpgradeStatusPending   = "PENDING"
	ClusterUpgradeStatusRunning   = "RUNNING"
	ClusterUpgradeStatusCompleted = "COMPLETED"
	ClusterUpgradeStatusFailed    = "FAILED"
	ClusterUpgradeStatusPaused    = "PAUSED"
)
