#!/usr/bin/env bash
# brain-distribuable: oui
# pre-commit — installé par scripts/install-brain-hooks.sh, source versionnée
#
#   1. la posture de l'instance (replica : pas de commit kernel), si le garde existe
#   2. la zone d'écriture du type de session, si le garde existe
#   3. docs-generer --check quand une source de la doc change
#   4. pas de marqueur de conflit git dans ce que le commit AJOUTE
#   5. le garde du distribué, s'il existe : ce qui part au gabarit, jugé au commit
#
# Le Python, la base et la posture sont ceux du dépôt PRINCIPAL ; les fichiers,
# ceux du commit. Voir _racines.sh.

source "$(dirname "${BASH_SOURCE[0]}")/_racines.sh"
BRAIN_ROOT="$BRAIN_MAIN" source "$BRAIN_MAIN/scripts/lib/python.sh"

if [[ -f "$BRAIN_MAIN/scripts/hooks/pre-commit-posture" ]]; then
    bash "$BRAIN_MAIN/scripts/hooks/pre-commit-posture" || exit 1
fi
if [[ -f "$BRAIN_MAIN/scripts/hooks/pre-commit-zone" ]]; then
    python3 "$BRAIN_MAIN/scripts/hooks/pre-commit-zone" || exit 1
fi

# La doc générée suit ses sources : un commit qui change une source de la doc
# (agents, manifests, schéma, routes, outils MCP, pages sources) sans régénérer
# `docs/` et `skills/brain/` est refusé — avec la commande. On juge l'INDEX, pas
# la copie de travail : le disque aurait laissé passer une doc régénérée mais
# pas indexée, et fait refuser un commit juste à cause du travail non indexé
# d'une autre session (relecture du 28/09).
triggers=$(git diff --cached --name-only | grep -E '^(agents/|noyau/agents/|instance/agents/|contexts/|brain-compose\.yml|docs/|skills/brain/|brain-engine/(schema-dolt|views-dolt)\.sql|brain-engine/(server|mcp_server)\.py)' || true)
if [[ -n "$triggers" && -f "$BRAIN_WT/scripts/docs-generer.py" ]]; then
    index=$(mktemp -d)
    trap 'chmod -R u+w "$index" 2>/dev/null; rm -rf "$index"' EXIT
    git checkout-index -a --prefix="$index/"
    # Un brain migré lit ses agents par une vue que git ignore : l'index n'en a pas,
    # et la doc s'y jugeait sur « aucun agent » — le commit de la migration lui-même
    # était refusé (répétition générale du 3/10). On construit la vue dans la copie
    # de l'index, catalogue compris, comme sur le disque.
    if [[ -d "$index/noyau/agents" && -f "$index/scripts/vue.py" ]]; then
        BRAIN_ROOT="$index" python3 "$index/scripts/vue.py" --construire >/dev/null 2>&1 || true
        if [[ ! -f "$index/agents/CATALOG.yml" ]]; then
            echo "docs-generer : impossible de juger la doc de ce commit — le catalogue de la vue"
            echo "  ne se calcule pas (ni brain-engine/doctor/agent_registry.py, ni MYELINE_ROOT)."
            exit 1
        fi
    fi
    code=0
    sortie=$(python3 "$BRAIN_WT/scripts/docs-generer.py" --brain "$index" --check 2>&1) || code=$?
    if [[ $code -eq 1 ]]; then
        echo "docs-generer : la doc de ce commit n'est plus à jour de ses sources."
        echo "$sortie" | grep "⚠" | sed 's/^/  /'
        echo "  python3 scripts/docs-generer.py --ecrire   puis ajouter docs/ et skills/brain/"
        exit 1
    elif [[ $code -ne 0 ]]; then
        # 2 : illisible (PyYAML absent, frontmatter cassé) — ce n'est pas « en
        # retard », et le dire comme tel enverrait chercher au mauvais endroit.
        echo "docs-generer : impossible de juger la doc de ce commit (code $code)."
        echo "$sortie" | tail -3 | sed 's/^/  /'
        exit 1
    fi
fi

# Un marqueur de conflit laissé dans un fichier se commite sans bruit : le
# 27/09, `||||||| 5c73ba0` — la ligne de BASE d'une fusion diff3 — est entré
# dans une fiche du backlog et y est resté deux jours. `git diff
# --check` les connaît tous (<<<<<<<, |||||||, =======, >>>>>>>) ; on ne garde
# que ce motif-là, pas les espaces de fin de ligne qu'il signale aussi. Seules
# les lignes AJOUTÉES sont jugées : un fichier qui en porte déjà ne bloque pas
# un commit qui n'y touche pas.
marqueurs=$(git diff --cached --check 2>/dev/null | grep "leftover conflict marker" || true)
if [[ -n "$marqueurs" ]]; then
    echo "pre-commit : marqueur(s) de conflit git dans ce commit — résoudre avant de commiter."
    echo "$marqueurs" | sed 's/^/  /'
    exit 1
fi

# Le garde du distribué — un outil de l'instance qui publie le gabarit, absent d'un
# fork : ce que le commit fait partir au gabarit ne porte ni renvoi au backlog privé
# pris dans la phrase, ni le nom de l'instance. La synchro le juge au moment de
# publier ; ici, au moment d'écrire.
if [[ -f "$BRAIN_WT/scripts/garde-distribue.py" ]]; then
    (cd "$BRAIN_WT" && python3 scripts/garde-distribue.py) || exit 1
fi
