package spu

import (
	"testing"

	"github.com/samber/lo"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"

	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/spu"
	clusterrepoimpl "github.com/tidbcloud/tidb-management-service/dedicated-global-service/infra/repoimpl/cluster"
	regionimpl "github.com/tidbcloud/tidb-management-service/dedicated-global-service/infra/repoimpl/region"
	spurepoimpl "github.com/tidbcloud/tidb-management-service/dedicated-global-service/infra/repoimpl/spu"
	featgatesvc "github.com/tidbcloud/tidb-management-service/utilities/featuregate"
)

func TestSpuService(t *testing.T) {
	spuRepo := spurepoimpl.NewSpuRepo(*dbProvider.Load())
	skuRepo := spurepoimpl.NewSkuRepo(*dbProvider.Load())
	instanceMuRepo := spurepoimpl.NewInstanceMuRepo(*dbProvider.Load())
	storageMuRepo := spurepoimpl.NewStorageMuRepo(*dbProvider.Load())
	regionRepo := regionimpl.NewRegionRepo(*dbProvider.Load())
	clusterRepo := clusterrepoimpl.NewClusterRepo(*dbProvider.Load())
	featureGateFacade := featgatesvc.NewFeatureGate(globalConf.Load().ServerConfig.FeatureGates, nil)
	skuSvc := NewSkuService(
		spuRepo,
		skuRepo,
		instanceMuRepo,
		storageMuRepo,
	)
	spuSvc := NewSpuService(spuRepo, skuRepo, regionRepo, clusterRepo, skuSvc, featureGateFacade, *dbProvider.Load())
	prepareDbRecords(t, spuSvc, skuRepo, instanceMuRepo, storageMuRepo)

	t.Run("List SPUs by (cloud_provider, region, org_id, project_id)", func(t *testing.T) {
		spus, err := spuSvc.List(t.Context(), &globaldedicatedv1.ListSpusRequest{
			Request: &globaldedicatedv1.ListSpusRequest_WithSku{
				WithSku: &globaldedicatedv1.ListSpusRequest_FilterWithSku{
					CloudProvider: globalcommonv1.CloudProvider_AWS,
					Region:        globalcommonv1.Region_AWS_US_WEST_2,
					TenantId:      9999,
					ProjectId:     9999,
				},
			},
		})
		require.NoError(t, err)

		assert.True(t, lo.ContainsBy(spus, func(s *entity.Spu) bool { return s.GetName() == "2c2g" }))

		spu1C1G, ok := lo.Find(spus, func(s *entity.Spu) bool { return s.GetName() == "1c1g" })
		assert.True(t, ok)

		dataStorage := spu1C1G.GetDataStorage()
		assert.Equal(t, int32(1), dataStorage.GetDefaultSizeGi())
		assert.Equal(t, int32(1), dataStorage.GetMaxSizeGi())
		assert.Equal(t, int32(1), dataStorage.GetMinSizeGi())
		assert.Equal(t, int32(1), dataStorage.GetDefaultIops())
		assert.Equal(t, int32(1), dataStorage.GetMaxIops())
		assert.Equal(t, int32(1), dataStorage.GetMinIops())

		raftStorage := spu1C1G.GetRaftlogStorage()
		assert.Equal(t, int32(1), raftStorage.GetDefaultSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetMaxSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetMinSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetDefaultIops())
		assert.Equal(t, int32(1), raftStorage.GetMaxIops())
		assert.Equal(t, int32(1), raftStorage.GetMinIops())
		assert.Empty(t, spu1C1G.GetStorageTypeDetails())

		assert.ElementsMatch(t, []*globaldedicatedv1.Spu_DiskPair{
			{
				DataVolumeType:    globaldedicatedv1.StorageMu_GP3,
				RaftlogVolumeType: globaldedicatedv1.StorageMu_GP3,
			},
			{
				DataVolumeType:    globaldedicatedv1.StorageMu_GP3,
				RaftlogVolumeType: globaldedicatedv1.StorageMu_IO2,
			},
		}, spu1C1G.GetSupportedDiskPairs())
	})

	t.Run("Tikv 6T whitelist should return 6T max size", func(t *testing.T) {
		// Refer to cases https://pingcap.feishu.cn/wiki/QBwnwqfx3iPo5hkI8KIciBHinCc.
		spus, err := spuSvc.List(t.Context(), &globaldedicatedv1.ListSpusRequest{
			Request: &globaldedicatedv1.ListSpusRequest_WithSku{
				WithSku: &globaldedicatedv1.ListSpusRequest_FilterWithSku{
					CloudProvider: globalcommonv1.CloudProvider_AWS,
					Region:        globalcommonv1.Region_AWS_US_WEST_2,
					TenantId:      123,
					ProjectId:     123,
				},
			},
		})
		require.NoError(t, err)

		spu1C1G, ok := lo.Find(spus, func(s *entity.Spu) bool { return s.GetName() == "1c1g" })
		assert.True(t, ok)

		dataStorage := spu1C1G.GetDataStorage()
		assert.Equal(t, int32(1), dataStorage.GetDefaultSizeGi())
		assert.Equal(t, int32(6144), dataStorage.GetMaxSizeGi())
		assert.Equal(t, int32(1), dataStorage.GetMinSizeGi())
		assert.Equal(t, int32(1), dataStorage.GetDefaultIops())
		assert.Equal(t, int32(1), dataStorage.GetMaxIops())
		assert.Equal(t, int32(1), dataStorage.GetMinIops())

		raftStorage := spu1C1G.GetRaftlogStorage()
		assert.Equal(t, int32(1), raftStorage.GetDefaultSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetMaxSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetMinSizeGi())
		assert.Equal(t, int32(1), raftStorage.GetDefaultIops())
		assert.Equal(t, int32(1), raftStorage.GetMaxIops())
		assert.Equal(t, int32(1), raftStorage.GetMinIops())
		assert.Empty(t, spu1C1G.GetStorageTypeDetails())

		assert.ElementsMatch(t, []*globaldedicatedv1.Spu_DiskPair{
			{
				DataVolumeType:    globaldedicatedv1.StorageMu_GP3,
				RaftlogVolumeType: globaldedicatedv1.StorageMu_GP3,
			},
			{
				DataVolumeType:    globaldedicatedv1.StorageMu_GP3,
				RaftlogVolumeType: globaldedicatedv1.StorageMu_IO2,
			},
		}, spu1C1G.GetSupportedDiskPairs())
	})

	t.Run("AWS TiKV Plus storage type should expose data storage detail only", func(t *testing.T) {
		spus, err := spuSvc.List(t.Context(), &globaldedicatedv1.ListSpusRequest{
			Request: &globaldedicatedv1.ListSpusRequest_WithSku{
				WithSku: &globaldedicatedv1.ListSpusRequest_FilterWithSku{
					CloudProvider: globalcommonv1.CloudProvider_AWS,
					Region:        globalcommonv1.Region_AWS_US_WEST_2,
					TenantId:      9999999999,
					ProjectId:     9999999999,
				},
			},
		})
		require.NoError(t, err)

		spu1C1G, ok := lo.Find(spus, func(s *entity.Spu) bool { return s.GetName() == "1c1g" })
		require.True(t, ok)
		assertPlusStorageTypeDetail(t, spu1C1G, 1)
	})
}

func TestDefaultSkuStorageIops(t *testing.T) {
	t.Run("fixed iops", func(t *testing.T) {
		storage := &globaldedicatedv1.Sku_Storage{
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{Iops: 123},
			},
		}

		assert.Equal(t, int32(123), defaultSkuStorageIops(storage))
	})

	t.Run("dynamic iops", func(t *testing.T) {
		storage := &globaldedicatedv1.Sku_Storage{
			SizeGiDefault: 100,
			IopsMin:       10,
			IopsMax:       1000,
			Iops: &globaldedicatedv1.Sku_Storage_IopsDynamic_{
				IopsDynamic: &globaldedicatedv1.Sku_Storage_IopsDynamic{IopsPerSizeGi: 5},
			},
		}

		assert.Zero(t, defaultSkuStorageIops(storage))
	})
}

func TestShouldBuildSpuStorageTypeDetails(t *testing.T) {
	testCases := []struct {
		name          string
		componentType globaldedicatedv1.ComponentType
		cloudProvider globalcommonv1.CloudProvider_Name
		storageType   globaldedicatedv1.Spu_StorageType
		want          bool
	}{
		{
			name:          "AWS TiKV Plus",
			componentType: globaldedicatedv1.ComponentType_TIKV,
			cloudProvider: globalcommonv1.CloudProvider_AWS,
			storageType:   globaldedicatedv1.Spu_Plus,
			want:          true,
		},
		{
			name:          "AWS TiFlash Plus",
			componentType: globaldedicatedv1.ComponentType_TIFLASH,
			cloudProvider: globalcommonv1.CloudProvider_AWS,
			storageType:   globaldedicatedv1.Spu_Plus,
		},
		{
			name:          "Azure TiKV Plus",
			componentType: globaldedicatedv1.ComponentType_TIKV,
			cloudProvider: globalcommonv1.CloudProvider_AZURE,
			storageType:   globaldedicatedv1.Spu_Plus,
		},
		{
			name:          "AWS TiKV Performance",
			componentType: globaldedicatedv1.ComponentType_TIKV,
			cloudProvider: globalcommonv1.CloudProvider_AWS,
			storageType:   globaldedicatedv1.Spu_Performance,
		},
	}

	for _, testCase := range testCases {
		t.Run(testCase.name, func(t *testing.T) {
			assert.Equal(t, testCase.want, shouldBuildSpuStorageTypeDetails(
				testCase.componentType,
				testCase.cloudProvider,
				testCase.storageType,
			))
		})
	}
}

// assertPlusStorageTypeDetail verifies that AWS Plus storage type details only expose data storage IOPS.
func assertPlusStorageTypeDetail(
	t *testing.T,
	spuEntity *entity.Spu,
	wantDataDefaultIops int32,
) {
	t.Helper()

	detail, ok := spuEntity.GetStorageTypeDetails()[globaldedicatedv1.Spu_Plus.String()]
	require.True(t, ok)
	require.NotNil(t, detail)
	require.NotNil(t, detail.GetDataStorage())
	assert.Zero(t, detail.GetDataStorage().GetDefaultSizeGi())
	assert.Zero(t, detail.GetDataStorage().GetMaxSizeGi())
	assert.Zero(t, detail.GetDataStorage().GetMinSizeGi())
	assert.Equal(t, wantDataDefaultIops, detail.GetDataStorage().GetDefaultIops())
	assert.Nil(t, detail.GetRaftlogStorage())
}

func prepareDbRecords(
	t *testing.T,
	spuSvc ServiceSpu,
	skuRepo spu.SkuRepo,
	instanceMuRepo spu.InstanceMuRepo,
	storageMuRepo spu.StorageMuRepo,
) {
	t.Helper()

	// instance MUs.
	instance1C1GArmId, err := instanceMuRepo.Save(t.Context(), &entity.InstanceMu{
		CloudProvider: globalcommonv1.CloudProvider_AWS,
		InstanceType:  "instance_type_1c1g_arm_6g.",
		CpuCore:       1,
		MemoryGi:      1,
		CpuArch:       globaldedicatedv1.InstanceMu_ARM64,
	})
	require.NoError(t, err)
	instance2C2GArmId, err := instanceMuRepo.Save(t.Context(), &entity.InstanceMu{
		CloudProvider: globalcommonv1.CloudProvider_AWS,
		InstanceType:  "instance_type_2c2g_arm_6g.",
		CpuCore:       2,
		MemoryGi:      2,
		CpuArch:       globaldedicatedv1.InstanceMu_ARM64,
	})
	require.NoError(t, err)
	instance1C1GAmdId, err := instanceMuRepo.Save(t.Context(), &entity.InstanceMu{
		CloudProvider: globalcommonv1.CloudProvider_AWS,
		InstanceType:  "instance_type_1c1g_amd",
		CpuCore:       1,
		MemoryGi:      1,
		CpuArch:       globaldedicatedv1.InstanceMu_AMD64,
	})
	require.NoError(t, err)

	// storage MUs.
	gp3Id, err := storageMuRepo.Save(t.Context(), &entity.StorageMu{
		CloudProvider: globalcommonv1.CloudProvider_AWS,
		VolumeType:    globaldedicatedv1.StorageMu_GP3,
	})
	require.NoError(t, err)
	io2Id, err := storageMuRepo.Save(t.Context(), &entity.StorageMu{
		CloudProvider: globalcommonv1.CloudProvider_AWS,
		VolumeType:    globaldedicatedv1.StorageMu_IO2,
	})
	require.NoError(t, err)

	// spus.
	spu1C1G, err := spuSvc.Create(t.Context(), &entity.Spu{
		DisplayName:   "1c1g",
		Name:          "1c1g",
		ComponentType: globaldedicatedv1.ComponentType_TIKV,
		CpuCore:       1,
		MemorySizeGi:  1,
		Mappings: []*globaldedicatedv1.Spu_Mapping{
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{123},
				SkuKey:          "1c1g-arm-data:gp3-raft:io2-max6t",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{123},
				SkuKey:          "1c1g-arm-data:gp3-raft:gp3-max6t",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{0},
				SkuKey:          "1c1g-arm-data:gp3-raft:io2",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{0},
				SkuKey:          "1c1g-arm-data:gp3-raft:gp3",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_1},
				OrganizationIds: []uint64{0},
				SkuKey:          "1c1g-arm-data:gp3-raft:none",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{9999999999},
				SkuKey:          "1c1g-arm-data:io2-raft:none",
			},
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{0},
				SkuKey:          "1c1g-amd-data:gp3-raft:io2",
			},
		},
	})
	require.NoError(t, err)
	spu2C2G, err := spuSvc.Create(t.Context(), &entity.Spu{
		DisplayName:   "2c2g",
		Name:          "2c2g",
		ComponentType: globaldedicatedv1.ComponentType_TIKV,
		CpuCore:       2,
		MemorySizeGi:  2,
		Mappings: []*globaldedicatedv1.Spu_Mapping{
			{
				CloudProvider:   globalcommonv1.CloudProvider_AWS,
				PhysicalRegions: []globalcommonv1.Region_Name{globalcommonv1.Region_AWS_US_WEST_2},
				OrganizationIds: []uint64{0},
				SkuKey:          "2c2g-arm-data:gp3-raft:io2",
			},
		},
	})
	require.NoError(t, err)

	// skus.
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:gp3-raft:io2",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(io2Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:gp3-raft:gp3",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:gp3-raft:none",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:io2-raft:none",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(io2Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:gp3-raft:io2-max6t",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     6144,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(io2Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-arm-data:gp3-raft:gp3-max6t",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     6144,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "1c1g-amd-data:gp3-raft:io2",
		SpuId:            spu1C1G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance1C1GAmdId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(io2Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
	_, err = skuRepo.Save(t.Context(), &entity.Sku{
		Key:              "2c2g-arm-data:gp3-raft:io2",
		SpuId:            spu2C2G.GetId(),
		CloudProvider:    globalcommonv1.CloudProvider_AWS,
		ComponentType:    globaldedicatedv1.ComponentType_TIKV,
		InstanceMuId:     uint64(instance2C2GArmId),
		DefaultNodeCount: 3,
		Priority:         0,
		DataStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(gp3Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
		RaftlogStorage: &globaldedicatedv1.Sku_Storage{
			StorageMuId:   uint64(io2Id),
			SizeGiDefault: 1,
			SizeGiMin:     1,
			SizeGiMax:     1,
			IopsMax:       1,
			IopsMin:       1,
			Iops: &globaldedicatedv1.Sku_Storage_IopsFixed_{
				IopsFixed: &globaldedicatedv1.Sku_Storage_IopsFixed{
					Iops: 1,
				},
			},
			ThroughputMibpsMax: 1,
			ThroughputMibpsMin: 1,
			Throughput: &globaldedicatedv1.Sku_Storage_ThroughputFixed_{
				ThroughputFixed: &globaldedicatedv1.Sku_Storage_ThroughputFixed{
					ThroughputMibps: 1,
				},
			},
		},
	})
	require.NoError(t, err)
}
