#!/usr/bin/env sh
# pre-commit – Agent Quality Gate
#
# Prüft bei jeder Code-Änderung ob:
#   1. Tests erstellt oder aktualisiert wurden
#   2. Mindestens eine Zielgruppen-Dokumentation aktualisiert wurde
#   3. Alle 3 Dokumentations-Zielgruppen vorhanden sind (USER/ADMIN/MAINTAINER)
#   4. history/summary/PROJECT_CONTEXT.md aktualisiert wurde
#   5. docs/requirements/REQUIREMENTS.md keine unstaged Änderungen hat
#   6. *_session.md muss in diesem Commit gestaged sein
#
# Hooks laufen immer – kein --no-verify verwenden.

STAGED=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null)
ERRORS=0

# Quellcode-Dateien (keine Tests, keine Konfiguration, keine Docs, keine Daten)
CODE_CHANGED=$(printf '%s\n' "$STAGED" \
    | grep -E '\.(py|js|ts|mjs|cjs|go|java|rs|rb|php|c|cpp|h|hpp|cs|kt|swift|sh|bash)$' \
    | grep -v -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$' \
    | grep -v -E '^(docs/|\.github/|\.vscode/|data/|history/)' \
    | grep -v -E '_test\.go$')

# Keine Code-Änderungen → Hook überspringen
if [ -z "$CODE_CHANGED" ]; then
    exit 0
fi

# ── Check 1: Tests ────────────────────────────────────────────────────────────
# Opt-out: Datei '.copilot-no-tests' im Repo-Root deaktiviert diesen Check
# (für Repos ohne Test-Framework, z.B. reine Script/Config-Repos)
TESTS_CHANGED=$(printf '%s\n' "$STAGED" \
    | grep -E '(test|spec|__tests__|_test)\.(py|js|ts|mjs|go|java|rs|rb|php|c|cpp|cs|kt|swift)$|_test\.go$|test_.*\.py$')

if [ -z "$TESTS_CHANGED" ] && [ ! -f ".copilot-no-tests" ]; then
    echo ""
    echo "✗ AGENT QUALITY GATE [1/4]: Keine Test-Dateien geändert"
    echo "  Code-Änderungen ohne Test-Updates:"
    printf '%s\n' "$CODE_CHANGED" | sed 's/^/    /'
    echo ""
    echo "  → Tests fehlen oder nicht als STAGED markiert"
    echo "  → Copilot Chat: /write-tests"
    echo "  → Kein Test-Framework vorhanden? Datei '.copilot-no-tests' anlegen um diesen Check zu deaktivieren"
    ERRORS=$((ERRORS + 1))
fi

# ── Check 2: Dokumentation aktualisiert ───────────────────────────────────────
# Prüfen ob docs/ Verzeichnis überhaupt existiert
# Opt-out: Datei '.copilot-no-docs' im Repo-Root deaktiviert diesen Check
# (für reine Config/Script-Repos ohne nutzerseitige Dokumentationspflicht)
if [ -d "docs" ] && [ ! -f ".copilot-no-docs" ]; then
    DOCS_CHANGED=$(printf '%s\n' "$STAGED" \
        | grep -E '(^docs/USER\.md$|^docs/ADMIN\.md$|^docs/MAINTAINER\.md$|^README\.md$)')

    if [ -z "$DOCS_CHANGED" ]; then
        echo ""
        echo "✗ AGENT QUALITY GATE [2/4]: Keine Dokumentation aktualisiert"
        echo "  Bei Code-Änderungen muss mindestens eine dieser Dateien angepasst werden:"
        echo "    docs/USER.md       – Nutzer-Dokumentation"
        echo "    docs/ADMIN.md      – Administrator-Dokumentation"
        echo "    docs/MAINTAINER.md – Entwickler/Maintainer-Dokumentation"
        echo "    README.md"
        echo ""
        echo "  → Copilot Chat: Frage den Agent die relevante Doku zu aktualisieren"
        ERRORS=$((ERRORS + 1))
    fi
fi

# ── Check 3: Vollständigkeit der 3 Zielgruppen ────────────────────────────────
# Nur prüfen wenn docs/ neu angelegt wird (noch nicht vollständig) oder ein
# neues Feature ein neues docs/-File staged hat.
DOCS_DIR_STAGED=$(printf '%s\n' "$STAGED" | grep -E '^docs/' | head -1)

if [ -n "$DOCS_DIR_STAGED" ] && [ -d "docs" ]; then
    MISSING=""
    [ ! -f "docs/USER.md" ]       && MISSING="${MISSING}\n    docs/USER.md       (fehlt – für Endnutzer)"
    [ ! -f "docs/ADMIN.md" ]      && MISSING="${MISSING}\n    docs/ADMIN.md      (fehlt – für Administratoren)"
    [ ! -f "docs/MAINTAINER.md" ] && MISSING="${MISSING}\n    docs/MAINTAINER.md (fehlt – für Entwickler)"

    if [ -n "$MISSING" ]; then
        echo ""
        echo "✗ AGENT QUALITY GATE [3/4]: Fehlende Zielgruppen-Dokumentation"
        printf "  Nicht vorhanden:%b\n" "$MISSING"
        echo ""
        echo "  Alle 3 Zielgruppen-Dokumente müssen existieren."
        echo "  Templates: docs/USER.md, docs/ADMIN.md, docs/MAINTAINER.md"
        ERRORS=$((ERRORS + 1))
    fi
fi

# ── Check 4: PROJECT_CONTEXT.md aktualisiert ──────────────────────────────────
if [ -f "history/summary/PROJECT_CONTEXT.md" ]; then
    CONTEXT_STAGED=$(printf '%s\n' "$STAGED" | grep -F 'history/summary/PROJECT_CONTEXT.md')
    if [ -z "$CONTEXT_STAGED" ]; then
        echo ""
        echo "✗ AGENT QUALITY GATE [4/4]: PROJECT_CONTEXT.md nicht aktualisiert"
        echo "  Bei Code-Änderungen muss der Agent-Kontext aktuell gehalten werden."
        echo "    history/summary/PROJECT_CONTEXT.md"
        echo ""
        echo "  → Copilot Chat: /history   (loggt Session + aktualisiert Kontext)"
        ERRORS=$((ERRORS + 1))
    fi
fi

# ── Check 5: Requirements-Konsistenz ─────────────────────────────────────────
# Wenn docs/requirements/REQUIREMENTS.md existiert und unstaged Änderungen hat,
# muss es vor dem Commit gestaged werden.
# Opt-out: Datei '.copilot-no-requirements' im Repo-Root deaktiviert diesen Check.
if [ -f "docs/requirements/REQUIREMENTS.md" ] && [ ! -f ".copilot-no-requirements" ]; then
    REQ_UNSTAGED=$(git diff --name-only -- "docs/requirements/REQUIREMENTS.md" 2>/dev/null)
    if [ -n "$REQ_UNSTAGED" ]; then
        echo ""
        echo "✗ AGENT QUALITY GATE [5/5]: Requirements-Datei hat unstaged Änderungen"
        echo "  docs/requirements/REQUIREMENTS.md wurde geändert aber nicht gestaged."
        echo ""
        echo "  → git add docs/requirements/REQUIREMENTS.md"
        echo "  → Copilot Chat: /requirements   (Requirements aktualisieren + konsistenz prüfen)"
        ERRORS=$((ERRORS + 1))
    fi
fi

# ── Check 6: Session-Datei muss in diesem Commit gestaged sein ─────────────
# Jeder Commit muss eine *_session.md enthalten – die laufende Konversation
# soll immer dokumentiert werden. Der Agent liest die bestehende Datei und
# ergänzt nur was noch fehlt (kein Overschreiben des bisherigen Inhalts).
# Opt-out: Datei '.copilot-no-session' für Repos ohne Chat-Kontext (z.B. CI).
if [ -d "history/prompts" ] && [ ! -f ".copilot-no-session" ]; then
    SESSION_STAGED=$(printf '%s\n' "$STAGED" | grep -E 'history/prompts/.*_session\.md$' | head -1)
    if [ -z "$SESSION_STAGED" ]; then
        echo ""
        echo "✗ AGENT QUALITY GATE [6/6]: Keine Session-Datei in diesem Commit"
        echo "  Jeder Commit muss eine *_session.md enthalten."
        echo ""
        echo "  → Copilot Chat: /history   (ergänzt bestehende Session-Datei + stagt sie)"
        echo "  → Kein Chat-Kontext (z.B. CI/manuell)? Opt-out anlegen:"
        echo "      touch .copilot-no-session && git add .copilot-no-session"
        ERRORS=$((ERRORS + 1))
    fi
fi

# ── Ergebnis ──────────────────────────────────────────────────────────────────
if [ "$ERRORS" -gt 0 ]; then
    echo ""
    echo "══════════════════════════════════════════════════════════"
    echo "  $ERRORS von 6 Quality Gate(s) nicht bestanden."
    echo "  Behebe die Probleme bevor du committst."
    echo "  ══════════════════════════════════════════════════════════"
    echo ""
    exit 1
fi

exit 0
