package bucket

import (
	"context"

	"github.com/tidbcloud/dataflow-service/app/models/domain"
	"github.com/tidbcloud/pkgv2/bizerr"
)

// BucketModelV2 is the interface for bucket model, BR business related orchestration logic
type BucketModelV2 interface {
	CreateBucket(ctx context.Context, req *domain.CreateBucketReqV2) (*domain.CreateBucketRespV2, bizerr.BizError)
	DeleteBucket(ctx context.Context, req *domain.DeleteBucketReqV2) (*domain.DeleteBucketRespV2, bizerr.BizError)
	GetBucket(ctx context.Context, req *domain.GetBucketReq) (*domain.GetBucketResp, bizerr.BizError)
	GrantAccessToBucket(ctx context.Context, req *domain.GrantAccessToBucketReq,
	) (*domain.GrantAccessToBucketResp, bizerr.BizError)
	RevokeAccessToBucket(ctx context.Context, req *domain.RevokeAccessToBucketReq,
	) (*domain.RevokeAccessToBucketResp, bizerr.BizError)
}

// BucketReplicationModel is the interface for bucket replication related orchestration logic
type BucketReplicationModel interface {
	CreateBucketReplication(
		ctx context.Context, req *domain.CreateBucketReplicationReq,
	) (*domain.CreateBucketReplicationResp, bizerr.BizError)
	DeleteBucketReplication(
		ctx context.Context, req *domain.DeleteBucketReplicationReq,
	) (*domain.DeleteBucketReplicationResp, bizerr.BizError)
}

// AWSBucketManagerModel is the interface for AWS bucket manager
//
//nolint:interfacebloat
type AWSBucketManagerModel interface {
	// CheckBucketIfExists checks if the bucket exists returns nil if exists
	CheckBucketIfExists(ctx context.Context, req *domain.AWSBucketReq) bizerr.BizError
	CreateBucket(ctx context.Context, req *domain.CreateAWSBucketReq) bizerr.BizError
	PutBucketTags(ctx context.Context, req *domain.PutAWSBucketTagsReq) bizerr.BizError
	EnableBucketEncryption(ctx context.Context, req *domain.EnableAWSBucketEncryptionReq) bizerr.BizError
	EnableBucketVersioning(ctx context.Context, req *domain.EnableAWSBucketVersioningReq) bizerr.BizError
	AddAllowRoleArnToBucketPolicy(
		ctx context.Context, req *domain.AddAWSAllowRoleArnToBucketPolicyReq,
	) (*domain.AddAWSAllowRoleArnToBucketPolicyResp, bizerr.BizError)
	DeleteRoleArnFromBucketPolicy(
		ctx context.Context, req *domain.DeleteAWSRoleArnFromBucketPolicyReq,
	) (*domain.DeleteAWSRoleArnFromBucketPolicyResp, bizerr.BizError)
	DeleteBucketIgnoreNotFound(ctx context.Context, req *domain.AWSBucketReq) bizerr.BizError
	AddBucketLifecycleConfiguration(
		ctx context.Context, req *domain.AddBucketLifecycleConfigurationReq,
	) bizerr.BizError
	AddBucketReplication(
		ctx context.Context, req *domain.AddAWSBucketReplicationReq,
	) (*domain.AddAWSBucketReplicationResp, bizerr.BizError)
	DeleteBucketReplication(
		ctx context.Context, req *domain.DeleteAWSBucketReplicationReq,
	) (*domain.DeleteAWSBucketReplicationResp, bizerr.BizError)
	ModifyReplicationRTC(
		ctx context.Context, req *domain.ModifyReplicationRTCReq,
	) bizerr.BizError
}

// AzureBucketManagerModel is the interface to manage Azure Storage Account
type AzureBucketManagerModel interface {
	// CreateBucket creates an Azure Storage Account
	CreateBucket(ctx context.Context, req *domain.CreateAzureBucketReq) bizerr.BizError
	// CreateContainer creates a container in an Azure Storage Account
	// Though container looks like bucket prefix in other cloud provider, it needs
	// to be exist before BR can use it
	CreateContainer(ctx context.Context, req *domain.CreateAzureBucketContainerReq) bizerr.BizError
	EnableBucketEncryption(ctx context.Context, req *domain.EnableAzureBucketEncryptionReq) bizerr.BizError
	// GenerateSASToken generates an SAS token for BR to access Azure Storage Account
	// BR kernel does not support managed identity
	GenerateSASToken(ctx context.Context, req *domain.GenerateAzureSASTokenReq) (string, bizerr.BizError)
	CheckBucketIfExists(ctx context.Context, req *domain.CheckAzureBucketReq) bizerr.BizError
	DeleteBucketIgnoreNotFound(ctx context.Context, req *domain.DeleteAzureBucketReq) bizerr.BizError
}

type GCPBucketManagerModel interface {
	CheckBucketIfExists(ctx context.Context, req *domain.CheckGCPBucketReq) bizerr.BizError
	CreateBucket(ctx context.Context, req *domain.CreateGCPBucketReq) bizerr.BizError
	DeleteBucketIgnoreNotFound(ctx context.Context, req *domain.DeleteGCPBucketReq) bizerr.BizError
	// AddAllowPolicyToBucket add binding rules base on the existed bucket policy, not replace
	AddAllowPolicyToBucket(
		ctx context.Context, req *domain.GCPAddAllowPolicyToBucketReq,
	) (*domain.GCPAddAllowPolicyToBucketResp, bizerr.BizError)
	// DeleteAllowPolicyFromBucket delete binding rules base on the existed bucket policy
	DeleteAllowPolicyFromBucket(
		ctx context.Context, req *domain.GCPDeleteAllowPolicyFromBucketReq,
	) (*domain.GCPDeleteAllowPolicyFromBucketResp, bizerr.BizError)
	PutBucketTags(
		ctx context.Context, req *domain.GCPPutBucketTags,
	) bizerr.BizError
}

// BucketWorkerV2 is the interface for bucket worker
type BucketWorkerV2 interface {
	RecycleBucket(ctx context.Context) bizerr.BizError
}

type BucketReplicationWorker interface {
	RecycleBucketReplication(ctx context.Context) bizerr.BizError
}
