"""Ancrages hors-module du PIE manifest (anti-dérive · anti-invention #6).

Le manifest PIE ne se valide pas seulement contre lui-même : trois faits sont
RE-DÉRIVÉS de sources de vérité EXTERNES au module, jamais recopiés à la main —

  1. Les codes projets (`brands[].code`) sont confrontés à `CLAUDE.md §Projets`
     (la constitution · [[claude-md-constant-anchor-gate]]). Une marque PIE dont
     le code ne figure pas dans la constitution est une invention refusée.
  2. `annexe` (12) et `version_workflow` (V10.1) doivent apparaître VERBATIM dans
     la directive PIE. Renuméroter l'annexe dans la directive sans régénérer ici
     casse la validation ([[roadmap-anchor-gate]] appliqué à la directive).
  3. Chaque `downstream_registry[].module` non nul doit être un répertoire de
     livrable RÉEL sous `05_deliverables_mvp/` (comme fiscal/ecf vérifie ses
     contrats voisins). Un module fantôme (renommé/supprimé) casse la validation.

Zéro dépendance pip · zéro réseau · aucune écriture VPS (#8) : lecture seule de
fichiers déjà versionnés dans le dépôt.
"""

from __future__ import annotations

import os
import re

_HERE = os.path.dirname(os.path.abspath(__file__))
_MODULE_DIR = os.path.normpath(os.path.join(_HERE, ".."))          # pie/manifest/
DELIVERABLES_ROOT = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))  # 05_deliverables_mvp/
_REPO_ROOT = os.path.normpath(os.path.join(DELIVERABLES_ROOT, ".."))
_CLAUDE_MD = os.path.join(_REPO_ROOT, "CLAUDE.md")


def claude_md_project_codes() -> set[str]:
    """Codes Pxx de la ligne `## Projets` de CLAUDE.md (source de vérité #Projets)."""
    with open(_CLAUDE_MD, encoding="utf-8") as fh:
        text = fh.read()
    # Section entre « ## Projets » et le prochain titre « ## ».
    m = re.search(r"^##\s+Projets\s*\n(.*?)(?:\n##\s|\Z)", text, re.S | re.M)
    section = m.group(1) if m else ""
    return set(re.findall(r"\bP0[1-9]\b", section))


def directive_declares(directive_relpath: str, *needles: str) -> dict[str, bool]:
    """Vrai/faux, pour chaque `needle`, s'il apparaît verbatim dans la directive PIE."""
    path = os.path.join(_REPO_ROOT, directive_relpath)
    try:
        with open(path, encoding="utf-8") as fh:
            text = fh.read()
    except OSError:
        return {n: False for n in needles}
    return {n: (n in text) for n in needles}


def module_exists(rel_module: str) -> bool:
    """Le module de livrable `rel_module` (ex. 'faisabilite/bancable') existe-t-il ?"""
    return os.path.isdir(os.path.join(DELIVERABLES_ROOT, rel_module))


def module_out_dir() -> str:
    """Répertoire de sortie du module (le SEUL endroit où ce worker écrit · #8)."""
    return os.path.join(_MODULE_DIR, "out")
