package middleware

import "sync"

// RateLimiter 双维度滑动窗口登录限流
// 维度一（账户）：同邮箱 1 分钟内失败 3 次 → 锁定 1 分钟
// 维度二（IP）：同 IP 1 分钟内失败 10 次 → 锁定 1 分钟
type RateLimiter struct {
	mu              sync.RWMutex
	accountFailures map[string]*windowState
	ipFailures      map[string]*windowState
}

// NewRateLimiter 创建限流器并启动后台清理
func NewRateLimiter() *RateLimiter {
	rl := &RateLimiter{
		accountFailures: make(map[string]*windowState),
		ipFailures:      make(map[string]*windowState),
	}
	go rl.cleanupLoop()
	return rl
}

// AllowAccount 原子检查+递增帐户维度。未被封禁则递增失败计数并返回允许。
// 调用方在操作成功（如登录成功）时应调用 Clear 清除计数。
func (rl *RateLimiter) AllowAccount(email string) RateLimitResult {
	return rl.try(rl.accountFailures, email, accountWindow, accountBlockDur, accountMaxFails, true)
}

// AllowIP 原子检查+递增 IP 维度。未被封禁则递增失败计数并返回允许。
// 调用方在操作成功时应调用 Clear 清除计数。
func (rl *RateLimiter) AllowIP(ip string) RateLimitResult {
	return rl.try(rl.ipFailures, ip, ipWindow, ipBlockDur, ipMaxFails, false)
}
