from __future__ import annotations

from collections import deque
from threading import Lock
from time import monotonic

from fastapi import HTTPException

_BUCKETS: dict[str, deque[float]] = {}
_LOCK = Lock()


async def enforce_rate_limit(
    *,
    scope: str,
    identifier: str,
    limit: int,
    window_seconds: int,
) -> None:
    _enforce_rate_limit_in_memory(
        key=f"auth:rate_limit:{scope}:{identifier.lower()}",
        limit=limit,
        window_seconds=window_seconds,
    )


def _enforce_rate_limit_in_memory(
    *,
    key: str,
    limit: int,
    window_seconds: int,
) -> None:
    now = monotonic()
    with _LOCK:
        bucket = _BUCKETS.setdefault(key, deque())
        cutoff = now - float(window_seconds)
        while bucket and bucket[0] <= cutoff:
            bucket.popleft()
        if len(bucket) >= limit:
            raise HTTPException(status_code=429, detail="Too many requests")
        bucket.append(now)


def reset_rate_limit_state() -> None:
    with _LOCK:
        _BUCKETS.clear()
