#!/usr/bin/env bash
# Selbstreparatur-Modus (Autonomie 0g, Kür): Macht ein Hermes-Update den Gehirn-Check rot,
# WEIL sich Config-Schlüssel geändert haben (v0.18-Klasse: „Unknown key … → stiller Default →
# alle Tools hingen"), versucht die Box den Config-Bruch SELBST zu ziehen — bevor zurückgerollt
# wird, um die neue Version zu behalten. NUR Config, NIE Code, NIE Security-Schlüssel.
#
# Sicher durch Kapselung — jeder Schritt ist reversibel und hart gegatet:
#   Backup → nur EINDEUTIGE (genau 1× vorkommende), nicht-sicherheitsrelevante Keys auskommentieren
#   → YAML muss gültig bleiben → Gehirn-Check (hermes-postcheck.sh) muss GRÜN werden → sonst zurück.
# Schlimmster Fall bei Fehlgriff = exakt der heutige: Rollback. Der Aufrufer (autoupdate.sh) ruft
# dies VOR seinem Rollback; bei Rückgabe 2 rollt er wie gehabt zurück + pinnt.
#
# Rückgabe: 0 = repariert (Gehirn-Check danach grün) · 2 = nichts sicher reparierbar.
# Gibt bei Misserfolg eine Zeile „SELFREPAIR_SUGGESTION=<LLM-Diagnose>" auf stdout aus.
set -uo pipefail

SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
HERMES="${HERMES_HOME:-$HOME/.hermes}"
CFG="$HERMES/config.yaml"
WARN_FILE="${HERMES_CONFIG_WARNINGS:-/tmp/hermes-config-warnings.txt}"
LLAMA="${LLAMA_SWAP_URL:-http://127.0.0.1:8080}"
VENV_PY="$HERMES/hermes-agent/venv/bin/python"
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"

say(){ echo "[self-repair] $*"; }

# ── 1) Evidenz: Postcheck-Warnungen + frisches Gateway-Journal ────────────────
EVID="$(cat "$WARN_FILE" 2>/dev/null)"
JOURN="$(journalctl --user -u hermes-gateway --since '-6 minutes' --no-pager -o cat 2>/dev/null \
        | grep -iE "Unknown [a-z._]+ '|deprecated .*(setting|option|config)|defaulting to|invalid config" \
        | grep -v check_fn | head -10)"
[ -z "$EVID" ] && EVID="$JOURN"
if [ -z "$EVID" ]; then
  say "Keine Config-Bruch-Hinweise gefunden — hier ist (sicher) nichts zu reparieren."
  exit 2
fi
say "Config-Hinweise:"; echo "$EVID"

# LLM-Diagnose/Empfehlung (best-effort) — für die Meldung, egal ob wir reparieren.
SUGG="$(curl -sf -m 60 "$LLAMA/v1/chat/completions" -H 'Content-Type: application/json' \
  -d "$(python3 - "$EVID" <<'PY'
import json, sys
p = ("Ein Hermes-Agent-Update hat den Selbsttest rot gemacht. Log-Hinweise:\n" + sys.argv[1] +
     "\n\nNenne auf Deutsch in 1-2 kurzen Sätzen die wahrscheinliche Ursache und die konkrete "
     "Config-Korrektur in ~/.hermes/config.yaml (Schlüssel → neuer Wert). Keine Einleitung.")
print(json.dumps({"model": "coder-lite", "max_tokens": 200, "temperature": 0.1,
                  "messages": [{"role": "user", "content": p}]}))
PY
)" 2>/dev/null | python3 -c 'import sys,json; print((json.load(sys.stdin).get("choices") or [{}])[0].get("message",{}).get("content","").strip())' 2>/dev/null)"

# ── 2) Offending Leaf-Keys ziehen ────────────────────────────────────────────
KEYS="$(echo "$EVID" | grep -oE "Unknown [a-zA-Z0-9_.]+|'[a-zA-Z0-9_.]+'" | sed -E "s/^Unknown //; s/'//g" | sort -u)"
LEAVES="$(for k in $KEYS; do echo "${k##*.}"; done | sort -u | grep -vE '^(true|false|null|)$')"

SEC_RX='token|secret|password|approval|api_server_key|ufw|sudo|allowlist|credential'
BAK="$CFG.selfrepair-bak-$(date +%Y%m%d-%H%M%S)"
cp -a "$CFG" "$BAK"

CHANGED=""; SKIPPED=""
for leaf in $LEAVES; do
  if echo "$leaf" | grep -qiE "$SEC_RX"; then SKIPPED="$SKIPPED $leaf(security-tabu)"; continue; fi
  # Nur EINDEUTIGE Schlüssel-Zeilen (genau 1×) anfassen — Mehrdeutige sind zu riskant.
  n=$(grep -cE "^[[:space:]]*${leaf}:" "$CFG" 2>/dev/null); n=${n:-0}
  if [ "$n" = "1" ]; then
    sed -i -E "s|^([[:space:]]*)(${leaf}:.*)$|\1# [selbstrepariert $(date +%F)] \2|" "$CFG"
    CHANGED="$CHANGED $leaf"; say "auskommentiert: $leaf (unbekannt/veraltet)"
  else
    SKIPPED="$SKIPPED $leaf(${n}x)"
  fi
done
[ -n "$SKIPPED" ] && say "nicht automatisch angefasst:$SKIPPED"

if [ -z "$CHANGED" ]; then
  say "Nichts sicher automatisch reparierbar."
  cp -a "$BAK" "$CFG"
  echo "SELFREPAIR_SUGGESTION=$SUGG"
  exit 2
fi

# ── 3) YAML noch gültig? ──────────────────────────────────────────────────────
if [ -x "$VENV_PY" ] && ! "$VENV_PY" -c "import yaml; yaml.safe_load(open('$CFG'))" 2>/dev/null; then
  say "YAML nach Fix ungültig → zurück zum Backup."
  cp -a "$BAK" "$CFG"; echo "SELFREPAIR_SUGGESTION=$SUGG"; exit 2
fi

# ── 4) Neustart + Gehirn-Check ────────────────────────────────────────────────
systemctl --user restart hermes-gateway; sleep 6
if bash "$SRC_DIR/hermes-postcheck.sh" >/dev/null 2>&1; then
  say "Gehirn-Check nach Selbstreparatur GRÜN."
  bash "$SRC_DIR/notify.sh" -s "[Box-Update]" \
    "Commander, nach dem Hermes-Update hakte der Selbsttest wegen geänderter Einstellungen — ich habe das selbst gerichtet (angepasst:${CHANGED// /, }). Der Test ist wieder grün, die neue Version läuft. Ein Rollback war nicht nötig." || true
  exit 0
fi

say "Auch nach Selbstreparatur rot → zurück zum Backup (der Aufrufer rollt zurück)."
cp -a "$BAK" "$CFG"
systemctl --user restart hermes-gateway; sleep 6
echo "SELFREPAIR_SUGGESTION=$SUGG"
exit 2
