package task

import (
	"context"
	"fmt"

	"github.com/tidbcloud/observability/pkg/common/constants"
	"github.com/tidbcloud/observability/pkg/common/deploy"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

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

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

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

// Create returns an error or makes the integration task phase be one of
// - constants.CREATING
// - constants.UPDATING
// - constants.ACTIVE
func (t *Guardian) Create(ctx context.Context) deploy.Result {
	if !controllerutil.ContainsFinalizer(t.Task, Finalizer) {
		controllerutil.AddFinalizer(t.Task, Finalizer)
		// Require immediate requeue without running other tasks
		return deploy.Panic(nil).WithRequeueAfter(0)
	}

	switch phase := t.Task.Status.Phase; phase {
	case "":
		t.Task.Status.Phase = constants.CREATING
	case constants.CREATING, constants.UPDATING, constants.ACTIVE, constants.COMPLETED, constants.FAILED:
		// Terminal state
	default:
		return deploy.Panic(fmt.Errorf("unexpected integration task phase during creation: %s", phase))
	}

	return deploy.Done()
}

func (t *Guardian) Delete(ctx context.Context) deploy.Result {
	switch phase := t.Task.Status.Phase; phase {
	case constants.CREATING, constants.ACTIVE, constants.COMPLETED, constants.FAILED, "":
		t.Task.Status.Phase = constants.DELETING
		// Require immediate requeue without running other tasks
		return deploy.Panic(nil).WithRequeueAfter(0)
	case constants.DELETING:
		// Already in deleting phase, proceed with deletion
	default:
		return deploy.Panic(fmt.Errorf("unexpected integration task phase during deletion: %s", phase))
	}
	return deploy.Done()
}
