package common

import (
	"context"
	"fmt"
	"time"

	"github.com/tidbcloud/infra-provider/regional-server/api/v1alpha1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/deploy"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/util"
	"k8s.io/apimachinery/pkg/types"
)

type CapacityPlanner struct {
	*task.BaseTask
}

const capacityPlannerChartName = "capacity-planner"

func capacityPlannerImage(values map[string]interface{}) (repository, tag string, ok bool) {
	imageMap, ok := values["image"].(map[string]interface{})
	if !ok {
		return "", "", false
	}
	repository, ok = imageMap["repository"].(string)
	if !ok || repository == "" {
		return "", "", false
	}
	tag, ok = imageMap["tag"].(string)
	if !ok || tag == "" {
		return "", "", false
	}
	return repository, tag, true
}

func NewCapacityPlanner(ctx *task.Context) *CapacityPlanner {
	return &CapacityPlanner{BaseTask: &task.BaseTask{Context: ctx}}
}

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

func (t *CapacityPlanner) enabled() bool {
	return t.APPBox.GetAnnotations()[v1alpha1.AnnotationKeyEnableCapacityPlanner] == "true"
}

func (t *CapacityPlanner) Create(ctx context.Context) deploy.Result {
	if !t.enabled() {
		return deploy.Done()
	}
	t.BeginAt = util.Pointer(time.Now())
	cfg := &t.DedicatedTmplConfig.CapacityPlanner
	if cfg.ChartPath == "" || cfg.GetName() == "" || cfg.GetNamespace() == "" {
		return deploy.Panic(fmt.Errorf("capacity planner helm configuration is incomplete"))
	}
	if _, _, ok := capacityPlannerImage(cfg.HelmValues); !ok {
		return deploy.Panic(fmt.Errorf("capacity planner image configuration is incomplete"))
	}
	return deploy.ErrorOrDone(t.ChartApplier.Apply(ctx, t.Remote, cfg))
}

func (t *CapacityPlanner) PostCreate(ctx context.Context) deploy.Result {
	if !t.enabled() {
		return deploy.Done()
	}
	cfg := &t.DedicatedTmplConfig.CapacityPlanner
	return deploy.ErrorOrDone(controllers.EnsureChartDeploymentReady(ctx, t.Remote, types.NamespacedName{
		Namespace: cfg.GetNamespace(),
		Name:      fmt.Sprintf("%s-%s", cfg.ReleaseName, capacityPlannerChartName),
	}))
}
