package tidbtools

import (
	"context"
	"testing"

	tidbapi "github.com/tidbcloud/devops/api/tidbtools"
	"github.com/tidbcloud/devops/pkg/infra/clients/coresvccli"
	commonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	mgmtv1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
	"go.uber.org/mock/gomock"
)

func TestSupportsBackupRestore(t *testing.T) {
	tests := []struct {
		name          string
		clusterType   tidbapi.ClusterType
		servicePlan   string
		wantSupported bool
	}{
		{name: "Dedicated", clusterType: dedicatedType, wantSupported: true},
		{name: "Premium logical cluster", clusterType: logicalType, servicePlan: "Premium", wantSupported: true},
		{name: "Essential v2 logical cluster", clusterType: logicalType, servicePlan: "Essential_V2", wantSupported: true},
		{name: "Premium Reserved logical cluster", clusterType: logicalType, servicePlan: "Premium_Reserved", wantSupported: false},
		{name: "BYOC logical cluster", clusterType: logicalType, servicePlan: "BYOC", wantSupported: false},
		{name: "Premium shared pool", clusterType: sharedPoolType, wantSupported: false},
		{name: "unknown", clusterType: tidbapi.ClusterType("UNKNOWN"), wantSupported: false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := supportsBackupRestore(tt.clusterType, tt.servicePlan); got != tt.wantSupported {
				t.Fatalf("supportsBackupRestore(%q, %q) = %v, want %v", tt.clusterType, tt.servicePlan, got, tt.wantSupported)
			}
		})
	}
}

func TestValidatePremiumBackupPageSize(t *testing.T) {
	if err := validatePremiumBackupPageSize(100); err != nil {
		t.Fatalf("expected upstream maximum to be accepted: %v", err)
	}
	if err := validatePremiumBackupPageSize(200); err == nil {
		t.Fatal("expected page size over Premium upstream maximum to be rejected")
	}
}

func TestResolveClusterInfoUsesNextGenServicePlan(t *testing.T) {
	ctrl := gomock.NewController(t)
	clusterClient := coresvccli.NewMockClusterServiceClient(ctrl)
	clusterClient.EXPECT().ListClusters(gomock.Any(), gomock.Any()).Return(&mgmtv1.ListClustersResponse{Clusters: []*mgmtv1.Cluster{{
		ClusterId:  42,
		DeployType: mgmtv1.DeployType_DEPLOY_TYPE_NEXTGEN,
		ClusterInfo: &mgmtv1.Cluster_NextGenCluster{NextGenCluster: &globalngv1.Cluster{
			ServicePlan: commonv1.ServicePlan_Premium,
		}},
	}}}, nil)
	c := &TidbToolsController{coreSvcCli: &coresvccli.CoreSvcCli{Mgmt: &coresvccli.MgmtService{Cluster: clusterClient}}}
	info, err := c.resolveClusterInfo(context.Background(), 42)
	if err != nil {
		t.Fatalf("resolveClusterInfo: %v", err)
	}
	if info.servicePlan != commonv1.ServicePlan_Premium.String() || !supportsBackupRestore(info.clusterType, info.servicePlan) {
		t.Fatalf("expected NextGen Premium plan to enable BR, got %#v", info)
	}
}
