package facade

import (
	"context"
	"time"

	"github.com/tidbcloud/pkgv2/bizerr"
	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	regionalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/regional/serverless/v1"
	openapicommonv1beta1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_cloud_open_api/common/v1beta1"
	tidbmgmtservicev1 "github.com/tidbcloud/tidb-management-service/api/spec/tidb_mgmt_service/v1"
)

type MgmtSvcFacade interface {
	// GetCluster apply undeleted and serverless filter inside.
	// Local View: all fields under mgmtapi.Cluster are accessiable
	// Basic View: all fields except usage, spendlimit, backuppolicy under mgmtapi.Cluster.GetServerlessCluster() are accessiable
	// since these fields need to interact with other services
	// Full View: usage, spendlimit, backuppolicy are also accessiable
	GetCluster(
		ctx context.Context,
		clusterId uint64,
		view tidbmgmtservicev1.ClusterFilter_ClusterView,
	) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// Same as GetCluster, but include dedicated cluster.
	GetClusterIncludeDedicated(
		ctx context.Context,
		clusterId uint64,
		view tidbmgmtservicev1.ClusterFilter_ClusterView,
	) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// Same as GetCluster, but include deleted cluster.
	GetClusterIncludeDeleted(ctx context.Context, clusterId uint64) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// No builtin filter, caller should assemble the filter by themselves. No pagination is done by default and in such cases
	// at most 1000 clusters will be returned. If you want to list all clusters, use ListAllClusters instead.
	ListClusters(
		ctx context.Context,
		req *tidbmgmtservicev1.ListClustersRequest,
	) (*tidbmgmtservicev1.ListClustersResponse, bizerr.BizError)
	ListAllClusters(
		ctx context.Context,
		req *tidbmgmtservicev1.ListClustersRequest,
	) ([]*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// ListAllClustersInOrg list all undeleted serverless clusters in the org
	ListAllClustersInOrg(
		ctx context.Context,
		orgId uint64,
		view tidbmgmtservicev1.ClusterFilter_ClusterView,
	) ([]*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// ListDeletedClustersInOrg lists all deleted serverless clusters in the org
	ListDeletedClustersInOrg(
		ctx context.Context,
		orgId uint64,
		view tidbmgmtservicev1.ClusterFilter_ClusterView,
	) ([]*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// SetClusterRestoreInPlaceStatus set cluster custom status when restore in place
	SetClusterRestoreInPlaceStatus(
		ctx context.Context,
		clusterId uint64,
		restoreId string,
		timeout time.Duration,
	) (uint64, bizerr.BizError)
	// SetClusterRestoreToNewStatus set cluster custom status when restore to new
	SetClusterRestoreToNewStatus(
		ctx context.Context,
		clusterId uint64,
		restoreId string,
	) (uint64, bizerr.BizError)
	// SetClusterCDCStatus set cluster custom status when cdc is running
	SetClusterCDCStatus(ctx context.Context, clusterId uint64) (uint64, bizerr.BizError)
	SetClusterMigrationStatus(ctx context.Context, clusterId uint64) (uint64, bizerr.BizError)
	// SetClusterImportStatus set cluster custom status when import is running
	SetClusterImportStatus(ctx context.Context, clusterId uint64) (uint64, bizerr.BizError)
	// RegisterCDCClusterJob registers a cluster job for a CDC task.
	RegisterCDCClusterJob(ctx context.Context, clusterId uint64, jobId string) bizerr.BizError
	// DeregisterCDCClusterJob deregisters a cluster job for a CDC task.
	DeregisterCDCClusterJob(ctx context.Context, clusterId uint64, jobId string) bizerr.BizError
	// ReplaceLegacyCDCClusterLock looks up the legacy cluster-level CDC custom status
	// (the one whose own mutex lists CUSTOM_STATUS_TYPE_CDC, written by the old-arch
	// SetClusterCDCStatus) and, if present, rewrites it into an equivalent lock that no
	// longer self-mutexes against CDC, so that newarch per-changefeed jobs can coexist.
	// It returns whether a legacy lock was replaced together with the old and new status
	// ids so the caller can fix up its own bookkeeping.
	ReplaceLegacyCDCClusterLock(
		ctx context.Context,
		clusterId uint64,
	) (replaced bool, oldStatusId, newStatusId uint64, err bizerr.BizError)
	// ListClusterCDCCustomStatuses lists the CDC-typed cluster custom statuses for a
	// cluster (cluster-level locks and per-changefeed jobs).
	ListClusterCDCCustomStatuses(
		ctx context.Context,
		clusterId uint64,
	) ([]*tidbmgmtservicev1.ClusterCustomStatus, bizerr.BizError)
	// SetClusterExportStatus set cluster custom status when export is running
	SetClusterExportStatus(ctx context.Context, clusterId uint64, exportId string) (uint64, bizerr.BizError)
	// SetClusterPrivateLinkConnectionStatus set cluster custom status when private link connection is created
	SetClusterPrivateLinkConnectionStatus(ctx context.Context, clusterId uint64, plcId string) (uint64, bizerr.BizError)
	DeleteClusterCustomStatus(ctx context.Context, clusterId, statusId uint64) bizerr.BizError
	GetClusterRestoreStatus(ctx context.Context, clusterId uint64, restoreId string) (uint64, bizerr.BizError)
	RestoreNewCluster(
		ctx context.Context,
		req *tidbmgmtservicev1.RestoreServerlessClusterRequest,
	) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	UpdateServerlessClusterAnnotations(
		ctx context.Context,
		clusterID uint64,
		annos map[string]string,
	) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	// GetClusterBypassCache apply undeleted, serverless and refresh filter inside. Use it when you want to read directly from the serverless-regional-svc.
	GetClusterBypassCache(
		ctx context.Context,
		clusterId uint64,
		view tidbmgmtservicev1.ClusterFilter_ClusterView,
	) (*tidbmgmtservicev1.Cluster, bizerr.BizError)
	Precheck(
		ctx context.Context,
		req *globalserverlessv1.PrecheckRequest,
	) (*globalserverlessv1.PrecheckResponse, bizerr.BizError)
	CheckImportPermission(ctx context.Context, req *globalserverlessv1.CheckImportPermissionRequest) bizerr.BizError
	UpdateAuditLogConfig(
		ctx context.Context,
		clusterId string,
		req *regionalserverlessv1.ServerlessRegionalServiceClusterInfo_AuditLogConfig,
	) bizerr.BizError
	CheckCloudStoragePermission(
		ctx context.Context,
		req *globalserverlessv1.CheckCloudStoragePermissionRequest,
	) bizerr.BizError
	DMPrecheck(
		ctx context.Context,
		req *globalserverlessv1.ServerlessDMServicePrecheckRequest,
	) (*globalserverlessv1.ServerlessDMServicePrecheckResponse, bizerr.BizError)

	CreateVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.CreateVpcEndpointRequest,
	) (*globalserverlessv1.CreateVpcEndpointResponse, bizerr.BizError)
	DescribeVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DescribeVpcEndpointRequest,
	) (*globalserverlessv1.DescribeVpcEndpointResponse, bizerr.BizError)
	DeleteVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DeleteVpcEndpointRequest,
	) bizerr.BizError
	// ListVpcEndpointZones lists the availability zones attached to the given endpoint
	ListVpcEndpointZones(
		ctx context.Context,
		req *globalserverlessv1.ListVpcEndpointZonesRequest,
	) (*globalserverlessv1.ListVpcEndpointZonesResponse, bizerr.BizError)
	// RemoveZoneFromVpcEndpoint removes a specific AZ from the endpoint
	RemoveZoneFromVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.RemoveZoneFromVpcEndpointRequest,
	) bizerr.BizError
	// ------ Private Link Connection ------
	CreateAWSVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.CreateAWSVpcEndpointRequest,
	) (*globalserverlessv1.CreateAWSVpcEndpointResponse, bizerr.BizError)
	DescribeAWSVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DescribeAWSVpcEndpointRequest,
	) (*globalserverlessv1.DescribeAWSVpcEndpointResponse, bizerr.BizError)
	DeleteAWSVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DeleteAWSVpcEndpointRequest,
	) bizerr.BizError
	CreateAliCloudVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.CreateAliCloudVpcEndpointRequest,
	) (*globalserverlessv1.CreateAliCloudVpcEndpointResponse, bizerr.BizError)
	DescribeAliCloudVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DescribeAliCloudVpcEndpointRequest,
	) (*globalserverlessv1.DescribeAliCloudVpcEndpointResponse, bizerr.BizError)
	DeleteAliCloudVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.DeleteAliCloudVpcEndpointRequest,
	) bizerr.BizError
	GetZoneIds(
		ctx context.Context,
		req *globalserverlessv1.GetZoneIdsRequest,
	) (*globalserverlessv1.GetZoneIdsResponse, bizerr.BizError)
	ListAliCloudVpcEndpointZones(
		ctx context.Context,
		req *globalserverlessv1.ListAliCloudVpcEndpointZonesRequest,
	) (*globalserverlessv1.ListAliCloudVpcEndpointZonesResponse, bizerr.BizError)
	RemoveAliCloudZoneFromVpcEndpoint(
		ctx context.Context,
		req *globalserverlessv1.RemoveAliCloudZoneFromVpcEndpointRequest,
	) bizerr.BizError
	CreateAliCloudDNSRecord(
		ctx context.Context,
		req *globalserverlessv1.CreateAliCloudDNSRecordRequest,
	) (*globalserverlessv1.CreateAliCloudDNSRecordResponse, bizerr.BizError)
	DeleteAliCloudDNSRecord(
		ctx context.Context,
		req *globalserverlessv1.DeleteAliCloudDNSRecordRequest,
	) bizerr.BizError
	CreateAWSRoute53Records(
		ctx context.Context,
		req *globalserverlessv1.CreateAWSRoute53RecordsRequest,
	) (*globalserverlessv1.CreateAWSRoute53RecordsResponse, bizerr.BizError)
	DeleteAWSRoute53Records(
		ctx context.Context,
		req *globalserverlessv1.DeleteAWSRoute53RecordsRequest,
	) (*globalserverlessv1.DeleteAWSRoute53RecordsResponse, bizerr.BizError)
	GetAWSRoute53Change(
		ctx context.Context,
		req *globalserverlessv1.GetAWSRoute53ChangeRequest,
	) (*globalserverlessv1.GetAWSRoute53ChangeResponse, bizerr.BizError)
	CreateAWSRoute53PrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.CreateAWSRoute53PrivateHostedZoneRequest,
	) (*globalserverlessv1.CreateAWSRoute53PrivateHostedZoneResponse, bizerr.BizError)
	DeleteAWSRoute53PrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.DeleteAWSRoute53PrivateHostedZoneRequest,
	) (*globalserverlessv1.DeleteAWSRoute53PrivateHostedZoneResponse, bizerr.BizError)
	CreateAliCloudDNSPrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.CreateAliCloudDNSPrivateHostedZoneRequest,
	) (*globalserverlessv1.CreateAliCloudDNSPrivateHostedZoneResponse, bizerr.BizError)
	DeleteAliCloudDNSPrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.DeleteAliCloudDNSPrivateHostedZoneRequest,
	) (*globalserverlessv1.DeleteAliCloudDNSPrivateHostedZoneResponse, bizerr.BizError)
	AttachVpcToAliCloudDNSPrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.AttachVpcToAliCloudDNSPrivateHostedZoneRequest,
	) (*globalserverlessv1.AttachVpcToAliCloudDNSPrivateHostedZoneResponse, bizerr.BizError)
	DetachVpcFromAliCloudDNSPrivateHostedZone(
		ctx context.Context,
		req *globalserverlessv1.DetachVpcFromAliCloudDNSPrivateHostedZoneRequest,
	) (*globalserverlessv1.DetachVpcFromAliCloudDNSPrivateHostedZoneResponse, bizerr.BizError)
	CreateMSKVPCConnection(
		ctx context.Context,
		req *globalserverlessv1.CreateMSKVPCConnectionRequest,
	) (*globalserverlessv1.CreateMSKVPCConnectionResponse, bizerr.BizError)
	DeleteMSKVPCConnection(
		ctx context.Context,
		req *globalserverlessv1.DeleteMSKVPCConnectionRequest,
	) (*globalserverlessv1.DeleteMSKVPCConnectionResponse, bizerr.BizError)
	GetMSKVPCConnection(
		ctx context.Context,
		req *globalserverlessv1.GetMSKVPCConnectionRequest,
	) (*globalserverlessv1.GetMSKVPCConnectionResponse, bizerr.BizError)
	// ------ Private Link Connection ------
}

var DeletedClusterStatus = []openapicommonv1beta1.ClusterState{
	openapicommonv1beta1.ClusterState_DELETED, openapicommonv1beta1.ClusterState_DELETING,
}
