package common

import (
	"context"

	"github.com/tidbcloud/eks-provider/controllers/network/task"
	"github.com/tidbcloud/infra-provider/pkg/deploy"
	"github.com/tidbcloud/infra-provider/pkg/k8s"

	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.AdminNamespace,         // for tidb-operator
			task.CertManagerNamespace,   // for cert-manager
			task.ObservabilityNamespace, // for observability related addons
			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()
}

func (t *Namespace) PostCreate(ctx context.Context) deploy.Result {
	return deploy.Done()
}
