"""Mode admin pour l'application Pseudonymisation (D-13).

Le mode admin déverrouille des fonctionnalités cachées au bêta-testeur :
- VLM Ollama (D-11) — détection visuelle par LLM local
- Paramètres avancés sensibles (stopwords personnalisés, force_terms, etc.)
- Profils techniques (regex_overrides)

Activation possible (par ordre de priorité) :
1. Variable d'environnement : `ANON_ADMIN=1`
2. Fichier `.admin` à la racine de l'application (à côté de l'EXE / du module)

Pour désactiver : supprimer le fichier `.admin` et la variable d'env.

Aucun mot de passe pour la v1.0 — c'est juste un verrou "interdit aux
distraits" qui empêche le bêta-testeur ou un utilisateur final de tomber
sur des options qui pourraient leak des données (envoi à Ollama externe,
modifications config critique).
"""
from __future__ import annotations

import os
from pathlib import Path
from typing import Optional

_ADMIN_CACHED: Optional[bool] = None


def _project_root() -> Path:
    """Retourne le dossier racine de l'application (compat dev + EXE)."""
    try:
        return Path(__file__).parent.resolve()
    except NameError:
        return Path.cwd()


def is_admin(force_refresh: bool = False) -> bool:
    """Retourne True si le mode admin est actif.

    Résultat caché en module (les vérifications coûtent presque rien mais
    `is_admin()` peut être appelé dans des boucles serrées). `force_refresh`
    permet de re-vérifier après un changement de configuration.
    """
    global _ADMIN_CACHED
    if _ADMIN_CACHED is not None and not force_refresh:
        return _ADMIN_CACHED

    # Priorité 1 : variable d'env
    env_val = os.environ.get("ANON_ADMIN", "").strip().lower()
    if env_val in ("1", "true", "yes", "on"):
        _ADMIN_CACHED = True
        return True

    # Priorité 2 : fichier .admin
    admin_file = _project_root() / ".admin"
    if admin_file.exists():
        _ADMIN_CACHED = True
        return True

    _ADMIN_CACHED = False
    return False


def admin_required(feature_name: str = "fonctionnalité") -> None:
    """Lève RuntimeError si pas admin.

    À utiliser comme garde au début d'une méthode sensible.
    """
    if not is_admin():
        raise RuntimeError(
            f"Mode admin requis pour {feature_name}. "
            f"Activez via ANON_ADMIN=1 ou créez le fichier .admin "
            f"à la racine de l'application."
        )
