package region

import (
	"testing"

	. "github.com/onsi/gomega"
	"github.com/samber/lo"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/entity"
	regionrepo "github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/repository/region"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/pkg/testdata"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func TestRegionRepoImplSelectRegion(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name         string
		filter       regionrepo.Filter
		wantErr      bool
		wantRegion   *schema.Region
		wantProvider *schema.Provider
	}{
		{
			name: "select region by region id and tenant id order by priority and create time",
			filter: regionrepo.Filter{
				TenantId: testdata.TestOrgID,
				RegionId: globalcommonv1.Region_AWS_US_WEST_2,
			},
			wantErr:      false,
			wantRegion:   testdata.GetRegionByID(3),
			wantProvider: testdata.GetProviderByID(1),
		},
		{
			name: "no region found by tenant id and wrong region id",
			filter: regionrepo.Filter{
				TenantId: testdata.TestOrgID,
				RegionId: globalcommonv1.Region_AWS_US_EAST_2,
			},
			wantErr:      true,
			wantRegion:   nil,
			wantProvider: nil,
		},
		{
			name: "select region by region id and tenant id without whitelist",
			filter: regionrepo.Filter{
				// tenant id is not in the whitelist
				TenantId: 99999,
				RegionId: globalcommonv1.Region_AWS_US_EAST_1,
			},
			wantErr:      false,
			wantRegion:   testdata.GetRegionByID(4),
			wantProvider: testdata.GetProviderByID(1),
		},
		{
			name: "not found by region id and wrong service plan",
			filter: regionrepo.Filter{
				TenantId:    testdata.TestOrgID,
				RegionId:    globalcommonv1.Region_AWS_US_WEST_2,
				ServicePlan: globalcommonv1.ServicePlan_BYOC,
			},
			wantErr:      true,
			wantRegion:   nil,
			wantProvider: nil,
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			region, err := regionRepo.SelectRegion(t.Context(), test.filter)
			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				return
			}
			g.Expect(err).To(BeNil())
			test.wantRegion.Provider = test.wantProvider
			test.wantRegion.RegionServicePlans = lo.Filter(testdata.GetRegionServicePlanRecords(), func(item *schema.RegionServicePlan, _ int) bool {
				return item.RegionId == uint64(test.wantRegion.ID)
			})
			test.wantRegion.RegionTenants = lo.Filter(testdata.GetRegionTenantRecords(), func(item *schema.RegionTenant, _ int) bool {
				return item.RegionId == uint64(test.wantRegion.ID)
			})
			entityRegion, err := convertRegionModelToEntity(test.wantRegion)
			g.Expect(err).To(BeNil())
			g.Expect(region).To(Equal(entityRegion))
		})
	}
}

func TestConvertRegionModelToEntityServicePlans(t *testing.T) {
	g := NewWithT(t)

	schemaRegion := testdata.GetRegionByID(1)
	schemaRegion.Provider = testdata.GetProviderByID(1)
	schemaRegion.RegionServicePlans = []*schema.RegionServicePlan{
		{RegionId: uint64(schemaRegion.ID), ServicePlan: globalcommonv1.ServicePlan_Premium.String()},
		{RegionId: uint64(schemaRegion.ID), ServicePlan: globalcommonv1.ServicePlan_BYOC.String()},
	}

	region, err := convertRegionModelToEntity(schemaRegion)
	g.Expect(err).To(BeNil())
	g.Expect(region.ServicePlan).To(Equal(globalcommonv1.ServicePlan_Premium))
	g.Expect(lo.Map(region.GetRegionWhiteLists(), func(wl *globalcommonv1.RegionWhiteList, _ int) globalcommonv1.ServicePlan {
		return wl.GetServicePlan()
	})).To(ConsistOf(globalcommonv1.ServicePlan_Premium, globalcommonv1.ServicePlan_BYOC))
}

func TestConvertRegionModelToEntityRegionWhiteListsWithPlanSpecificPublic(t *testing.T) {
	g := NewWithT(t)

	region := &schema.Region{
		Name:        "us-east-1-ng",
		RegionName:  "us-east-1",
		DisplayName: "US East 1 NG",
		ServicePlan: globalcommonv1.ServicePlan_Premium.String(),
		Provider: &schema.Provider{
			Name: globalcommonv1.CloudProvider_AWS.String(),
		},
		RegionServicePlans: []*schema.RegionServicePlan{
			{
				Model:       schema.RegionServicePlan{}.Model,
				RegionId:    100,
				ServicePlan: globalcommonv1.ServicePlan_Premium.String(),
				IsPublic:    lo.ToPtr(true),
			},
			{
				Model:       schema.RegionServicePlan{}.Model,
				RegionId:    100,
				ServicePlan: globalcommonv1.ServicePlan_Premium_Reserved.String(),
				IsPublic:    lo.ToPtr(false),
			},
		},
	}
	region.RegionServicePlans[0].ID = 1001
	region.RegionServicePlans[1].ID = 1002
	region.RegionTenants = []*schema.RegionTenant{
		{RegionId: 100, RegionServicePlanId: 1002, TenantId: 20001},
		{RegionId: 100, RegionServicePlanId: 1002, TenantId: 20002},
		{RegionId: 100, RegionServicePlanId: 1001, TenantId: 30001},
	}

	en, err := convertRegionModelToEntity(region)
	g.Expect(err).To(BeNil())

	wlByPlan := lo.SliceToMap(en.GetRegionWhiteLists(),
		func(wl *globalcommonv1.RegionWhiteList) (globalcommonv1.ServicePlan, *globalcommonv1.RegionWhiteList) {
			sp := wl.GetServicePlan()
			return sp, wl
		})
	g.Expect(wlByPlan[globalcommonv1.ServicePlan_Premium].GetIsPublic()).To(BeTrue())
	g.Expect(wlByPlan[globalcommonv1.ServicePlan_Premium].GetOpenedTenantIds()).To(BeEmpty())
	g.Expect(wlByPlan[globalcommonv1.ServicePlan_Premium_Reserved].GetIsPublic()).To(BeFalse())
	g.Expect(wlByPlan[globalcommonv1.ServicePlan_Premium_Reserved].GetOpenedTenantIds()).To(ConsistOf(uint64(20001), uint64(20002)))
}

func TestNormalizeRegionServicePlans(t *testing.T) {
	g := NewWithT(t)

	region := &entity.Region{Region: &globalcommonv1.Region{
		ServicePlan: globalcommonv1.ServicePlan_Premium,
		RegionWhiteLists: []*globalcommonv1.RegionWhiteList{
			{ServicePlan: globalcommonv1.ServicePlan_BYOC},
			{ServicePlan: globalcommonv1.ServicePlan_BYOC},
		},
	}}
	g.Expect(normalizeRegionServicePlans(region)).To(Equal([]globalcommonv1.ServicePlan{globalcommonv1.ServicePlan_BYOC}))

	region.RegionWhiteLists = nil
	g.Expect(normalizeRegionServicePlans(region)).To(Equal([]globalcommonv1.ServicePlan{globalcommonv1.ServicePlan_Premium}))
}

func TestRegionRepoImplGetCloudProviderById(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name              string
		cloudProviderId   entity.CloudProviderName
		servicePlan       entity.ServicePlan
		wantErr           bool
		wantErrCode       bizerr.ErrCode
		wantCloudProvider *entity.CloudProvider
	}{
		{
			name:            "get existing cloud provider with specific service plan",
			cloudProviderId: globalcommonv1.CloudProvider_ALICLOUD,
			servicePlan:     globalcommonv1.ServicePlan_Premium,
			wantErr:         false,
			wantCloudProvider: &entity.CloudProvider{
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_ALICLOUD,
					State:       globalcommonv1.CloudProvider_INACTIVE,
					IsPublic:    true,
					ServicePlan: globalcommonv1.ServicePlan_Premium,
				},
				ProviderID: 2,
			},
		},
		{
			name:            "get existing cloud provider with unspecified service plan",
			cloudProviderId: globalcommonv1.CloudProvider_AWS,
			servicePlan:     globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED,
			wantErr:         false,
			wantCloudProvider: &entity.CloudProvider{
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_AWS,
					State:       globalcommonv1.CloudProvider_ACTIVE,
					IsPublic:    true,
					ServicePlan: globalcommonv1.ServicePlan_Premium,
				},
				ProviderID: 1,
			},
		},
		{
			// GCP exists in testdata as BYOC; querying with Premium returns not-found because
			// GetCloudProviderById filters by (vendor, plan) to support per-plan duplicate checks.
			name:            "cloud provider exists with mismatched service plan returns not found",
			cloudProviderId: globalcommonv1.CloudProvider_GCP,
			servicePlan:     globalcommonv1.ServicePlan_Premium,
			wantErr:         true,
			wantErrCode:     bizerr.ErrCodeRecordNotFound,
		},
		{
			// ALICLOUD exists as Premium; querying with BYOC returns not-found.
			name:            "cloud provider exists but wrong service plan returns not found",
			cloudProviderId: globalcommonv1.CloudProvider_ALICLOUD,
			servicePlan:     globalcommonv1.ServicePlan_BYOC,
			wantErr:         true,
			wantErrCode:     bizerr.ErrCodeRecordNotFound,
		},
		{
			name:            "unsupported cloud provider",
			cloudProviderId: globalcommonv1.CloudProvider_NAME_UNSPECIFIED,
			servicePlan:     globalcommonv1.ServicePlan_Premium,
			wantErr:         true,
			wantErrCode:     bizerr.ErrCodeRecordNotFound,
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			cloudProvider, err := regionRepo.GetCloudProviderById(t.Context(), test.cloudProviderId, test.servicePlan)

			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				if test.wantErrCode != bizerr.ErrCodeOK {
					bizErr, ok := err.(*bizerr.BizErr)
					g.Expect(ok).To(BeTrue())
					g.Expect(bizErr.ErrCode()).To(Equal(test.wantErrCode))
				}
				return
			}

			g.Expect(err).To(BeNil())
			g.Expect(cloudProvider).ToNot(BeNil())

			// Verify basic fields
			g.Expect(cloudProvider.Id).To(Equal(test.wantCloudProvider.Id))
			g.Expect(cloudProvider.State).To(Equal(test.wantCloudProvider.State))
			g.Expect(cloudProvider.IsPublic).To(Equal(test.wantCloudProvider.IsPublic))
			g.Expect(cloudProvider.ServicePlan).To(Equal(test.wantCloudProvider.ServicePlan))
		})
	}
}

func TestRegionRepoImplSaveCloudProvider(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name            string
		cloudProvider   *entity.CloudProvider
		wantErr         bool
		wantErrCode     bizerr.ErrCode
		wantServicePlan globalcommonv1.ServicePlan // if non-zero, overrides cloudProvider.ServicePlan in verification
		setupMock       func()
		verifyResult    func()
	}{
		{
			name: "create new cloud provider successfully",
			cloudProvider: &entity.CloudProvider{
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_GCP,
					DisplayName: "GCP",
					State:       globalcommonv1.CloudProvider_ACTIVE,
					IsPublic:    true,
					ServicePlan: globalcommonv1.ServicePlan_Essential,
				},
			},
			wantErr: false,
		},
		{
			name: "update existing cloud provider successfully",
			cloudProvider: &entity.CloudProvider{
				ProviderID: 1,
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_AWS,
					DisplayName: "AWS Updated",
					State:       globalcommonv1.CloudProvider_ACTIVE,
					IsPublic:    false,
					ServicePlan: globalcommonv1.ServicePlan_Premium,
				},
			},
			wantErr: false,
		},
		{
			name: "cloud provider with inactive state",
			cloudProvider: &entity.CloudProvider{
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_AZURE,
					DisplayName: "Azure",
					State:       globalcommonv1.CloudProvider_INACTIVE,
					IsPublic:    true,
					ServicePlan: globalcommonv1.ServicePlan_Starter,
				},
			},
			wantErr: false,
		},
		{
			// With region/plan decoupling, unspecified service plan defaults to Premium in
			// convertCloudProviderEntityToModel, so this save now succeeds.
			name: "unspecified service plan defaults to Premium",
			cloudProvider: &entity.CloudProvider{
				CloudProvider: &globalcommonv1.CloudProvider{
					Id:          globalcommonv1.CloudProvider_AWS,
					DisplayName: "AWS",
					State:       globalcommonv1.CloudProvider_ACTIVE,
					IsPublic:    true,
					ServicePlan: globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED,
				},
			},
			wantErr:         false,
			wantServicePlan: globalcommonv1.ServicePlan_Premium,
		},
		{
			name:          "nil cloud provider",
			cloudProvider: nil,
			wantErr:       true,
			wantErrCode:   bizerr.ErrCodeParams,
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			err := regionRepo.SaveCloudProvider(t.Context(), test.cloudProvider)

			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				if test.wantErrCode != bizerr.ErrCodeOK {
					bizErr, ok := err.(*bizerr.BizErr)
					g.Expect(ok).To(BeTrue())
					g.Expect(bizErr.ErrCode()).To(Equal(test.wantErrCode))
				}
				return
			}

			g.Expect(err).To(BeNil())

			// Verify the cloud provider was saved correctly
			if test.cloudProvider != nil {
				lookupPlan := test.cloudProvider.ServicePlan
				wantPlan := test.cloudProvider.ServicePlan
				if test.wantServicePlan != globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED {
					wantPlan = test.wantServicePlan
					lookupPlan = test.wantServicePlan
				}
				savedProvider, err := regionRepo.GetCloudProviderById(
					t.Context(),
					test.cloudProvider.Id,
					lookupPlan,
				)
				g.Expect(err).To(BeNil())
				g.Expect(savedProvider).ToNot(BeNil())
				g.Expect(savedProvider.Id).To(Equal(test.cloudProvider.Id))
				g.Expect(savedProvider.DisplayName).To(Equal(test.cloudProvider.DisplayName))
				g.Expect(savedProvider.State).To(Equal(test.cloudProvider.State))
				g.Expect(savedProvider.IsPublic).To(Equal(test.cloudProvider.IsPublic))
				g.Expect(savedProvider.ServicePlan).To(Equal(wantPlan))
			}
		})
	}
}

func TestRegionRepoImplSaveRegion(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name         string
		region       *entity.Region
		wantErr      bool
		wantErrCode  bizerr.ErrCode
		setupMock    func()
		verifyResult func()
	}{
		{
			name: "create new region successfully",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-new",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) New",
					OpenedTenantIds:   []uint64{1001, 1002},
					SortPriority:      200,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          false,
					DefaultBackupTime: "12:00",
					ServiceAddress:    "https://new-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0, // Will be generated
				ProviderID:        1,
				RegionLogicalName: "us-west-2-new",
			},
			wantErr: false,
		},
		{
			name: "update existing region successfully",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-a0",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Updated",
					OpenedTenantIds:   []uint64{1001, 1003},
					SortPriority:      150,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          false,
					DefaultBackupTime: "14:00",
					ServiceAddress:    "https://updated-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          1,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-a0",
			},
			wantErr: false,
		},
		{
			name: "create public region without tenant ids",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_EAST_1,
					LogicalName:       "us-east-1-public",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Virginia (us-east-1) Public",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://public-us-east-1.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-east-1-public",
			},
			wantErr: false,
		},
		{
			name: "region with unspecified service plan",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-invalid",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Invalid",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://invalid-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-invalid",
			},
			wantErr:     true,
			wantErrCode: bizerr.ErrCodeParams,
		},
		{
			name: "region with non-existent cloud provider",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-invalid-provider",
					CloudProviderId:   globalcommonv1.CloudProvider_NAME_UNSPECIFIED,
					DisplayName:       "Oregon (us-west-2) Invalid Provider",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://invalid-provider-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-invalid-provider",
			},
			wantErr:     true,
			wantErrCode: bizerr.ErrCodeRecordNotFound,
		},
		{
			name: "region with empty logical name (should use region id as default)",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Default Name",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://default-name-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "",
			},
			wantErr: false,
		},
		{
			name:        "nil region",
			region:      nil,
			wantErr:     true,
			wantErrCode: bizerr.ErrCodeParams,
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			err := regionRepo.SaveRegion(t.Context(), test.region)

			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				if test.wantErrCode != bizerr.ErrCodeOK {
					bizErr, ok := err.(*bizerr.BizErr)
					g.Expect(ok).To(BeTrue())
					g.Expect(bizErr.ErrCode()).To(Equal(test.wantErrCode))
				}
				return
			}

			g.Expect(err).To(BeNil())

			// Verify the region was saved correctly
			if test.region != nil {
				// Get the region by logical name to verify it was saved
				logicalName := test.region.GetLogicalName()
				if logicalName == "" {
					logicalName = test.region.Id.String()
				}

				savedRegion, err := regionRepo.GetByLogicalName(t.Context(), logicalName)
				g.Expect(err).To(BeNil())
				g.Expect(savedRegion).ToNot(BeNil())

				// Verify basic fields
				g.Expect(savedRegion.Id).To(Equal(test.region.Id))
				g.Expect(savedRegion.DisplayName).To(Equal(test.region.DisplayName))
				g.Expect(savedRegion.CloudProviderId).To(Equal(test.region.CloudProviderId))
				g.Expect(savedRegion.ServicePlan).To(Equal(test.region.ServicePlan))
				g.Expect(savedRegion.IsPublic).To(Equal(test.region.IsPublic))
				g.Expect(savedRegion.SortPriority).To(Equal(test.region.SortPriority))
				g.Expect(savedRegion.Area).To(Equal(test.region.Area))
				g.Expect(savedRegion.CountryCode).To(Equal(test.region.CountryCode))
				g.Expect(savedRegion.State).To(Equal(test.region.State))
				g.Expect(savedRegion.DefaultBackupTime).To(Equal(test.region.DefaultBackupTime))
				g.Expect(savedRegion.ServiceAddress).To(Equal(test.region.ServiceAddress))

				// Verify tenant access for private regions
				if !test.region.IsPublic && len(test.region.OpenedTenantIds) > 0 {
					for _, tenantId := range test.region.OpenedTenantIds {
						// Check if tenant can access the region
						region, err := regionRepo.SelectRegion(t.Context(), regionrepo.Filter{
							RegionId:    test.region.Id,
							TenantId:    tenantId,
							ServicePlan: test.region.ServicePlan,
						})
						g.Expect(err).To(BeNil())
						g.Expect(region).ToNot(BeNil())
					}
				}
			}
		})
	}
}

func TestRegionRepoImplSaveRegionEdgeCases(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name        string
		region      *entity.Region
		wantErr     bool
		wantErrCode bizerr.ErrCode
		description string
	}{
		{
			name: "region with very long display name",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-long-name",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "This is a very long display name for testing purposes that exceeds normal limits",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://long-name-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-long-name",
			},
			wantErr:     false,
			description: "Should handle long display names gracefully",
		},
		{
			name: "region with special characters in logical name",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-special-chars-123",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Special",
					OpenedTenantIds:   []uint64{},
					SortPriority:      100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://special-chars-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-special-chars-123",
			},
			wantErr:     false,
			description: "Should handle special characters in logical name",
		},
		{
			name: "region with zero priority",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-zero-priority",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Zero Priority",
					OpenedTenantIds:   []uint64{},
					SortPriority:      0,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://zero-priority-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-zero-priority",
			},
			wantErr:     false,
			description: "Should handle zero priority values",
		},
		{
			name: "region with negative priority",
			region: &entity.Region{
				Region: &globalcommonv1.Region{
					Id:                globalcommonv1.Region_AWS_US_WEST_2,
					LogicalName:       "us-west-2-negative-priority",
					CloudProviderId:   globalcommonv1.CloudProvider_AWS,
					DisplayName:       "Oregon (us-west-2) Negative Priority",
					OpenedTenantIds:   []uint64{},
					SortPriority:      -100,
					Area:              "Americas",
					CountryCode:       "US",
					State:             globalcommonv1.Region_ACTIVE,
					IsPublic:          true,
					DefaultBackupTime: "10:00",
					ServiceAddress:    "https://negative-priority-us-west-2.tidbcloud.com",
					ServicePlan:       globalcommonv1.ServicePlan_Premium,
				},
				RegionID:          0,
				ProviderID:        1,
				RegionLogicalName: "us-west-2-negative-priority",
			},
			wantErr:     false,
			description: "Should handle negative priority values",
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			err := regionRepo.SaveRegion(t.Context(), test.region)

			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				if test.wantErrCode != bizerr.ErrCodeOK {
					bizErr, ok := err.(*bizerr.BizErr)
					g.Expect(ok).To(BeTrue())
					g.Expect(bizErr.ErrCode()).To(Equal(test.wantErrCode))
				}
				return
			}

			g.Expect(err).To(BeNil())

			// Verify the region was saved correctly
			if test.region != nil {
				logicalName := test.region.GetLogicalName()
				if logicalName == "" {
					logicalName = test.region.Id.String()
				}

				savedRegion, err := regionRepo.GetByLogicalName(t.Context(), logicalName)
				g.Expect(err).To(BeNil())
				g.Expect(savedRegion).ToNot(BeNil())

				// Verify the specific edge case behavior
				g.Expect(savedRegion.Id).To(Equal(test.region.Id))
				g.Expect(savedRegion.DisplayName).To(Equal(test.region.DisplayName))
				expectedPriority := test.region.SortPriority
				if expectedPriority == 0 {
					expectedPriority = 999999
				}
				g.Expect(savedRegion.SortPriority).To(Equal(expectedPriority))
			}
		})
	}
}

func TestRegionRepoImplListRegions(t *testing.T) {
	g := NewWithT(t)

	tests := []struct {
		name            string
		filter          regionrepo.Filter
		wantErr         bool
		wantErrCode     bizerr.ErrCode
		expectedCount   int
		expectedRegions []string // logical names of expected regions
	}{
		{
			name: "list regions with service plan",
			filter: regionrepo.Filter{
				CloudProvider: globalcommonv1.CloudProvider_GCP,
				ServicePlan:   globalcommonv1.ServicePlan_BYOC,
			},
			wantErr:         false,
			expectedCount:   1, // 1 BYOC region
			expectedRegions: []string{"us-east1-a0"},
		},
		{
			name: "list regions with unspecified state",
			filter: regionrepo.Filter{
				CloudProvider: globalcommonv1.CloudProvider_GCP,
				ServicePlan:   globalcommonv1.ServicePlan_BYOC,
				State:         globalcommonv1.Region_STATE_UNSPECIFIED.String(),
			},
			wantErr:         false,
			expectedCount:   1, // 1
			expectedRegions: []string{"us-east1-a0"},
		},
		{
			name: "list regions with inactive state",
			filter: regionrepo.Filter{
				CloudProvider: globalcommonv1.CloudProvider_GCP,
				ServicePlan:   globalcommonv1.ServicePlan_BYOC,
				State:         globalcommonv1.Region_INACTIVE.String(),
			},
			wantErr:         false,
			expectedCount:   0, // 0
			expectedRegions: []string{},
		},
		{
			name: "list regions with tenant id 0 and service plan",
			filter: regionrepo.Filter{
				CloudProvider: globalcommonv1.CloudProvider_GCP,
				ServicePlan:   globalcommonv1.ServicePlan_BYOC,
				TenantId:      0,
			},
			wantErr:         false,
			expectedCount:   1, // 1
			expectedRegions: []string{"us-east1-a0"},
		},
		{
			name: "list regions with tenant id 0 and service plan",
			filter: regionrepo.Filter{
				CloudProvider: globalcommonv1.CloudProvider_GCP,
				ServicePlan:   globalcommonv1.ServicePlan_BYOC,
				TenantId:      999,
			},
			wantErr:         false,
			expectedCount:   0, // 0
			expectedRegions: []string{},
		},
	}

	dbPvd := *dbProvider.Load()
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			regionRepo := NewRegionRepo(dbPvd)
			regions, err := regionRepo.ListRegions(t.Context(), test.filter)

			if test.wantErr {
				g.Expect(err).To(HaveOccurred())
				if test.wantErrCode != bizerr.ErrCodeOK {
					bizErr, ok := err.(*bizerr.BizErr)
					g.Expect(ok).To(BeTrue())
					g.Expect(bizErr.ErrCode()).To(Equal(test.wantErrCode))
				}
				return
			}

			g.Expect(err).To(BeNil())
			g.Expect(regions).ToNot(BeNil())
			g.Expect(len(regions)).To(Equal(test.expectedCount))

			// Verify that all returned regions match the expected logical names
			if len(test.expectedRegions) > 0 {
				actualLogicalNames := make([]string, len(regions))
				for i, region := range regions {
					actualLogicalNames[i] = region.GetLogicalName()
				}

				for _, expectedName := range test.expectedRegions {
					g.Expect(actualLogicalNames).To(ContainElement(expectedName))
				}
			}

			// Verify that all returned regions have the expected properties based on filters
			for _, region := range regions {
				if test.filter.ServicePlan != globalcommonv1.ServicePlan_SERVICE_PLAN_UNSPECIFIED {
					g.Expect(region.ServicePlan).To(Equal(test.filter.ServicePlan))
				}
				if test.filter.CloudProvider != globalcommonv1.CloudProvider_NAME_UNSPECIFIED {
					g.Expect(region.CloudProviderId).To(Equal(test.filter.CloudProvider))
				}
				if test.filter.State != "" && test.filter.State != globalcommonv1.Region_STATE_UNSPECIFIED.String() {
					g.Expect(region.State.String()).To(Equal(test.filter.State))
				}

				// Verify that regions are properly converted from schema to entity
				g.Expect(region.Region).ToNot(BeNil())
				g.Expect(region.GetLogicalName()).ToNot(BeEmpty())
				g.Expect(region.DisplayName).ToNot(BeEmpty())
				g.Expect(region.CloudProviderId).ToNot(Equal(globalcommonv1.CloudProvider_NAME_UNSPECIFIED))
			}
		})
	}
}
