"""
JWT revocation store.

In-memory blacklist of revoked token JTI claims with auto-expiry tied to
each token's own `exp` claim. Single-process by design — for multi-worker
deployments swap the backing dict for Redis (the REDIS_URL env var is
already plumbed into the rest of the stack).
"""
from __future__ import annotations

import threading
import time
from typing import Optional


# jti -> expiry epoch (seconds since epoch, matches JWT `exp`)
_revoked: dict[str, float] = {}
_lock = threading.Lock()


def revoke(jti: str, exp_epoch: Optional[float]) -> None:
    """Mark a token JTI as revoked until its natural expiry."""
    if not jti:
        return
    expiry = exp_epoch if exp_epoch is not None else time.time() + 7 * 24 * 3600
    with _lock:
        _revoked[jti] = expiry


def is_revoked(jti: str) -> bool:
    """Return True if the JTI was revoked and the revocation has not expired."""
    if not jti:
        return False
    now = time.time()
    with _lock:
        # Opportunistic purge of expired entries.
        expired = [k for k, exp in _revoked.items() if exp <= now]
        for k in expired:
            _revoked.pop(k, None)
        return jti in _revoked
