package server

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"
	clusteragentv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/cluster-agent/v1"
	"github.com/tidbcloud/cluster-service-ng/domain/entity"
	clustergatewaymocks "github.com/tidbcloud/cluster-service-ng/pkg/clustergateway/mocks"
	dataplanemocks "github.com/tidbcloud/cluster-service-ng/pkg/dataplane/mocks"
	repomocks "github.com/tidbcloud/cluster-service-ng/pkg/storage/repo/mocks"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestMarkTiProxyBackendsNoNewConnectionsUsesLegacyMarker(t *testing.T) {
	ctx := context.Background()
	scheme := runtime.NewScheme()
	require.NoError(t, corev1.AddToScheme(scheme))

	sharedPool := &entity.SharedPool{SharedPool: apiv1.SharedPool{
		Id:            "sp-1",
		DataplaneName: "dp-1",
		Provider:      &apiv1.Provider{Type: apiv1.ProviderType_ALICLOUD},
	}}
	tiproxyComponent := "cluster-1"
	tiproxyGroup := tiProxyGroupName(tiproxyComponent)
	sharedPool.ComponentGroups = []*entity.Component{{Id: tiproxyComponent, ComponentType: apiv1.ComponentType_TIPROXY}}
	pod := &corev1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:      "tiproxy-0",
			Namespace: sharedPool.GetDataPlaneNamespace(),
			Labels: map[string]string{
				k8sComponentLabelKey: tiProxyComponentValue,
				k8sInstanceLabelKey:  tiproxyGroup,
			},
		},
		Status: corev1.PodStatus{PodIP: "10.0.0.1"},
	}
	remoteCli := fake.NewClientBuilder().WithScheme(scheme).WithObjects(pod).Build()

	sharedPoolRepo := repomocks.NewSharedPoolRepo(t)
	dataplaneManager := dataplanemocks.NewManager(t)
	clusterGatewayClient := clustergatewaymocks.NewClient(t)
	s := &serverImpl{
		clustergatewayCli: clusterGatewayClient,
		dataplaneManager:  dataplaneManager,
		sharedPoolRepo:    sharedPoolRepo,
	}

	sharedPoolRepo.EXPECT().
		Load(mock.Anything, sharedPool.GetId(), false).
		Return(sharedPool, nil).
		Once()
	dataplaneManager.EXPECT().
		GetClient(sharedPool.GetDataplaneName()).
		Return(remoteCli, nil).
		Once()
	clusterGatewayClient.EXPECT().
		MarkTiProxyPodUnhealthyLegacy(mock.Anything, sharedPool, mock.MatchedBy(func(req *clusteragentv1.MarkTiProxyPodUnhealthyLegacyReq) bool {
			return req.GetClusterId() == sharedPool.GetId() && req.GetPodName() == pod.Name
		})).
		Return(nil).
		Once()

	require.NoError(t, s.markTiProxyBackendsNoNewConnections(ctx, sharedPool.GetId(), tiproxyGroup, []string{pod.Name}))
}
