import time, logging, asyncio
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import Response, JSONResponse
from app.core.redis import redis_pool

logger = logging.getLogger(__name__)

RATE_LIMIT_PATHS = {
    "/api/v1/auth/jwt/login": (5, 60),  # 5 requests per 60 seconds per IP
}

class RateLimitMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        path = request.url.path
        limit_cfg = RATE_LIMIT_PATHS.get(path)
        if not limit_cfg:
            return await call_next(request)

        max_requests, window = limit_cfg
        client_ip = request.client.host if request.client else "unknown"
        key = f"rate:{path}:{client_ip}"
        try:
            current = await redis_pool.get(key)
            current_int = int(current) if current else 0
            if current_int >= max_requests:
                logger.warning(f"Rate limit exceeded for {client_ip} on {path}")
                return JSONResponse(status_code=429, content={"detail": "Too Many Requests"})
            # increment
            pipe = redis_pool.pipeline()
            pipe.incr(key, 1)
            pipe.expire(key, window)
            await pipe.execute()
        except Exception as e:
            logger.error(f"Rate limiting error: {e}")
            # Fail-open if redis unavailable
            pass

        return await call_next(request) 