package schema

import "fmt"

// Fixed names in the migration workflow: the target vmcluster and its
// operator-managed services (vmselect-/vminsert- are the VM operator
// prefixes), plus the two vmselect deployments this tool's rendered steps
// create and delete. The CD repo pins the vmcluster name to "vmcluster" in
// deployments/charts/vmcluster and every envs/ override.
const (
	VmclusterName         = "vmcluster"
	VmselectName          = "vmselect-" + VmclusterName
	VminsertName          = "vminsert-" + VmclusterName
	VmselectMigrationName = "vmselect-migration"
	VmselectCandidateName = "vmselect-candidate"
)

// VmselectURLPattern returns the in-cluster query URL pattern for a vmselect
// service name in namespace.
func VmselectURLPattern(namespace, name string) string {
	return fmt.Sprintf("http://%s.%s.svc.cluster.local:8481/select/{tenant}/prometheus", name, namespace)
}

// VminsertURLPattern returns the in-cluster insert URL pattern for a
// vminsert service name in namespace.
func VminsertURLPattern(namespace, name string) string {
	return fmt.Sprintf("http://%s.%s.svc.cluster.local:8480/insert/{tenant}/prometheus", name, namespace)
}

// Step is one entry in steps.<stage>.items[] in plan.json.
//
// Also reused as the rendered step type after placeholder substitution.
type Step struct {
	Name    string   `json:"name"`
	Desc    string   `json:"desc"`
	Command []string `json:"command"`
}

// RawPlan mirrors plan.json exactly.
//
// Used for the initial unmarshal; the plan/ package then validates and
// projects it into Config + Stages.
type RawPlan struct {
	Namespace          string       `json:"namespace"`
	Region             string       `json:"region"`
	SourceReplicaCount int          `json:"sourceReplicaCount"`
	TargetReplicaCount int          `json:"targetReplicaCount"`
	ShardStepInterval  string       `json:"shardStepInterval"`
	Vmselects          RawVmselects `json:"vmselects"`
	RetentionWindow    RawWindow    `json:"retentionWindow"`
	Vmctl              RawVmctl     `json:"vmctl"`
	Steps              RawSteps     `json:"steps"`
	Tenants            []string     `json:"tenants,omitempty"`
}

// RawVmselects is the vmselects block in plan.json: one shared image, one
// sizing sub-block per temporary vmselect.
type RawVmselects struct {
	Image     string            `json:"image"`
	Migration RawVmselectTarget `json:"migration"`
	Candidate RawVmselectTarget `json:"candidate"`
}

// RawVmselectTarget is one temporary vmselect's sizing.
type RawVmselectTarget struct {
	Replicas  *int         `json:"replicas"`
	Resources RawResources `json:"resources"`
}

// RawResources is the resources sub-block.
type RawResources struct {
	Requests RawResourceQuant `json:"requests"`
	Limits   RawResourceQuant `json:"limits"`
}

// RawResourceQuant is one of {limits, requests} with cpu/memory.
type RawResourceQuant struct {
	CPU    *string `json:"cpu"`
	Memory *string `json:"memory"`
}

// RawWindow is the retentionWindow block.
type RawWindow struct {
	Start string `json:"start"`
	End   string `json:"end"`
}

// RawVmctl is the vmctl block.
type RawVmctl struct {
	RateLimitBytes *int   `json:"rateLimitBytes"`
	Concurrency    *int   `json:"concurrency"`
	StepInterval   string `json:"stepInterval"`
}

// RawSteps is the steps block grouping stage items.
type RawSteps struct {
	Prepare      RawStage     `json:"prepare"`
	Migration    RawMigration `json:"migration"`
	Decommission RawStage     `json:"decommission"`
}

// RawStage is a non-migration stage.
type RawStage struct {
	Items []Step `json:"items"`
}

// RawMigration is the migration stage.
type RawMigration struct {
	Items []Step `json:"items"`
}
