package task

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"

	agentv2 "github.com/tidbcloud/observability/agent-control-server/api/v2"
	"github.com/tidbcloud/observability/agent-control-server/pkg/config"
	"github.com/tidbcloud/observability/agent-control-server/pkg/consts"
	"github.com/tidbcloud/observability/agent-control-server/pkg/reconciler"
	"github.com/tidbcloud/observability/agent-control-server/pkg/testkits"
)

func makeOperatorTask(agent *agentv2.KubernetesAgent, opts testkits.TaskOptions) *OperatorTask {
	ctx := &reconciler.Context[*agentv2.KubernetesAgent]{
		Agent:  agent,
		Local:  testkits.BuildClient(agent),
		Remote: testkits.NewClientGetterWithOpts(opts),
		Config: &opts.Config,
	}
	return NewOperatorTask(ctx)
}

func baseOperatorConfig() config.RootConfig {
	return config.RootConfig{
		O11yConfig: config.ObservabilityInfra{
			Vendor: "aws",
			CustomerConfigsV2: config.CustomerConfigsV2{
				NextGen: config.CustomerNextGen{
					Charts: map[string]config.CustomerHelmChart{
						"victoria-metrics-operator": {
							Name:    "victoria-metrics/victoria-metrics-operator",
							Version: "0.0.0",
						},
					},
				},
			},
		},
	}
}

func TestOperatorTask(t *testing.T) {
	t.Run("Name", func(t *testing.T) {
		task := &OperatorTask{}
		assert.Equal(t, "Operator", task.Name())
	})

	t.Run("ClusterMeta", func(t *testing.T) {
		agent := testkits.NewKubernetesAgentBuilder().Build()
		task := makeOperatorTask(agent, testkits.TaskOptions{})
		meta := task.ClusterMeta()

		assert.Equal(t, consts.AgentKubernetes, meta.Agent)
		assert.Equal(t, "test-cluster", meta.K8sClusterName)
		assert.Equal(t, "tenant-1", meta.TenantID)
		assert.Equal(t, "app-1", meta.ApplicationID)
	})

	t.Run("buildNamespace normal mode", func(t *testing.T) {
		agent := testkits.NewKubernetesAgentBuilder().Build()
		task := makeOperatorTask(agent, testkits.TaskOptions{Config: baseOperatorConfig()})
		assert.Equal(t, consts.O11ySystemNamespace, task.buildNamespace())
	})

	t.Run("buildNamespace serverless mode", func(t *testing.T) {
		cfg := baseOperatorConfig()
		cfg.Mode = config.ModeServerless
		agent := testkits.NewKubernetesAgentBuilder().Build()
		task := makeOperatorTask(agent, testkits.TaskOptions{Config: cfg})
		assert.Equal(t, consts.ServerlessObservabilityNamespace, task.buildNamespace())
	})
}

func TestOperatorTask_Create(t *testing.T) {
	t.Run("fails when helm client cannot be built", func(t *testing.T) {
		agent := testkits.NewKubernetesAgentBuilder().Build()
		task := makeOperatorTask(agent, testkits.TaskOptions{HelmError: true, Config: baseOperatorConfig()})
		result := task.Create(context.Background())
		assert.Error(t, result.Error())
	})
}
