package entity

import (
	"errors"
	"fmt"
	"net/url"
	"path"
	"strings"

	apiv1 "github.com/tidbcloud/cluster-service-ng/api/cluster-service-ng/v1beta"
)

var (
	// ErrPlanReplayerStorageNotReady indicates that no hydrated physical bucket is available.
	ErrPlanReplayerStorageNotReady = errors.New("plan replayer storage is not ready")
	// ErrPlanReplayerStorageProviderUnsupported indicates that the cloud provider has no adapter.
	ErrPlanReplayerStorageProviderUnsupported = errors.New("plan replayer storage provider is unsupported")
)

// GetPlanReplayerStorageRoot returns the canonical provider URI ending at global-sort.
// Plan Replayer files live under internal storage only; do not fall back to the data bucket.
func (sharedPool *SharedPool) GetPlanReplayerStorageRoot() (string, error) {
	storage := sharedPool.GetInternalStorage()
	if storage == nil || storage.GetBucket() == "" {
		return "", ErrPlanReplayerStorageNotReady
	}

	var scheme string
	switch sharedPool.GetProvider().GetType() {
	case apiv1.ProviderType_AWS:
		scheme = "s3"
	case apiv1.ProviderType_ALICLOUD:
		// TiDB uses an S3-compatible URI for OSS. This API instead uses the
		// canonical OSS identity; endpoint selection belongs to cluster-agent.
		scheme = "oss"
	default:
		return "", fmt.Errorf(
			"%w: provider type %s",
			ErrPlanReplayerStorageProviderUnsupported,
			sharedPool.GetProvider().GetType(),
		)
	}

	keyPrefix := strings.TrimLeft(path.Join(storage.GetPrefix(), "global-sort"), "/")
	return (&url.URL{
		Scheme: scheme,
		Host:   storage.GetBucket(),
		Path:   "/" + keyPrefix,
	}).String(), nil
}
