package common

import (
	"context"

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

	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/util"

	"github.com/tidbcloud/chaos-provider/controllers/chaos/task"
)

// Guardian adds and removes the finalizer of the ChaosServer.
type Guardian struct {
	*task.BaseTask
}

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

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

func (t *Guardian) Create(ctx context.Context) deploy.Result {
	if t.ChaosServer != nil {
		// prevent reconciling objects from different regions
		if t.Network.Spec.Region != t.Config.Region {
			return deploy.Panic(nil)
		}
		// ignore resource that doesn't belong to this region
		if !util.ContainsRegionLabel(t.ChaosServer) {
			if ok, err := util.CheckNetworkRegion(t.Config.Region, t.Network); err != nil {
				return deploy.Panic(err)
			} else if !ok {
				return deploy.Panic(nil)
			}
			// ensure the object contains the region label
			if !util.EnsureRegion(t.ChaosServer, t.Network.Spec.Region) {
				return deploy.Panic(nil).WithRequeuAfter(0)
			}
		}
		if !controllerutil.ContainsFinalizer(t.ChaosServer, task.Finalizer) {
			controllerutil.AddFinalizer(t.ChaosServer, task.Finalizer)
			// Require immediate requeue without running other tasks
			return deploy.Panic(nil).WithRequeuAfter(0)
		}
	}

	if t.ChaosWorkflow != nil {
		if !controllerutil.ContainsFinalizer(t.ChaosWorkflow, task.Finalizer) {
			controllerutil.AddFinalizer(t.ChaosWorkflow, task.Finalizer)
			// Require immediate requeue without running other tasks
			return deploy.Panic(nil).WithRequeuAfter(0)
		}
	}

	return deploy.Done()
}
