package main

import (
	"context"
	"fmt"
	"os"

	v1alpha1 "github.com/pfeifferj/container-mom-go/pkg/apis/containermom/v1alpha1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/config"
)

var scheme = runtime.NewScheme()

func init() {
	_ = clientgoscheme.AddToScheme(scheme)
	_ = v1alpha1.AddToScheme(scheme)
}

func main() {
	ctx := context.Background()
	ctrl.SetLogger(ctrl.Log.WithName("test-wlc"))

	ctrl.Log.Info("Starting test program")

	// Get config from kubeconfig
	cfg := config.GetConfigOrDie()

	// Create a client
	k8sClient, err := client.New(cfg, client.Options{Scheme: scheme})
	if err != nil {
		ctrl.Log.Error(err, "failed to create client")
		os.Exit(1)
	}

	// Get the CR
	cr := &v1alpha1.ContainerMomDeployment{}
	err = k8sClient.Get(ctx, client.ObjectKey{Name: "josie-lol", Namespace: "container-mom-system"}, cr)
	if err != nil {
		ctrl.Log.Error(err, "failed to get CR")
		os.Exit(1)
	}

	ctrl.Log.Info("Found CR", "name", cr.Name, "clusters", cr.Spec.Clusters)

	// Generate a namespace name
	nsName := fmt.Sprintf("wkl-%s-%s", cr.Name, "test123")

	ctrl.Log.Info("Creating namespace for ContainerMomDeployment",
		"deployment", cr.Name,
		"namespace", nsName,
		"clusters", cr.Spec.Clusters)

	// Create the namespace
	ns := &corev1.Namespace{
		ObjectMeta: metav1.ObjectMeta{
			Name: nsName,
			Labels: map[string]string{
				"app.kubernetes.io/managed-by": "container-mom-test",
				"containermom.mom/deployment":  cr.Name,
			},
		},
	}

	// Try to create the namespace
	err = k8sClient.Create(ctx, ns)
	if err != nil {
		if errors.IsAlreadyExists(err) {
			ctrl.Log.Info("Namespace already exists", "namespace", nsName)
		} else {
			ctrl.Log.Error(err, "Failed to create namespace", "namespace", nsName)
			os.Exit(1)
		}
	} else {
		ctrl.Log.Info("Created namespace", "namespace", nsName)
	}

	// Add annotation to CR to persist namespace
	if cr.Annotations == nil {
		cr.Annotations = make(map[string]string)
	}
	cr.Annotations["containermom.mom/namespace"] = nsName

	if err := k8sClient.Update(ctx, cr); err != nil {
		ctrl.Log.Error(err, "Failed to update CR with namespace annotation")
	} else {
		ctrl.Log.Info("Updated CR with namespace annotation",
			"deployment", cr.Name,
			"namespace", nsName)
	}

	// Check if we can read the updated CR with the annotation
	updatedCR := &v1alpha1.ContainerMomDeployment{}
	if err := k8sClient.Get(ctx, client.ObjectKey{Name: cr.Name, Namespace: cr.Namespace}, updatedCR); err != nil {
		ctrl.Log.Error(err, "Failed to read updated CR")
	} else {
		ctrl.Log.Info("Read updated CR",
			"deployment", updatedCR.Name,
			"namespace", updatedCR.Annotations["containermom.mom/namespace"])
	}

	ctrl.Log.Info("Test completed!")
}
