package sendguard

import (
	"errors"
	"sync"
	"time"

	"golang.org/x/time/rate"
)

var ErrSendRateLimited = errors.New("send rate limited")

// RateLimiter limits outbound send API requests per user.
type RateLimiter struct {
	mu      sync.Mutex
	limits  map[string]*rate.Limiter
	limit   rate.Limit
	burst   int
}

func NewRateLimiter(perMinute int, burst int) *RateLimiter {
	if perMinute < 1 {
		perMinute = 30
	}
	if burst < 1 {
		burst = 10
	}
	return &RateLimiter{
		limits: make(map[string]*rate.Limiter),
		limit:  rate.Every(time.Minute / time.Duration(perMinute)),
		burst:  burst,
	}
}

func (r *RateLimiter) Allow(userID string) error {
	if userID == "" {
		return ErrSendRateLimited
	}
	lim := r.limiter(userID)
	if !lim.Allow() {
		return ErrSendRateLimited
	}
	return nil
}

func (r *RateLimiter) limiter(userID string) *rate.Limiter {
	r.mu.Lock()
	defer r.mu.Unlock()
	lim, ok := r.limits[userID]
	if !ok {
		lim = rate.NewLimiter(r.limit, r.burst)
		r.limits[userID] = lim
	}
	return lim
}
