#!/usr/bin/env bash
# brain-distribuable: oui
# brain — le point d'entrée unique du brain.
#
# Usage :
#   brain init [nom] [dossier]       créer un brain, ici ou dans ce dossier (les 13 étapes) ; relancé, il complète
#   brain init --sans-service        idem, sans systemd utilisateur (conteneur, essai)
#   brain init --reecrire-claude-md  idem, et remplacer ~/.claude/CLAUDE.md (l'ancien est sauvegardé)
#   brain init --verifier            les prérequis seulement — rien n'est écrit
#   brain serve [http|mcp]           les portes réseau (HTTP + MCP), une seule déclaration
#   brain serve --declaration        ce qui serait lancé, sans rien lancer
#   brain serve --ports              les deux ports, en CLÉ=valeur — pour un script
#   brain doctor                     ce qui se dégrade en silence — le brain se contrôle
#   brain maj [version]              un fork git : le plan vers la dernière version, ou celle-ci — rien ne bouge (le paquet : pipx upgrade)
#   brain maj --appliquer            recevoir la version : fusionner, régénérer, réinstaller
#   brain maj --sans-unites          avec --appliquer : sans réinstaller les unités systemd
#   brain maj --sans-reseau          sans relire les tags de l'amont
#   brain vue [--construire]         agents/ comme une vue du noyau et de l'instance
#   brain vue --deverrouiller        rendre le noyau modifiable le temps d'une mise à jour
#   brain vue --satellites           le .gitignore du dossier tait ses satellites (programme installé à part)
#   brain aligne                     reprendre le tronc, le noyau verrouillé compris
#   brain briefing [--projet P]      le briefing du boot, calculé (helloWorld le lance)
#   brain briefing --fiches P        seulement les prochaines fiches d'un projet
#   brain migrer [dossier]           un brain git passe au paquet, une fois
#   brain migrer --a-blanc           dire ce qui serait fait — rien n'est touché
#   brain migrer --annuler           rendre le clone d'avant la migration
#
# Ce bloc EST l'aide : `brain --help` l'imprime jusqu'à sa ligne vide, la liste
# des verbes connus en dérive, et `docs-generer.py` en tire `docs/commandes.md`.
# Une ligne ajoutée ici apparaît partout ; une option que la doc fait taper sans
# qu'il la nomme fait rougir `docs-verite.py`.
#
# Les autres verbes viendront des scripts du brain, un par un (`brain <verbe>`)
# — chacun le jour où il est prêt, pas avant.
#
# Ce fichier peut être appelé par un lien (`~/.local/bin/brain`, posé par
# `brain-engine.sh install`) : il retrouve son brain par le chemin RÉEL.

set -euo pipefail

# L'aide : le bloc « Usage : » de cet en-tête, jusqu'à sa première ligne vide.
# Lu par son titre, jamais par numéros de ligne : `sed -n '4,15p'` aurait laissé
# hors de l'aide toute ligne ajoutée au bloc.
_usage() {
  awk '/^# Usage :$/ { u = 1 } u && /^#$/ { exit } u { sub(/^# ?/, ""); print }' "${BASH_SOURCE[0]}"
}

_ici="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
source "$_ici/lib/python.sh"   # python3 = celui du venv de brain-engine

# Un programme installé à part (la marque `.cortex-programme`) sert un brain situé
# ailleurs : la data se trouve (BRAIN_ROOT, le dossier courant, le brain déclaré par
# `brain init`) et chaque verbe la reçoit par `BRAIN_ROOT`. Sans la marque, rien ne
# change. `init` crée la data : il ne la cherche pas.
source "$_ici/lib/donnees.sh" 2>/dev/null || brain_donnees() { printf '%s\n' "$1"; }
_donnees=""
# `migrer` reçoit le clone à migrer : il ne cherche pas la data non plus.
# L'aide non plus : juste après `pipx install`, aucun brain n'est déclaré, et
# `brain --help` échouait à le chercher.
case "${1:-}" in
  init|migrer|""|-h|--help|help) ;;
  *)
    if [[ -e "$_ici/../.cortex-programme" ]]; then
      _donnees="$(brain_donnees "$(cd "$_ici/.." && pwd)")" || exit 1
      export BRAIN_ROOT="$_donnees"
    fi
    ;;
esac

case "${1:-}" in
  init)
    # Créer un brain : les prérequis d'abord, puis les 13 étapes.
    shift
    exec bash "$_ici/brain-init.sh" "$@"
    ;;
  serve)
    shift
    exec python3 "$_ici/../brain-engine/serve.py" "$@"
    ;;
  doctor)
    # Le doctor livré avec le gabarit (`brain-engine/doctor/`) joue les contrôles
    # de portée gabarit ; ses outils importent le CORE livré, d'où PYTHONPATH.
    # Sans lui — le brain d'origine —, celui du dépôt de Myéline, complet.
    shift
    _brain="$(cd "$_ici/.." && pwd)"
    if [ -f "$_brain/brain-engine/doctor/brain_doctor.py" ]; then
      PYTHONPATH="$_brain/brain-engine${PYTHONPATH:+:$PYTHONPATH}" \
        exec python3 "$_brain/brain-engine/doctor/brain_doctor.py" --brain "${_donnees:-$_brain}" --portee gabarit "$@"
    fi
    if [ -n "${MYELINE_ROOT:-}" ] && [ -f "$MYELINE_ROOT/tools/brain_doctor.py" ]; then
      exec python3 "$MYELINE_ROOT/tools/brain_doctor.py" --brain "$_brain" "$@"
    fi
    echo "brain doctor : aucun doctor dans ce brain (brain-engine/doctor/ absent)." >&2
    echo "  Le brain d'origine : MYELINE_ROOT=<dépôt de Myéline> brain doctor" >&2
    exit 2
    ;;
  maj)
    # Recevoir une version du gabarit : à blanc par défaut, `--appliquer` pour agir.
    shift
    exec python3 "$_ici/maj.py" "$@"
    ;;
  vue)
    # agents/ comme une vue du noyau et de l'instance : l'état, ou `--construire`.
    shift
    exec python3 "$_ici/vue.py" "$@"
    ;;
  aligne)
    # Reprendre la branche suivie : le verrou du noyau levé le temps de la fusion.
    shift
    exec python3 "$_ici/aligne.py" "$@"
    ;;
  migrer)
    # Un brain git passe au paquet, une fois — depuis le programme installé.
    shift
    exec python3 "$_ici/migrer.py" "$@"
    ;;
  briefing)
    # Le briefing du boot : les gestes mécaniques, faits par un script.
    shift
    exec python3 "$_ici/briefing.py" "$@"
    ;;
  ""|-h|--help|help)
    _usage
    ;;
  *)
    echo "brain : verbe inconnu « $1 » — connus : $(_usage | awk '$1 == "brain" && !vu[$2]++ { printf "%s%s", (n++ ? ", " : ""), $2 }')" >&2
    exit 2
    ;;
esac
