package cloud_storage

import (
	"context"

	"github.com/tidbcloud/pkgv2/bizerr"
	"go.opentelemetry.io/otel"
)

var Tracer = otel.Tracer("cloud_storage")

// DefaultMaxFilesToList defines the default maximum number of files to return
const DefaultMaxFilesToList = 1000

type ListFilesOptions struct {
	// MaxFiles specifies the maximum number of files to list, default is DefaultMaxFilesToList
	MaxFiles int
}

// GetMaxFilesFromOptions returns the max files to list, using the default if not set or invalid
func GetMaxFilesFromOptions(opts *ListFilesOptions) int {
	if opts != nil && opts.MaxFiles > 0 {
		return opts.MaxFiles
	}
	return DefaultMaxFilesToList
}

type CloudStorage interface {
	// ListAll lists all object paths under the specified prefix.
	ListAll(ctx context.Context) ([]string, bizerr.BizError)
	// CheckImportPermission checks if the cloud storage has the required permissions
	// for import operations. Specifically, it ensures that the storage supports:
	// - Listing objects in the bucket/container
	// - Reading objects/files
	//
	// Required permissions vary by cloud provider:
	// - AWS S3: s3:ListBucket, s3:GetObject, s3:GetObjectVersion
	// - GCS: storage.objects.list, storage.objects.get
	// - Azure Blob Storage:
	//     - Allowed services:
	//         - Blob ("b")
	//     - Allowed resource types:
	//         - Container ("c") — access to blob containers
	//         - Object ("o") — access to individual blobs
	//     - Allowed permissions:
	//         - Read ("r")
	//         - List ("l")
	CheckImportPermission(ctx context.Context) bizerr.BizError
	// ListLimited returns up to DefaultMaxFilesToList files and indicates if there are more files available
	ListLimited(ctx context.Context, opts *ListFilesOptions) ([]string, bool, bizerr.BizError)

	// RetrieveSchemaFile retrieves a schema file path that matches the pattern:
	// {dir}/{schema}.{table}-schema.sql[.gz|.gzip|.zst|.zstd|.snappy]
	// This pattern supports optional compression extensions (.gz, .gzip, .zst, .zstd, .snappy)
	// Returns the full path to the schema file if found, or nil if not found
	// There is a assumption that the schema file is stored in the same directory as the data files
	RetrieveSchemaFile(ctx context.Context, schema string, table string, subDir string) (*string, bizerr.BizError)
}
