package job

import (
	"context"
	"errors"

	"sigs.k8s.io/controller-runtime/pkg/client"

	eksv1alpha1 "github.com/tidbcloud/eks-provider/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/namer"
)

// TiflowJobPhase manages the status change scaling<->running of tiflowjob.
type TiflowJobPhase struct {
	*BaseTask
}

func NewTiflowJobPhase(ctx *Context) *TiflowJobPhase {
	return &TiflowJobPhase{BaseTask: &BaseTask{Context: ctx}}
}

func (t *TiflowJobPhase) Name() string {
	return "TiflowJobPhase"
}

func (t *TiflowJobPhase) Create(ctx context.Context) deploy.Result {
	found := true
	tce := &eksv1alpha1.TiflowClusterExecutor{}
	tce.Namespace = t.Network.Namespace
	tce.Name = t.Namer.GetTiflowClusterName()
	key := client.ObjectKeyFromObject(tce)
	if err := t.Local.Get(ctx, key, tce); err != nil {
		found = false
	}
	switch phase := t.TiflowJob.Status.Phase; phase {
	case eksv1alpha1.TiflowJobPhaseRunning:
		if t.TiflowJob.Spec.SpecCode != t.TiflowJob.Status.TceSpecCode &&
			tce.Status.Phase == eksv1alpha1.TiflowClusterExecutorPhaseRunning {
			t.TiflowJob.Status.Phase = eksv1alpha1.TiflowJobPhasePhaseScaling
		}
	case eksv1alpha1.TiflowJobPhasePhaseScaling:
		if found && t.TiflowJob.Spec.SpecCode == t.TiflowJob.Status.TceSpecCode &&
			t.TiflowJob.Spec.SpecCode == tce.Status.ClusterNodeSelector[namer.TiflowSpecLabelKey] &&
			tce.Status.Phase == eksv1alpha1.TiflowClusterExecutorPhaseRunning {
			// should make sure tiflowclusterexecutor has been reconciled.
			// tiflowclusterexecutor.Status.NodeSelector can only be set after it is
			// reconciled by k8s.
			t.TiflowJob.Status.Phase = eksv1alpha1.TiflowJobPhaseRunning
		}
	}
	if !found {
		return deploy.Error(errors.New("fail to get tiflowclusterexecutor"))
	}
	return deploy.Done()
}
