package api

import (
	"github.com/go-logr/logr"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func GetExtraGroupInstanceTypeScalePhase(extraGroup *cloudv1.ExtraGroupCluster, componentType cloudv1.ComponentType) cloudv1.InstanceTypeScalePhase {
	if extraGroup.Status == nil {
		return cloudv1.InstanceTypeScalePhaseNone
	}

	switch componentType {
	case cloudv1.ComponentTiDB:
		if extraGroup.Status.TiDB == nil {
			return cloudv1.InstanceTypeScalePhaseNone
		}
		return extraGroup.Status.TiDB.InstanceTypeScalePhase
	case cloudv1.ComponentTiProxy:
		if extraGroup.Status.TiProxy == nil {
			return cloudv1.InstanceTypeScalePhaseNone
		}
		return extraGroup.Status.TiProxy.InstanceTypeScalePhase
	}
	return cloudv1.InstanceTypeScalePhaseNone
}

func TransExtraGroupInstanceTypeScalePhase(logger logr.Logger, extraGroup *cloudv1.ExtraGroupCluster,
	componentType cloudv1.ComponentType, newPhase cloudv1.InstanceTypeScalePhase) {
	checkAndLog := func(oldPhase cloudv1.InstanceTypeScalePhase, newPhase cloudv1.InstanceTypeScalePhase) bool {
		if oldPhase == newPhase {
			return false // no need to transfer
		}
		if (oldPhase == "" && newPhase == cloudv1.InstanceTypeScalePhaseCreatingNodes) ||
			(oldPhase == cloudv1.InstanceTypeScalePhaseCreatingNodes && newPhase == cloudv1.InstanceTypeScalePhaseCordoningNodes) ||
			(oldPhase == cloudv1.InstanceTypeScalePhaseCordoningNodes && newPhase == cloudv1.InstanceTypeScalePhaseRestartingPods) ||
			(oldPhase == cloudv1.InstanceTypeScalePhaseRestartingPods && newPhase == cloudv1.InstanceTypeScalePhaseDeletingNodes) ||
			(oldPhase == cloudv1.InstanceTypeScalePhaseDeletingNodes && newPhase == cloudv1.InstanceTypeScalePhaseNone) { // scale finished
			logger.Info("Transfer instance type scale phase", "from", oldPhase, "to", newPhase, "component", componentType)
			return true
		}
		logger.Error(nil, "Invalid instance type scale phase transfer", "from", oldPhase, "to", newPhase, "component", componentType)
		return false
	}

	switch componentType {
	case cloudv1.ComponentTiDB:
		if extraGroup.Status.TiDB == nil {
			extraGroup.Status.TiDB = &cloudv1.TiDBStatus{}
		}
		if checkAndLog(extraGroup.Status.TiDB.InstanceTypeScalePhase, newPhase) {
			extraGroup.Status.TiDB.InstanceTypeScalePhase = newPhase
		}
	case cloudv1.ComponentTiProxy:
		if extraGroup.Status.TiProxy == nil {
			extraGroup.Status.TiProxy = &cloudv1.TiProxyStatus{}
		}
		if checkAndLog(extraGroup.Status.TiProxy.InstanceTypeScalePhase, newPhase) {
			extraGroup.Status.TiProxy.InstanceTypeScalePhase = newPhase
		}
	}
}
