package regionserver

import (
	"context"

	clusteragentv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-agent/v1"
	clusterdedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/cluster-server/v1"
	regionaldedicatedv1 "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	"google.golang.org/protobuf/types/known/emptypb"

	"github.com/tidbcloud/tidb-management-service/dedicated-global-service/domain/entity"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

//go:generate go run go.uber.org/mock/mockgen@latest -source=$GOFILE -package=mock_$GOPACKAGE -destination=./mock_$GOPACKAGE/mock_$GOFILE
type Client interface {
	// Ping service
	Ping(ctx context.Context, region *entity.Region, req *emptypb.Empty) (*regionaldedicatedv1.Pong, bizerr.BizError)

	// VPC service
	CreateVpc(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateVpcRequest,
	) (*regionaldedicatedv1.Vpc, bizerr.BizError)
	GetVpc(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetVpcRequest,
	) (*regionaldedicatedv1.Vpc, bizerr.BizError)
	ListVpcs(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListVpcsRequest,
	) (*regionaldedicatedv1.ListVpcsResponse, bizerr.BizError)
	DeleteVpc(ctx context.Context, region *entity.Region, req *regionaldedicatedv1.DeleteVpcRequest) bizerr.BizError
	AddSecondaryCidr(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.AddSecondaryCidrRequest,
	) (*regionaldedicatedv1.Vpc, bizerr.BizError)

	// VPC peering service
	CreateVpcPeering(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateVpcPeeringRequest,
	) (*regionaldedicatedv1.VpcPeering, bizerr.BizError)
	DeleteVpcPeering(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.DeleteVpcPeeringRequest,
	) bizerr.BizError
	ListVpcPeerings(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListVpcPeeringsRequest,
	) (*regionaldedicatedv1.ListVpcPeeringsResponse, bizerr.BizError)
	GetVpcPeering(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetVpcPeeringRequest,
	) (*regionaldedicatedv1.VpcPeering, bizerr.BizError)
	AcceptVpcPeering(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.AcceptVpcPeeringRequest,
	) bizerr.BizError

	// Cluster service
	CreateCluster(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateClusterRequest,
	) (*regionaldedicatedv1.Cluster, bizerr.BizError)
	GetCluster(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetClusterRequest,
	) (*clusterdedicatedv1.Cluster, bizerr.BizError)
	ListClusters(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListClustersRequest,
	) (*clusterdedicatedv1.ListClustersResponse, bizerr.BizError)
	DeleteCluster(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.DeleteClusterRequest,
	) bizerr.BizError
	PauseCluster(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.PauseClusterRequest,
	) (*regionaldedicatedv1.PauseClusterResponse, bizerr.BizError)
	ResumeCluster(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ResumeClusterRequest,
	) (*regionaldedicatedv1.ResumeClusterResponse, bizerr.BizError)
	SetVersionAndConfigurations(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.SetVersionAndConfigurationsRequest,
	) (*regionaldedicatedv1.SetVersionAndConfigurationsResponse, bizerr.BizError)
	GetComponentNodeInfo(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetComponentNodeInfosRequest,
	) (*regionaldedicatedv1.GetComponentNodeInfosResponse, bizerr.BizError)
	ScaleComponent(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ScaleClusterRequest,
	) (*regionaldedicatedv1.ScaleClusterResponse, bizerr.BizError)
	GetCaCertificate(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetCaCertificateRequest,
	) (*regionaldedicatedv1.CaCertificate, bizerr.BizError)
	SetClientCaCertificate(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.SetClientCaCertificateRequest,
	) (*regionaldedicatedv1.CaCertificate, bizerr.BizError)
	GetClusterRole(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetClusterRoleRequest,
	) (*regionaldedicatedv1.ClusterRole, bizerr.BizError)
	ValidateSecurityConfiguration(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ValidateSecurityConfigurationRequest,
	) (*regionaldedicatedv1.ValidateSecurityConfigurationResponse, bizerr.BizError)
	CheckClusterPublicLBInboundRulesStatus(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.CheckClusterPublicLBInboundRulesStatusRequest,
	) (*clusterdedicatedv1.CheckClusterPublicLBInboundRulesStatusResponse, bizerr.BizError)
	EnableGKEPolicyControl(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.EnableGKEPolicyControlRequest,
	) (*regionaldedicatedv1.GKEPolicyControl, bizerr.BizError)
	GetGKEPolicyControl(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetGKEPolicyControlRequest,
	) (*regionaldedicatedv1.GKEPolicyControl, bizerr.BizError)
	CreateGKEHeterogeneousDeploy(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateGKEHeterogeneousDeployRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousDeploy, bizerr.BizError)
	UpdateGKEHeterogeneousDeploy(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.UpdateGKEHeterogeneousDeployRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousDeploy, bizerr.BizError)
	GetGKEHeterogeneousDeploy(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetGKEHeterogeneousDeployRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousDeploy, bizerr.BizError)
	DeleteGKEHeterogeneousDeploy(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.DeleteGKEHeterogeneousDeployRequest,
	) bizerr.BizError
	CreateGKEHeterogeneousNodePool(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateGKEHeterogeneousNodePoolRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousNodePool, bizerr.BizError)
	GetGKEHeterogeneousNodePools(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetGKEHeterogeneousNodePoolsRequest,
	) (*regionaldedicatedv1.ListGKEHeterogeneousNodePoolsResponse, bizerr.BizError)
	ListGKEHeterogeneousNodePools(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListGKEHeterogeneousNodePoolsRequest,
	) (*regionaldedicatedv1.ListGKEHeterogeneousNodePoolsResponse, bizerr.BizError)
	CreateGKEHeterogeneousComputeClass(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateGKEHeterogeneousComputeClassRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousComputeClass, bizerr.BizError)
	GetGKEHeterogeneousComputeClass(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetGKEHeterogeneousComputeClassRequest,
	) (*regionaldedicatedv1.GetGKEHeterogeneousComputeClassResponse, bizerr.BizError)
	DeleteGKEHeterogeneousComputeClass(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.DeleteGKEHeterogeneousComputeClassRequest,
	) bizerr.BizError
	CreateGKEHeterogeneousGatekeeperAssign(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreateGKEHeterogeneousGatekeeperAssignRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousGatekeeperAssign, bizerr.BizError)
	GetGKEHeterogeneousGatekeeperAssign(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetGKEHeterogeneousGatekeeperAssignRequest,
	) (*regionaldedicatedv1.GKEHeterogeneousGatekeeperAssign, bizerr.BizError)
	DeleteGKEHeterogeneousGatekeeperAssign(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.DeleteGKEHeterogeneousGatekeeperAssignRequest,
	) bizerr.BizError

	// PrivateLink Connection Service
	CreatePrivateLinkService(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreatePrivateLinkServiceRequest,
	) (*regionaldedicatedv1.PrivateLinkService, bizerr.BizError)
	GetPrivateLinkService(
		ctx context.Context,
		region *entity.Region,
		req *GetPrivateLinkServiceRequest,
	) (*regionaldedicatedv1.PrivateLinkService, bizerr.BizError)
	ListPrivateLinkServices(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListPrivateLinkServicesRequest,
	) (*regionaldedicatedv1.ListPrivateLinkServicesResponse, bizerr.BizError)
	UpdatePrivateLinkService(
		ctx context.Context,
		region *entity.Region,
		req *UpdatePrivateLinkServiceRequest,
	) (*regionaldedicatedv1.PrivateLinkService, bizerr.BizError)
	DeletePrivateLinkService(
		ctx context.Context,
		region *entity.Region,
		req *DeletePrivateLinkServiceRequest,
	) bizerr.BizError
	RejectVpcEndpointConnections(
		ctx context.Context,
		region *entity.Region,
		req *RejectVpcEndpointConnectionsRequest,
	) (*emptypb.Empty, bizerr.BizError)
	PausePrivateLinkService(
		ctx context.Context,
		region *entity.Region,
		req *PausePrivateLinkServiceRequest,
	) (*emptypb.Empty, bizerr.BizError)
	PurgePrivateLinkMetadata(
		ctx context.Context,
		region *entity.Region,
		req *PurgePrivateLinkMetadataRequest,
	) (*emptypb.Empty, bizerr.BizError)
	GetTidbGroupPrivateLinkIPAddressType(
		ctx context.Context,
		region *entity.Region,
		clusterID, tidbGroupID string,
	) (*regionaldedicatedv1.PrivateLinkIPAddressTypeStatus, bizerr.BizError)
	SetTidbGroupPrivateLinkIPAddressType(
		ctx context.Context,
		region *entity.Region,
		clusterID, tidbGroupID string,
		addressType regionaldedicatedv1.PrivateLinkIPAddressType,
	) bizerr.BizError
	ValidateTidbGroupPrivateLinkIPv4Only(
		ctx context.Context,
		region *entity.Region,
		clusterID, tidbGroupID string,
	) bizerr.BizError

	// Compatibility Service. Old infra-api apis needed by dp/ops/dataflow team.
	GetCompatNetwork(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetCompatNetworkRequest,
	) (*regionaldedicatedv1.CompatNetwork, bizerr.BizError)
	GetRegionConfig(ctx context.Context, region *entity.Region) (*regionaldedicatedv1.RegionConfig, bizerr.BizError)
	ListAppBoxes(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListAPPBoxesRequest,
	) (*regionaldedicatedv1.ListAPPBoxesResponse, bizerr.BizError)

	// TidbGroup Service
	CreateTidbGroup(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.CreateTidbGroupRequest,
	) (*clusterdedicatedv1.TidbGroup, bizerr.BizError)
	GetTidbGroup(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.GetTidbGroupRequest,
	) (*clusterdedicatedv1.TidbGroup, bizerr.BizError)
	ListTidbGroups(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.ListTidbGroupsRequest,
	) (*clusterdedicatedv1.ListTidbGroupsResponse, bizerr.BizError)
	UpdateTidbGroup(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.UpdateTidbGroupRequest,
	) (*clusterdedicatedv1.TidbGroup, bizerr.BizError)
	DeleteTidbGroup(
		ctx context.Context,
		region *entity.Region,
		req *clusterdedicatedv1.DeleteTidbGroupRequest,
	) bizerr.BizError

	// DB Audit Log Service
	SetAuditLogConfiguration(
		ctx context.Context,
		region *entity.Region,
		in *clusterdedicatedv1.SetAuditLogConfigurationRequest,
	) (*clusterdedicatedv1.AuditLogConfiguration, bizerr.BizError)
	GetAuditLogConfiguration(
		ctx context.Context,
		region *entity.Region,
		in *clusterdedicatedv1.GetAuditLogConfigurationRequest,
	) (*clusterdedicatedv1.AuditLogConfiguration, bizerr.BizError)
	ValidateAuditLogConfiguration(
		ctx context.Context,
		region *entity.Region,
		in *clusterdedicatedv1.ValidateAuditLogConfigurationRequest,
	) (*clusterdedicatedv1.ValidateAuditLogConfigurationResponse, bizerr.BizError)
	ListAuditLogs(
		ctx context.Context,
		region *entity.Region,
		in *clusterdedicatedv1.ListAuditLogsRequest,
	) (*clusterdedicatedv1.ListAuditLogsResponse, bizerr.BizError)
	GetAuditLogDownloadUrl(
		ctx context.Context,
		region *entity.Region,
		in *clusterdedicatedv1.GetAuditLogDownloadURLRequest,
	) (*clusterdedicatedv1.GetAuditLogDownloadURLResponse, bizerr.BizError)

	// Account
	AssignAccount(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.AssignAccountRequest,
	) (*regionaldedicatedv1.Account, bizerr.BizError)
	GetAccount(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetAccountRequest,
	) (*regionaldedicatedv1.Account, bizerr.BizError)

	// PrivateLinkServiceMigration Service
	CreatePrivateLinkServiceMigration(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.CreatePrivateLinkServiceMigrationRequest,
	) (*regionaldedicatedv1.PrivateLinkServiceMigration, bizerr.BizError)

	GetPrivateLinkServiceMigration(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.GetPrivateLinkServiceMigrationRequest,
	) (*regionaldedicatedv1.PrivateLinkServiceMigration, bizerr.BizError)

	ListPrivateLinkServiceMigrations(
		ctx context.Context,
		region *entity.Region,
		req *regionaldedicatedv1.ListPrivateLinkServiceMigrationsRequest,
	) (*regionaldedicatedv1.ListPrivateLinkServiceMigrationsResponse, bizerr.BizError)

	// cluster agent service
	ExecuteClusterAgentCommand(
		ctx context.Context,
		region *entity.Region,
		clusterId string,
		req *clusteragentv1.ExecuteCommandReq,
	) (*clusteragentv1.ExecuteCommandResp, bizerr.BizError)

	PauseClusterTc(
		ctx context.Context,
		region *entity.Region,
		clusterId string,
	) bizerr.BizError

	DeleteClusterAstsAndResumeTc(
		ctx context.Context,
		region *entity.Region,
		clusterId string,
	) bizerr.BizError

	ListClusterTcs(
		ctx context.Context,
		region *entity.Region,
		clusterId string,
	) (*clusteragentv1.ListTCsResp, bizerr.BizError)
}

type GetPrivateLinkServiceRequest struct {
	ClusterId   string
	TidbGroupId string
}

type DeletePrivateLinkServiceRequest struct {
	ClusterId   string
	TidbGroupId string
}

type UpdatePrivateLinkServiceRequest struct {
	ClusterId              string
	TidbGroupId            string
	PrivateLinkConnections []*regionaldedicatedv1.PrivateLinkService_Connection
	ValidateOnly           bool
}

type RejectVpcEndpointConnectionsRequest struct {
	ClusterId   string
	TidbGroupId string
	EndpointIds []string
}

type PausePrivateLinkServiceRequest struct {
	ClusterId   string
	TidbGroupId string
}

type PurgePrivateLinkMetadataRequest struct {
	ClusterId   string
	TidbGroupId string
}
