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.O11yK8sAgent, opts testkits.TaskOptions) *OperatorTask {
	ctx := &reconciler.Context[*agentv2.O11yK8sAgent]{
		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{
				Dedicated: config.CustomerDedicated{
					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.NewO11yK8sAgentBuilder().Build()
		task := makeOperatorTask(agent, testkits.TaskOptions{})
		meta := task.ClusterMeta()

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

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