"""Simple file-backed JSON cache with TTL."""
from __future__ import annotations

import hashlib
import json
import time
from pathlib import Path
from typing import Any

_DEFAULT_CACHE_DIR = Path.home() / ".cache" / "pyguard"


class FileCache:
    def __init__(self, cache_dir: Path | None = None) -> None:
        self._dir = (cache_dir or _DEFAULT_CACHE_DIR).resolve()
        self._dir.mkdir(parents=True, exist_ok=True)

    def _path(self, key: str) -> Path:
        digest = hashlib.sha256(key.encode()).hexdigest()
        return self._dir / f"{digest}.json"

    def get(self, key: str) -> Any | None:
        path = self._path(key)
        if not path.exists():
            return None
        try:
            data: dict[str, Any] = json.loads(path.read_text(encoding="utf-8"))
        except (json.JSONDecodeError, OSError):
            return None
        if time.time() > data.get("expires_at", 0.0):
            path.unlink(missing_ok=True)
            return None
        return data.get("value")

    def set(self, key: str, value: Any, ttl_seconds: int = 3600) -> None:
        path = self._path(key)
        payload = {"expires_at": time.time() + ttl_seconds, "value": value}
        try:
            path.write_text(json.dumps(payload), encoding="utf-8")
        except OSError:
            pass  # non-fatal; caching is best-effort

    def delete(self, key: str) -> None:
        self._path(key).unlink(missing_ok=True)

    def clear(self) -> None:
        for p in self._dir.glob("*.json"):
            p.unlink(missing_ok=True)


# Module-level default cache instance
_default: FileCache | None = None


def get_default_cache() -> FileCache:
    global _default
    if _default is None:
        _default = FileCache()
    return _default
