package action

import (
	"context"
	"testing"

	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
	dplanemgrv1 "github.com/tidbcloud/cluster-service-ng/api/dataplane-manager/v1"
	"github.com/tidbcloud/cluster-service-ng/domain/entity"
	"github.com/tidbcloud/cluster-service-ng/domain/workflow"
	dplanemgrmocks "github.com/tidbcloud/cluster-service-ng/pkg/dataplanemgr/mocks"
	"github.com/tidbcloud/cluster-service-ng/pkg/runtime/actions"
	repomocks "github.com/tidbcloud/cluster-service-ng/pkg/storage/repo/mocks"
	o11yv2 "github.com/tidbcloud/observability/agent-control-server/api/v2"
	"k8s.io/apimachinery/pkg/types"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestSharedPoolAgentActionsUseConfiguredNamespace(t *testing.T) {
	ctx := context.Background()
	defaultAgent := &o11yv2.SharedPoolAgent{}
	defaultAgent.Name = "sp-1"
	defaultAgent.Namespace = entity.GetNamespace()
	kubeClient := fake.NewClientBuilder().
		WithScheme(newO11yTestScheme(t)).
		WithObjects(defaultAgent).
		Build()
	dataplaneClient := dplanemgrmocks.NewClient(t)
	sharedPoolRepo := repomocks.NewSharedPoolRepo(t)
	dataplaneClient.EXPECT().
		GetDataPlane(mock.Anything, &dplanemgrv1.GetDataPlaneRequest{DataPlaneId: "dp-1"}).
		Return(&dplanemgrv1.DataPlane{
			Kubernetes: &dplanemgrv1.DataPlane_Kubernetes{Name: "k8s-1"},
		}, nil).
		Twice()
	sharedPoolRepo.EXPECT().
		Load(mock.Anything, "sp-1", false).
		Return(&entity.SharedPool{SharedPool: apiv1.SharedPool{Id: "sp-1"}}, nil).
		Twice()
	args := actions.ActionArgs{
		workflow.SharedPoolIdKey: actions.ActionArgString("sp-1"),
		workflow.DataplaneIdKey:  actions.ActionArgString("dp-1"),
	}

	create := NewCreateO11ySharedPoolAgentAction(
		"test-biz",
		false,
		dataplaneClient,
		kubeClient,
		sharedPoolRepo,
		"cp9-premium",
	)
	require.NoError(t, create.Invoke(args))
	require.NoError(t, create.Invoke(args))
	require.NoError(t, kubeClient.Get(ctx, types.NamespacedName{Namespace: "cp9-premium", Name: "sp-1"}, &o11yv2.SharedPoolAgent{}))
	var agents o11yv2.SharedPoolAgentList
	require.NoError(t, kubeClient.List(ctx, &agents, client.InNamespace("cp9-premium")))
	require.Len(t, agents.Items, 1)

	remove := NewDeleteO11ySharedPoolAgentAction(false, kubeClient, "cp9-premium")
	require.NoError(t, remove.Invoke(args))
	require.Error(t, kubeClient.Get(ctx, types.NamespacedName{Namespace: "cp9-premium", Name: "sp-1"}, &o11yv2.SharedPoolAgent{}))
	require.NoError(t, kubeClient.Get(ctx, types.NamespacedName{Namespace: entity.GetNamespace(), Name: "sp-1"}, &o11yv2.SharedPoolAgent{}))
}
