package gkeheterogeneous

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"
	"go.uber.org/mock/gomock"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globaldedicatedv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/dedicated/v1"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/cluster/mock_cluster"
	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/repository/region/mock_region"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
	"github.com/tidbcloud/tidb-management-service/utilities/featuregate/mock_featuregate"
)

func TestPrepareRequiresFeatureGateClient(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	clusterRepo := mock_cluster.NewMockRepo(ctrl)
	regionRepo := mock_region.NewMockRepo(ctrl)

	clusterRepo.EXPECT().Get(gomock.Any(), uint64(1001), false).Return(&entity.Cluster{
		Cluster: &globaldedicatedv1.Cluster{
			ClusterId:       1001,
			OrganizationId:  2001,
			ProjectId:       3001,
			CloudProviderId: globalcommonv1.CloudProvider_GCP,
			RegionId:        globalcommonv1.Region_GCP_US_WEST2,
			State:           globaldedicatedv1.Cluster_AVAILABLE,
		},
	}, nil)

	_, _, berr := Prepare(
		context.Background(),
		clusterRepo,
		regionRepo,
		nil,
		2001,
		3001,
		1001,
		globaldedicatedv1.ComponentType_TIKV,
		true,
		true,
	)
	require.Error(t, berr)
	require.Equal(t, bizerr.ErrCodeUnknown, berr.ErrCode())
	require.Contains(t, berr.Error(), "feature gate client is required")
}

func TestPrepareAllowsNonAvailableCluster(t *testing.T) {
	ctrl := gomock.NewController(t)
	defer ctrl.Finish()

	clusterRepo := mock_cluster.NewMockRepo(ctrl)
	regionRepo := mock_region.NewMockRepo(ctrl)
	featGate := mock_featuregate.NewMockService(ctrl)

	clusterRepo.EXPECT().Get(gomock.Any(), uint64(2001), false).Return(&entity.Cluster{
		Cluster: &globaldedicatedv1.Cluster{
			ClusterId:       2001,
			OrganizationId:  2001,
			ProjectId:       3001,
			CloudProviderId: globalcommonv1.CloudProvider_GCP,
			RegionId:        globalcommonv1.Region_GCP_US_WEST2,
			State:           globaldedicatedv1.Cluster_CREATING,
		},
	}, nil)
	regionRepo.EXPECT().SelectRegionById(gomock.Any(), globalcommonv1.Region_GCP_US_WEST2, uint64(2001)).Return(
		&globalcommonv1.Region{Id: globalcommonv1.Region_GCP_US_WEST2, State: globalcommonv1.Region_ACTIVE}, nil,
	)
	featGate.EXPECT().CheckFeatureEnabled(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(true)

	_, _, berr := Prepare(
		context.Background(),
		clusterRepo,
		regionRepo,
		featGate,
		2001,
		3001,
		2001,
		globaldedicatedv1.ComponentType_TIKV,
		true,
		true,
	)
	require.NoError(t, berr)
}
