package common

import (
	"context"

	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/k8s"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

// Namespace deploys the namespace for TiDB operator and related components.
// It does not implement deletion related functions as the namespaces will
// be removed as part of the cluster deletion itself, i.e. no external resources
// are provisioned during the creation.
type Namespace struct {
	*task.BaseTask
	namespaces []string
}

func NewNamespace(ctx *task.Context) *Namespace {
	return &Namespace{
		BaseTask: &task.BaseTask{Context: ctx},
		namespaces: []string{
			task.ObservabilityNamespace,
			task.CertManagerNamespace,
			task.DedicatedAdminNamespace,
			k8s.HelmNamespace, // for helm
		},
	}
}

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

func (t *Namespace) Create(ctx context.Context) deploy.Result {
	cli, err := t.Remote.GetClient(ctx)
	if err != nil {
		return deploy.Panic(err)
	}
	for _, namespace := range t.namespaces {
		ns := &corev1.Namespace{
			ObjectMeta: metav1.ObjectMeta{
				Name: namespace,
			},
		}
		_, err = controllerutil.CreateOrUpdate(ctx, cli, ns, func() error { return nil })
		if err != nil {
			return deploy.Panic(err)
		}
	}
	return deploy.Done()
}
