package common

import (
	"context"
	"fmt"

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

	"github.com/tidbcloud/eks-provider/controllers/replay/task"
	v1 "github.com/tidbcloud/infra-api/api/v1"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
)

type Guardian struct {
	*task.BaseTask
}

func NewGuardian(ctx *task.Context) deploy.Task {
	return &Guardian{BaseTask: &task.BaseTask{Context: ctx}}
}

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

func (t *Guardian) Create(ctx context.Context) deploy.Result {
	if !controllerutil.ContainsFinalizer(t.Replay, task.Finalizer) {
		controllerutil.AddFinalizer(t.Replay, task.Finalizer)
		// Require immediate requeue without running other tasks
		return deploy.Panic(nil).WithRequeuAfter(0)
	}
	switch phase := t.Replay.Status.Phase; phase {
	case "", v1.ReplayPending:
		initReplicas(t.Replay)
		t.Replay.Status.Phase = v1.ReplayCreating
		return deploy.Panic(nil).WithRequeuAfter(0)
	case v1.ReplayCreating, v1.ReplayRunning, v1.ReplayStopped:
	default:
		return deploy.Panic(fmt.Errorf("unexpected replay phase during creation: %s", phase))
	}
	return deploy.Done()
}

func (t *Guardian) Delete(ctx context.Context) deploy.Result {
	if t.Replay.Status.Phase != v1.ReplayDeleting {
		t.Replay.Status.Phase = v1.ReplayDeleting
		t.Replay.Status.Message = "Replay resources are being deleted"
	}
	return deploy.Done()
}

func initReplicas(replay *v1.Replay) {
	for _, task := range replay.Spec.Tasks {
		if task.Replicas == 0 {
			task.Replicas = 1
		}
	}
}
