package common

import (
	"context"
	"testing"

	. "github.com/onsi/gomega"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"

	o11yv2 "github.com/tidbcloud/observability/agent-control-server/api/v2"

	"github.com/tidbcloud/infra-provider/regional-server/pkg/config"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/controllers/appbox/task"
	regionalscheme "github.com/tidbcloud/infra-provider/regional-server/pkg/scheme"
)

type noOpO11yProvider struct{}

func (noOpO11yProvider) FillProviderSpec(context.Context, *task.BaseTask, *o11yv2.KubernetesAgentSpec) error {
	return nil
}

func TestO11yUsesConfiguredAgentNamespaceForCreateReadAndDelete(t *testing.T) {
	g := NewWithT(t)
	ctx := context.Background()
	defaultAgent := &o11yv2.KubernetesAgent{
		ObjectMeta: metav1.ObjectMeta{
			Name:        "appbox-1",
			Namespace:   "test",
			Annotations: map[string]string{"owner": "default"},
		},
	}
	cli := fake.NewClientBuilder().
		WithScheme(regionalscheme.Scheme).
		WithObjects(defaultAgent).
		Build()
	o11yTask := newTestO11yTask(cli)
	o11yTask.provider = noOpO11yProvider{}
	o11yTask.APPBox.Status.KubernetesClusterName = "k8s-1"
	o11yTask.Config.APPBoxConfig = config.APPBoxConfig{
		O11yBizType:        "test-biz",
		O11yAgentNamespace: "cp-byoc",
	}
	o11yTask.Config.O11Y = config.O11YConfig{}

	createResult := o11yTask.Create(ctx)
	g.Expect(createResult.Error()).NotTo(HaveOccurred())
	retryResult := o11yTask.Create(ctx)
	g.Expect(retryResult.Error()).NotTo(HaveOccurred())

	configuredAgent := &o11yv2.KubernetesAgent{}
	g.Expect(cli.Get(ctx, client.ObjectKey{Namespace: "cp-byoc", Name: "appbox-1"}, configuredAgent)).To(Succeed())
	g.Expect(configuredAgent.Spec.KubernetesClusterName).To(Equal("k8s-1"))
	configuredAgents := &o11yv2.KubernetesAgentList{}
	g.Expect(cli.List(ctx, configuredAgents, client.InNamespace("cp-byoc"))).To(Succeed())
	g.Expect(configuredAgents.Items).To(HaveLen(1))

	deleteResult := o11yTask.Delete(ctx)
	g.Expect(deleteResult.Error()).To(HaveOccurred())
	g.Expect(cli.Get(ctx, client.ObjectKey{Namespace: "cp-byoc", Name: "appbox-1"}, &o11yv2.KubernetesAgent{})).NotTo(Succeed())
	g.Expect(cli.Get(ctx, client.ObjectKey{Namespace: "test", Name: "appbox-1"}, defaultAgent)).To(Succeed())
	g.Expect(defaultAgent.Annotations["owner"]).To(Equal("default"))
}
