"""Stockage local de la licence signée, hors dépôt.

La licence est stockée dans l'espace utilisateur, jamais dans le dépôt Git :

- Windows : ``%LOCALAPPDATA%/Aivanov/Anonymisation/license.json``
- Linux/dev : ``~/.local/share/aivanov/anonymisation/license.json``

Règle de sécurité : ce module ne journalise jamais le contenu de la licence
(le token signé est sensible). Aucune impression, aucun log du payload.
"""

from __future__ import annotations

import json
import os
import sys
from pathlib import Path
from typing import Any, Optional

_APP_VENDOR = "Aivanov"
_APP_NAME = "Anonymisation"
_LICENSE_FILENAME = "license.json"


def default_license_path() -> Path:
    """Retourne le chemin du fichier licence dans l'espace utilisateur.

    Le répertoire n'est pas créé ici ; il l'est à la première écriture.
    """
    if sys.platform.startswith("win"):
        base = os.environ.get("LOCALAPPDATA")
        root = Path(base) if base else Path.home() / "AppData" / "Local"
        return root / _APP_VENDOR / _APP_NAME / _LICENSE_FILENAME

    # Linux / macOS / dev : respecte XDG_DATA_HOME si défini.
    base = os.environ.get("XDG_DATA_HOME")
    root = Path(base) if base else Path.home() / ".local" / "share"
    return root / _APP_VENDOR.lower() / _APP_NAME.lower() / _LICENSE_FILENAME


class LicenseStore:
    """Lit / écrit / supprime le fichier licence local (JSON).

    Le chemin est injectable pour les tests (vrai fichier dans un tmp_path) ;
    par défaut il pointe vers l'emplacement utilisateur de la plateforme.
    """

    def __init__(self, path: Optional[Path] = None) -> None:
        self._path = Path(path) if path is not None else default_license_path()

    @property
    def path(self) -> Path:
        return self._path

    def exists(self) -> bool:
        return self._path.is_file()

    def load(self) -> Optional[dict[str, Any]]:
        """Retourne le payload licence, ou ``None`` si absent / illisible."""
        if not self._path.is_file():
            return None
        try:
            with self._path.open("r", encoding="utf-8") as handle:
                data = json.load(handle)
        except (json.JSONDecodeError, OSError, ValueError):
            return None
        return data if isinstance(data, dict) else None

    def save(self, data: dict[str, Any]) -> Path:
        """Écrit le payload licence de façon atomique. Crée le répertoire parent."""
        self._path.parent.mkdir(parents=True, exist_ok=True)
        tmp = self._path.with_name(self._path.name + ".tmp")
        with tmp.open("w", encoding="utf-8") as handle:
            json.dump(data, handle, ensure_ascii=False, indent=2)
        os.replace(tmp, self._path)
        return self._path

    def delete(self) -> bool:
        """Supprime le fichier licence. Retourne True s'il existait."""
        try:
            self._path.unlink()
            return True
        except FileNotFoundError:
            return False
