#!/usr/bin/env python3
"""Pre-Commit-Pruefung: faehrt die Stufe-1-Checks automatisch vor jedem Commit.

⚠ WOZU. Am 2026-08-07 habe ich `py_compile`, `pytest` und `check_nfalle` rund
fuenfzehnmal von Hand gestartet — und trotzdem gingen zwei Fehler durch, weil
ich sie im falschen Moment aufrief: die `\\n`-Falle fiel erst beim naechsten
Aufruf auf, die beiden `log.`-Fehler in `core/trader.py` lagen MONATE drin
(einer seit dem Initial-Commit). Ein Hook vergisst das nicht.

WAS GEPRUEFT WIRD (~3–4 s):
  1. `tools/check_nfalle.py` — kompiliert alle .py, ruff (F821/E999),
     JS-String-Literale, die \\n-Falle in beide Richtungen, .ps1-BOM
  2. `pytest` — die Szenario-Suite

⚠ NOTAUSGANG: `git commit --no-verify` ueberspringt den Hook. Das ist Absicht —
eine Pruefung, die einen dringenden Fix blockiert, wird sonst dauerhaft
deinstalliert. Wer ihn nutzt, sollte die Pruefung danach nachholen.

⚠ BEWUSST OHNE das `pre-commit`-Framework: dessen Nutzen ist die Verwaltung von
Werkzeug-Versionen ueber mehrere Entwickler und Maschinen hinweg. Hier gibt es
eine Maschine und einen Entwickler; ein eigenes, versioniertes Skript ist
transparenter und braucht keine isolierten Zusatz-Umgebungen (die dann eine
ANDERE ruff-Version haetten als die Kommandozeile — genau die Art Divergenz,
die dieses Projekt schon oft genug hatte).

Aufruf:
    python tools/pre_commit.py              # Pruefung von Hand
    python tools/pre_commit.py --install    # als Git-Hook einrichten
"""
import subprocess
import sys
import time
from pathlib import Path

WURZEL = Path(__file__).resolve().parents[1]
PY = sys.executable


def lauf(titel: str, argv: list[str]) -> bool:
    t0 = time.time()
    r = subprocess.run(argv, cwd=WURZEL, capture_output=True, text=True)
    dauer = time.time() - t0
    if r.returncode == 0:
        print(f"  ✅ {titel:<28} {dauer:.1f}s")
        return True
    print(f"  ❌ {titel:<28} {dauer:.1f}s")
    # Nur die letzten Zeilen — der Hook soll die Ursache zeigen, nicht fluten.
    for z in (r.stdout + r.stderr).strip().splitlines()[-25:]:
        print(f"       {z}")
    return False


def installieren() -> int:
    hooks = WURZEL / ".git" / "hooks"
    if not hooks.is_dir():
        print("  Kein .git/hooks-Verzeichnis gefunden."); return 1
    ziel = hooks / "pre-commit"
    # ⚠ Git fuer Windows fuehrt Hooks ueber `sh` aus, nicht ueber cmd — deshalb
    # ein sh-Shim mit Vorwaertsschraegstrichen.
    ziel.write_text(
        "#!/bin/sh\n"
        "# Erzeugt von tools/pre_commit.py --install\n"
        f'exec "{Path(PY).as_posix()}" -X utf8 '
        f'"{(WURZEL / "tools" / "pre_commit.py").as_posix()}"\n',
        encoding="utf-8", newline="\n")
    print(f"  Hook installiert: {ziel}")
    print("  Ueberspringen im Notfall:  git commit --no-verify")
    return 0


def main() -> int:
    if "--install" in sys.argv:
        return installieren()

    print("── Pre-Commit ─────────────────────────────────────")
    ok = True
    ok &= lauf("Syntax · Linter · Scanner",
               [PY, "-X", "utf8", str(WURZEL / "tools" / "check_nfalle.py")])
    ok &= lauf("Szenario-Tests (pytest)", [PY, "-X", "utf8", "-m", "pytest", "-q"])
    if ok:
        print("── alles gruen ────────────────────────────────────")
        return 0
    print("── COMMIT GESTOPPT ────────────────────────────────")
    print("   Beheben — oder bewusst uebergehen:  git commit --no-verify")
    return 1


if __name__ == "__main__":
    sys.exit(main())
