"""A minimal in-memory TTL cache used to conserve the daily API quota.

AccuWeather's free tier is limited to 50 requests per day, so avoiding
duplicate calls matters. This hand-rolled cache keeps the package free of
extra dependencies.
"""

import time
from collections.abc import Hashable
from typing import Any


class TTLCache:
    """A tiny dictionary-backed cache with per-entry time-to-live.

    Args:
        ttl: Lifetime of each entry in seconds. A ``ttl`` of ``0`` (or a
            negative number) disables caching entirely.

    Example:
        >>> cache = TTLCache(ttl=600)
        >>> cache.set(("forecast", "5day"), {"some": "payload"})
        >>> cache.get(("forecast", "5day"))
        {'some': 'payload'}
    """

    def __init__(self, ttl: float = 0):
        self.ttl = ttl
        self._store: dict[Hashable, tuple[float, Any]] = {}

    @property
    def enabled(self) -> bool:
        """Whether caching is active (``ttl`` > 0)."""
        return self.ttl > 0

    def get(self, key: Hashable) -> Any | None:
        """Return the cached value for ``key``, or ``None`` if absent/expired."""
        if not self.enabled:
            return None
        entry = self._store.get(key)
        if entry is None:
            return None
        expires_at, value = entry
        if time.monotonic() >= expires_at:
            del self._store[key]
            return None
        return value

    def set(self, key: Hashable, value: Any) -> None:
        """Store ``value`` under ``key`` for ``ttl`` seconds."""
        if not self.enabled:
            return
        self._store[key] = (time.monotonic() + self.ttl, value)

    def clear(self) -> None:
        """Drop all cached entries."""
        self._store.clear()
