package task

import (
	"context"
	"fmt"
	"time"

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

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/util"
)

// Guardian guards the deletion and creation of the nodepool.
type Guardian struct {
	*BaseTask
}

func NewGuardian(ctx *Context) *Guardian {
	return &Guardian{BaseTask: &BaseTask{Context: ctx}}
}

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

func (t *Guardian) Create(ctx context.Context) deploy.Result {
	t.BeginAt = util.Pointer(time.Now())
	if !controllerutil.ContainsFinalizer(t.NodePool, Finalizer) {
		controllerutil.AddFinalizer(t.NodePool, Finalizer)
		return deploy.Panic(nil).WithRequeuAfter(0)
	}

	// if phase is empty recover to creating phase
	if t.NodePool.Status.Phase == "" {
		t.NodePool.Status.Phase = v1alpha1.NodePoolPhaseCreating
	}

	if t.DataPlane != nil && t.DataPlane.Status.Phase != v1alpha1.DataPlanePhaseActive {
		return deploy.Error(fmt.Errorf("dataplane %s is not active", t.DataPlane.Name)).WithRequeuAfter(deploy.DefaultRequeueAfter)
	}
	if t.APPBox != nil && t.APPBox.Status.Phase != v1alpha1.APPBoxPhaseActive {
		return deploy.Error(fmt.Errorf("appbox %s is not active", t.APPBox.Name)).WithRequeuAfter(deploy.DefaultRequeueAfter)
	}

	return deploy.Done()
}

func (t *Guardian) Delete(ctx context.Context) deploy.Result {
	return deploy.Done()
}
