package middleware

import (
	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"

	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/ratelimit"
	"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/security/clientip"
)

// RateLimitMiddlewares holds all four rate limiting middlewares
type RateLimitMiddlewares struct {
	Registration *RateLimitMiddleware // CWE-307: Account creation protection (IP-based)
	Generic      *RateLimitMiddleware // CWE-770: CRUD endpoint protection (User-based)
	PluginAPI    *RateLimitMiddleware // CWE-770: Plugin API protection (Site-based)
	// Note: Login rate limiter is specialized and handled directly in login handler
}

// ProvideRateLimitMiddlewares provides all rate limiting middlewares for dependency injection
// CWE-348: Injects clientip.Extractor for secure IP extraction with trusted proxy validation
// CWE-770: Provides four-tier rate limiting architecture
func ProvideRateLimitMiddlewares(redisClient *redis.Client, cfg *config.Config, ipExtractor *clientip.Extractor, logger *zap.Logger) *RateLimitMiddlewares {
	// 1. Registration rate limiter (CWE-307: strict, IP-based)
	// Default: 5 requests per hour per IP
	registrationRateLimiter := ratelimit.NewRateLimiter(redisClient, ratelimit.Config{
		MaxRequests: cfg.RateLimit.RegistrationMaxRequests,
		Window:      cfg.RateLimit.RegistrationWindow,
		KeyPrefix:   "ratelimit:registration",
	}, logger)

	// 3. Generic CRUD endpoints rate limiter (CWE-770: lenient, user-based)
	// Default: 100 requests per hour per user
	genericRateLimiter := ratelimit.NewRateLimiter(redisClient, ratelimit.Config{
		MaxRequests: cfg.RateLimit.GenericMaxRequests,
		Window:      cfg.RateLimit.GenericWindow,
		KeyPrefix:   "ratelimit:generic",
	}, logger)

	// 4. Plugin API rate limiter (CWE-770: very lenient, site-based)
	// Default: 1000 requests per hour per site
	pluginAPIRateLimiter := ratelimit.NewRateLimiter(redisClient, ratelimit.Config{
		MaxRequests: cfg.RateLimit.PluginAPIMaxRequests,
		Window:      cfg.RateLimit.PluginAPIWindow,
		KeyPrefix:   "ratelimit:plugin",
	}, logger)

	return &RateLimitMiddlewares{
		Registration: NewRateLimitMiddleware(registrationRateLimiter, ipExtractor, logger),
		Generic:      NewRateLimitMiddleware(genericRateLimiter, ipExtractor, logger),
		PluginAPI:    NewRateLimitMiddleware(pluginAPIRateLimiter, ipExtractor, logger),
	}
}
