package entity

import (
	"slices"

	globalcommonv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/common/v1"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

// Entities.
type (
	CloudProvider     = globalcommonv1.CloudProvider
	Region            = globalcommonv1.Region
	CloudProviderName = globalcommonv1.CloudProvider_Name
	RegionName        = globalcommonv1.Region_Name
)

func IsRegionOpenToTenant(region *Region, tenantID uint64) bool {
	if region.IsPublic {
		return true
	}

	return slices.Contains(region.OpenedTenantIds, tenantID)
}

func CheckCloudProviderAndRegion(cloudProvider *CloudProvider, region *Region) bizerr.BizError {
	if cloudProvider.State != globalcommonv1.CloudProvider_ACTIVE {
		return bizerr.New(bizerr.ErrCodeParams, "inactive cloud provider %s", cloudProvider.Id)
	}

	if region.State != globalcommonv1.Region_ACTIVE {
		return bizerr.New(bizerr.ErrCodeParams, "inactive region %s in %s cloud provider", region.Id, cloudProvider.Id)
	}

	if region.CloudProviderId != cloudProvider.Id {
		return bizerr.New(bizerr.ErrCodeParams, "region %s is not in cloud provider %s", region.Id, cloudProvider.Id)
	}

	return nil
}

func CheckCloudProviderAndRegionAvailableForTenant(
	cloudProvider *CloudProvider,
	region *Region,
	tenantID uint64,
) bizerr.BizError {
	err := CheckCloudProviderAndRegion(cloudProvider, region)
	if err != nil {
		return err
	}

	if !IsRegionOpenToTenant(region, tenantID) {
		return bizerr.New(bizerr.ErrCodeParams, "region %s is unavailable", region.Id)
	}

	return nil
}

type BasicRegion struct {
	Name              RegionName
	LogicalName       string
	DisplayName       string
	CloudProviderName CloudProviderName
}

func RegionToBasicRegion(r *Region) *BasicRegion {
	return &BasicRegion{
		Name:              r.Id,
		DisplayName:       r.DisplayName,
		LogicalName:       r.LogicalName,
		CloudProviderName: r.CloudProviderId,
	}
}
