package mediaprovider

import (
	"context"
	"time"

	"github.com/minio/minio-go/v7"
	"github.com/minio/minio-go/v7/pkg/credentials"
	"git.mstar.dev/mstar/linstrom/config"
)

type Provider struct {
	client *minio.Client
}

// Create a new storage provider using the values from the global config
// It also sets up the bucket in the s3 provider if it doesn't exist yet
func NewProviderFromConfig() (*Provider, error) {
	client, err := minio.New(config.GlobalConfig.S3.Endpoint, &minio.Options{
		Creds: credentials.NewStaticV4(
			config.GlobalConfig.S3.KeyId,
			config.GlobalConfig.S3.Secret,
			"",
		),
		Region: config.GlobalConfig.S3.Region,
		Secure: config.GlobalConfig.S3.UseSSL,
	})
	if err != nil {
		return nil, err
	}

	if err = setupBucket(client, config.GlobalConfig.S3.BucketName); err != nil {
		return nil, err
	}
	return &Provider{
		client: client,
	}, nil
}

func setupBucket(client *minio.Client, bucketName string) error {
	ctx := context.Background()
	// Give it half a minute tops to check if a bucket with the given name already exists
	existsContext, cancel := context.WithTimeout(ctx, time.Second*30)
	defer cancel()
	ok, err := client.BucketExists(existsContext, bucketName)
	if err != nil {
		return err
	}
	if ok {
		return nil
	}
	// Same timeout for creating the new bucket if it doesn't exist
	createContext, createCancel := context.WithTimeout(ctx, time.Second*30)
	defer createCancel()
	err = client.MakeBucket(createContext, bucketName, minio.MakeBucketOptions{
		Region: config.GlobalConfig.S3.Region,
	})
	return err
}
