"""Thread-safe helpers for rate-limiting repetitive logs."""

from __future__ import annotations

import threading
import time

_LOCK = threading.Lock()
_LAST_EMITTED: dict[str, float] = {}
_COUNTERS: dict[str, int] = {}
_SUPPRESSED: dict[str, int] = {}


def should_emit_after(key: str, seconds: float) -> bool:
    """Return True when the cooldown has elapsed for the given key."""

    if seconds <= 0:
        return True

    now = time.monotonic()
    with _LOCK:
        last_emitted = _LAST_EMITTED.get(key)
        if last_emitted is None or now - last_emitted >= seconds:
            _LAST_EMITTED[key] = now
            return True
        _SUPPRESSED[key] = _SUPPRESSED.get(key, 0) + 1
        return False


def should_emit_every_n(key: str, n: int) -> bool:
    """Return True every N calls for a deterministic key."""

    if n <= 1:
        return True

    with _LOCK:
        count = _COUNTERS.get(key, 0) + 1
        _COUNTERS[key] = count
        return count % n == 0


def consume_suppressed_count(key: str) -> int:
    """Return and reset the number of suppressed events for a key."""

    with _LOCK:
        return _SUPPRESSED.pop(key, 0)


def reset_key(key: str) -> None:
    """Clear all tracking state for a key."""

    with _LOCK:
        _LAST_EMITTED.pop(key, None)
        _COUNTERS.pop(key, None)
        _SUPPRESSED.pop(key, None)
