package operation

import apprent "github.com/tidbcloud/devops/entity/approval"

type (
	OperationTarget string
	OperationMethod string
)

// Enums
// Update value list `XXXValues` when update a enum
const (
	OperationTargetCluster      OperationTarget = "cluster"
	OperationTargetTenant       OperationTarget = "tenant"
	OperationTargetProject      OperationTarget = "project"
	OperationTargetUser         OperationTarget = "user"
	OperationTargetRegion       OperationTarget = "region"
	OperationTargetResourcePool OperationTarget = "resource_pool"
	OperationTargetUndefined    OperationTarget = "undefined"

	OperationTypeShutdownOperationForClusterVersionUpgrade = "ShutdownOperationForClusterVersionUpgrade"
	OperationTypeShutdownOperationForClusterConfigChange   = "ShutdownOperationForClusterConfigUpdate"
	OperationTypeShutdownOperationForClusterScaleUpDown    = "ShutdownOperationForClusterScaleUpDown"
	OperationTypeRecreateMemberForCluster                  = "RecreateMemberForCluster"
	OperationTypeReplaceNodeForCluster                     = "ReplaceNodeForCluster"
	OperationTypeReplaceNodeForNextGenResourcePool         = "ReplaceNodeForNextGenResourcePool"
	OperationTypeMigratePrivateLinkForCluster              = "MigratePrivateLinkForCluster"
	OperationTypeOfflineAzForCluster                       = "OfflineAzForCluster"
	OperationTypeRecoverAzForCluster                       = "RecoverAzForCluster"
	OperationTypeOfflineAzWithZonalShiftForCluster         = "OfflineAzWithZonalShiftForCluster"
	OperationTypeRecoverAzWithStopZonalShiftForCluster     = "RecoverAzWithStopZonalShiftForCluster"
)

var (
	OperationTargetValues = []OperationTarget{
		OperationTargetCluster, OperationTargetTenant, OperationTargetResourcePool,
		OperationTargetProject, OperationTargetUser, OperationTargetRegion,
		OperationTargetUndefined,
	}
	// OperationTargetIDParamNames define where to get the target id from a param.
	OperationTargetIDParamNames = map[OperationTarget]ParamName{
		OperationTargetCluster:      ParamClusterID,
		OperationTargetTenant:       ParamTenantID,
		OperationTargetProject:      ParamProjectID,
		OperationTargetResourcePool: ParamResourcePoolID,
	}
)

type OperationAction struct {
	// Name is the action name.
	Name ActionName `json:"name" yaml:"name"`
	// Optional means this action is optional.
	Optional bool `json:"optional" yaml:"optional"`
	// PreferStartPolicy is the default start policy when shown on UI.
	PreferStartPolicy *ActionStartPolicy `json:"prefer_start_policy" yaml:"preferStartPolicy"`
	// PreferScheduleHour is the default schedule hour, and the schedule time is `now()+hour` when shown on UI.
	PreferScheduleHour *int `json:"prefer_schedule_hour" yaml:"preferScheduleHour"`
}

type Operation struct {
	// Name is the unique identifier of an operation.
	Name string `json:"name" yaml:"name"`
	// Alias is the shown name of an operation when creating.
	Alias string `json:"alias" yaml:"alias"`
	// Target is the target of an operation.
	Target OperationTarget `json:"target" yaml:"target"`
	// Description is the description of an operation.
	Description string `json:"description" yaml:"description"`
	// Internal means this operation is internal and only created by system.
	// It will not be shown on UI when internal is true.
	Internal bool `json:"internal" yaml:"internal"`
	// Categories is the category of an operation.
	Categories []string `json:"categories" yaml:"categories"`
	// Actions is actions be executed in an operation.
	Actions []OperationAction `json:"actions" yaml:"actions"`
	// Params is params of an operation, it will be used in actions.
	Params map[ParamName]ParamDefine `json:"params" yaml:"params"`
	// ApprovalTips is the text shown on approval page.
	ApprovalTips string `json:"approval_tips" yaml:"approvalTips"`
	//  Approval is the approval template of the operation.
	//
	// NOTE: The template is injected with format `operation/<Name>` to avoid
	Approval apprent.Template `json:"approval" yaml:"approval"`
	// RuntimeData is injected by backend at read time only.
	RuntimeData map[string]string `json:"runtime_data,omitempty" yaml:"-"`
}
