package seafile

import (
	"context"
	"fmt"
	"net/url"
	"sync"
	"time"

	"github.com/rclone/rclone/fs"
	"github.com/rclone/rclone/lib/pacer"
)

const (
	minSleep      = 100 * time.Millisecond
	maxSleep      = 10 * time.Second
	decayConstant = 2 // bigger for slower decay, exponential
)

// Use only one pacer per server URL
var (
	pacers     map[string]*fs.Pacer
	pacerMutex sync.Mutex
)

func init() {
	pacers = make(map[string]*fs.Pacer, 0)
}

// getPacer returns the unique pacer for that remote URL
func getPacer(ctx context.Context, remote string) *fs.Pacer {
	pacerMutex.Lock()
	defer pacerMutex.Unlock()

	remote = parseRemote(remote)
	if existing, found := pacers[remote]; found {
		return existing
	}

	pacers[remote] = fs.NewPacer(
		ctx,
		pacer.NewDefault(
			pacer.MinSleep(minSleep),
			pacer.MaxSleep(maxSleep),
			pacer.DecayConstant(decayConstant),
		),
	)
	return pacers[remote]
}

// parseRemote formats a remote url into "hostname:port"
func parseRemote(remote string) string {
	remoteURL, err := url.Parse(remote)
	if err != nil {
		// Return a default value in the very unlikely event we're not going to parse remote
		fs.Infof(nil, "Cannot parse remote %s", remote)
		return "default"
	}
	host := remoteURL.Hostname()
	port := remoteURL.Port()
	if port == "" {
		if remoteURL.Scheme == "https" {
			port = "443"
		} else {
			port = "80"
		}
	}
	return fmt.Sprintf("%s:%s", host, port)
}