package aws

import (
	"fmt"

	"github.com/aws/aws-sdk-go-v2/service/s3"
	"github.com/pingcap/log"
	"github.com/tidbcloud/serverless-service/internal/config"
	"go.uber.org/zap"
)

type PresignerProvider struct {
	presigners map[string]*s3.PresignClient
}

func NewPresignerProvider(s3Clients *S3ClientProvider) *PresignerProvider {
	presigners := make(map[string]*s3.PresignClient)
	for _, regionConfig := range config.Global().WorkerConfig.RegionalConfig {
		if !config.HasS3CompatibleStashing(regionConfig.Provider) {
			continue
		}
		key := getS3ClientKey(regionConfig.Provider, regionConfig.Region)
		s3Client, err := s3Clients.GetS3Client(regionConfig.Provider, regionConfig.Region)
		if err != nil {
			// Missing S3 client must not crash process start. GCP is
			// normally skipped by HasS3CompatibleStashing; this also
			// covers AWS/AliCloud regions listed before a client exists.
			log.Warn("skip creating s3 presigner",
				zap.String("provider", regionConfig.Provider),
				zap.String("region", regionConfig.Region),
				zap.Error(err))
			continue
		}
		presigners[key] = s3.NewPresignClient(s3Client)
	}
	return &PresignerProvider{
		presigners: presigners,
	}
}

func (p *PresignerProvider) GetPresignerClient(provider, region string) (*s3.PresignClient, error) {
	key := getS3ClientKey(provider, region)
	if p.presigners[key] == nil {
		return nil, fmt.Errorf("presigner for provider and %s region %s not found", provider, region)
	}
	return p.presigners[key], nil
}
