#!/bin/bash
# Aria Watchdog - prueft ob die Claude-Session lebt, sichert Kontext, startet neu
# Laeuft alle 2 Minuten via systemd Timer (EINZIGER Trigger, kein Cron!)

TMUX_SESSION="aria"
LOG="/var/log/aria-watchdog.log"
export PATH="/root/.local/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
SESSION_BACKUP="/root/.aria-last-session.txt"
LOCKFILE="/tmp/aria-watchdog.lock"
COOLDOWN_FILE="/tmp/aria-restart-cooldown"
COOLDOWN_SECONDS=600  # 10 Minuten Cooldown nach fehlgeschlagenem Restart
CHECK_COUNTER_FILE="/root/.aria-check-counter"
GRACE_FILE="/tmp/aria-restart-grace"
GRACE_SECONDS=180  # 3 Min Grace Period nach Restart - Telegram braucht Zeit zum Starten

# 12.08.2026 Watchdog-Architektur-Fix (Root-Cause: brain/post-mortem/2026-07-14-root-migration.md
# + brain/02-Wissen/watchdog-incident-2026-08-12.md). Dieser Service laeuft als root (kein
# User= in aria-watchdog.service), aber die echte Aria-tmux-Session laeuft seit der
# 14.07.-Migration unter dem User aria (aria.service: User=aria). tmux-Sockets sind pro-UID
# (/tmp/tmux-<uid>/default) — ein blankes "tmux ..." als root sieht root's EIGENEN, immer
# leeren tmux-Server, nie aria's Session. Das machte jede tmux-basierte Erkennung hier seit
# der Migration wirkungslos (nur der Health-API-Fallback :9998 hat das kaschiert). Fix:
# jeder tmux-Aufruf gegen die Aria-Session laeuft ueber tmux_aria() mit explizitem Socket-Pfad.
ARIA_SYS_UID=$(id -u aria 2>/dev/null || echo 1001)
TMUX_SOCK="/tmp/tmux-${ARIA_SYS_UID}/default"
tmux_aria() { tmux -S "$TMUX_SOCK" "$@"; }

# Dry-Run-Modus fuer sichere Tests der Entscheidungslogik ohne echten Restart/Kill.
# ARIA_WATCHDOG_DRYRUN=1 vor dem Aufruf setzen — alle destruktiven Aktionen werden nur geloggt.
DRYRUN="${ARIA_WATCHDOG_DRYRUN:-0}"

# Token und Chat-ID zentral aus .env
source $HOME/aria/.env 2>/dev/null
BOT_TOKEN="${TELEGRAM_BOT_TOKEN}"
CHAT_ID="${TELEGRAM_CHAT_ID:-${TELEGRAM_CHAT_ID}}"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOG"
}

NOTIFY_COOLDOWN_FILE="/tmp/aria-notify-cooldown"
NOTIFY_COOLDOWN_SECONDS=600  # Max 1 Telegram-Nachricht pro 10 Minuten

telegram_notify() {
    if [ -n "$BOT_TOKEN" ]; then
        # Rate Limit: nicht öfter als alle 10 Min eine Nachricht
        if [ -f "$NOTIFY_COOLDOWN_FILE" ]; then
            LAST_NOTIFY=$(cat "$NOTIFY_COOLDOWN_FILE" 2>/dev/null)
            NOW=$(date +%s)
            ELAPSED=$((NOW - LAST_NOTIFY))
            if [ "$ELAPSED" -lt "$NOTIFY_COOLDOWN_SECONDS" ]; then
                log "Telegram-Notify unterdrueckt (${ELAPSED}s seit letzter, Cooldown ${NOTIFY_COOLDOWN_SECONDS}s)"
                return
            fi
        fi
        date +%s > "$NOTIFY_COOLDOWN_FILE"
        curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
            -d chat_id="$CHAT_ID" \
            -d parse_mode="HTML" \
            -d text="$1" > /dev/null 2>&1
    fi
}

# Lock-File: verhindert parallele Watchdog-Runs
exec 200>"$LOCKFILE"
if ! flock -n 200; then
    exit 0
fi

# Manual-Mode: Wenn Kais direkt mit Claude arbeitet, Watchdog pausieren
# Setzen mit: touch /tmp/aria-manual-mode
# Aufheben automatisch wenn Aria mit --channels laeuft, oder: rm /tmp/aria-manual-mode
if [ -f "/tmp/aria-manual-mode" ]; then
    log "Manual-Mode aktiv (/tmp/aria-manual-mode) - kein Restart"
    exit 0
fi

# Cooldown pruefen
if [ -f "$COOLDOWN_FILE" ]; then
    COOLDOWN_TIME=$(cat "$COOLDOWN_FILE" 2>/dev/null)
    NOW=$(date +%s)
    ELAPSED=$((NOW - COOLDOWN_TIME))
    # Cooldown-Dauer aus Datei lesen (Standard: COOLDOWN_SECONDS, bei Auth-Fehler: 14400s)
    EFFECTIVE_COOLDOWN="$COOLDOWN_SECONDS"
    if [ -f "${COOLDOWN_FILE}.duration" ]; then
        EFFECTIVE_COOLDOWN=$(cat "${COOLDOWN_FILE}.duration" 2>/dev/null || echo "$COOLDOWN_SECONDS")
    fi
    if [ "$ELAPSED" -lt "$EFFECTIVE_COOLDOWN" ]; then
        exit 0
    else
        rm -f "$COOLDOWN_FILE"
        rm -f "${COOLDOWN_FILE}.duration"
    fi
fi

# Prueft ob Telegram-Plugin aktiv ist
# Ab Claude Code v2.1.92+ laeuft das Plugin direkt im Claude-Prozess (kein separater bun server.ts mehr)
# Gibt 0 zurueck wenn OK, 1 wenn kaputt
check_telegram_healthy() {
    # Primaer: Claude-Prozess mit --channels telegram Flag pruefen
    CLAUDE_TELEGRAM=$(pgrep -f "claude.*channels.*telegram" 2>/dev/null)
    if [ -n "$CLAUDE_TELEGRAM" ]; then
        # OpenClaw-Style: Zusaetzlich pruefen ob Bot API erreichbar ist
        # (nicht nur ob Prozess laeuft, sondern ob Telegram antwortet)
        if [ -n "$BOT_TOKEN" ]; then
            BOT_CHECK=$(curl -s --max-time 5 "https://api.telegram.org/bot${BOT_TOKEN}/getMe" 2>/dev/null)
            if echo "$BOT_CHECK" | grep -q '"ok":true'; then
                return 0
            else
                log "TELEGRAM_API_UNREACHABLE: Prozess laeuft aber Bot API antwortet nicht"
                # Nicht sofort killen, koennte temporaer sein
                # Beim naechsten Check (2 Min) nochmal pruefen
                TELEGRAM_FAIL_FILE="/tmp/aria-telegram-fail-count"
                FAIL_COUNT=$(cat "$TELEGRAM_FAIL_FILE" 2>/dev/null || echo 0)
                FAIL_COUNT=$((FAIL_COUNT + 1))
                echo "$FAIL_COUNT" > "$TELEGRAM_FAIL_FILE"
                if [ "$FAIL_COUNT" -ge 3 ]; then
                    log "TELEGRAM_BROKEN: API 3x nicht erreichbar, Restart noetig"
                    rm -f "$TELEGRAM_FAIL_FILE"
                    return 1
                fi
                log "TELEGRAM_API_FAIL: ${FAIL_COUNT}/3 (wartet auf naechsten Check)"
                return 0
            fi
        fi
        # Kein Token = kann nicht testen, Prozess-Check reicht
        return 0
    fi

    # Fallback: Altes bun server.ts Modell (fuer aeltere Plugin-Versionen)
    SERVERTS_PIDS=$(pgrep -f "bun.*server\.ts" 2>/dev/null)
    if [ -n "$SERVERTS_PIDS" ]; then
        SERVERTS_COUNT=$(echo "$SERVERTS_PIDS" | grep -c . 2>/dev/null)
        if [ "$SERVERTS_COUNT" -gt 1 ]; then
            log "TELEGRAM_BROKEN: $SERVERTS_COUNT bun server.ts Prozesse (soll: 1) - Duplikate!"
            pkill -f "bun.*server\.ts" 2>/dev/null
            pkill -f "bun.*telegram" 2>/dev/null
            sleep 1
            pkill -9 -f "bun.*server\.ts" 2>/dev/null
            return 1
        fi
        return 0
    fi

    log "TELEGRAM_BROKEN: Weder Claude+channels noch bun server.ts gefunden"
    return 1
}

# Telegram API OK -> Fail-Counter zuruecksetzen
reset_telegram_fail_counter() {
    rm -f /tmp/aria-telegram-fail-count
}

# Prueft ob $1 ein Nachfahre (beliebige Tiefe) eines claude-Prozesses ist.
# Gibt 0 zurueck wenn irgendwo in der PPID-Kette ein laufender claude steht.
# Fix 2026-04-11: Telegram-Plugin v0.0.5 hat 2+ Ebenen (bun run -> bun server.ts)
# zwischen Claude und dem Bot-Prozess, daher reicht der alte Parent-Check nicht.
is_descendant_of_claude() {
    local pid="$1"
    local depth=0
    while [ -n "$pid" ] && [ "$pid" != "0" ] && [ "$pid" != "1" ] && [ "$depth" -lt 10 ]; do
        local comm
        comm=$(ps -o comm= -p "$pid" 2>/dev/null | tr -d ' ')
        if [ "$comm" = "claude" ]; then
            return 0
        fi
        pid=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ')
        depth=$((depth + 1))
    done
    return 1
}

# Raeume Orphan-Prozesse auf (Telegram-Bots ohne Claude-Vorfahren)
cleanup_orphans() {
    for pid in $(pgrep -f "bun.*telegram.*server" 2>/dev/null); do
        if is_descendant_of_claude "$pid"; then
            continue
        fi
        kill "$pid" 2>/dev/null
        log "Orphan Telegram-Bot $pid gekillt (kein claude im Prozessbaum)"
    done
}

# Double-Session Guard: killt Claude+Telegram Prozesse die NICHT zur aria-Session gehoeren
kill_duplicate_sessions() {
    if ! tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
        return
    fi
    PANE_PID=$(tmux_aria list-panes -t "$TMUX_SESSION" -F '#{pane_pid}' 2>/dev/null | head -1)
    # Finde den Claude-Prozess in der tmux-Session
    EXPECTED_CLAUDE=$(pgrep -P "$PANE_PID" -x claude 2>/dev/null)
    if [ -z "$EXPECTED_CLAUDE" ] && [ "$(ps -p "$PANE_PID" -o comm= 2>/dev/null)" = "claude" ]; then
        EXPECTED_CLAUDE="$PANE_PID"
    fi
    if [ -z "$EXPECTED_CLAUDE" ]; then
        return
    fi
    # Finde alle Claude-Prozesse mit Telegram-Channel und kille die falschen
    for pid in $(pgrep -x claude 2>/dev/null); do
        if [ "$pid" != "$EXPECTED_CLAUDE" ]; then
            # Pruefen ob dieser Prozess Telegram nutzt
            if ls /proc/"$pid"/fd 2>/dev/null | xargs -I{} readlink /proc/"$pid"/fd/{} 2>/dev/null | grep -q telegram; then
                kill "$pid" 2>/dev/null
                log "Doppelte Claude+Telegram Session $pid gekillt (erwartet: $EXPECTED_CLAUDE)"
            fi
        fi
    done
    # Fix 2026-04-11: Die frueher hier stehende "orphan channels-telegram"-Schleife
    # ist entfernt. Sie matchte via pgrep -f "channels.*telegram" auch den tmux-
    # Wrapper und die bash -c Shell, weil diese den claude --channels Aufruf in
    # ihrer Command-Line tragen. Ergebnis: tmux-Server + bash wurden als "Orphans"
    # gekillt und die gesamte Aria-Session ging down. cleanup_orphans() oben
    # uebernimmt bereits das Aufraeumen verwaister bun-telegram-Bot-Prozesse
    # sicher via is_descendant_of_claude().
}

# Responsiveness-Check: PASSIV pruefen ob Aria lebt
# Kein Input an Claude senden (verhindert False Positives bei langen Denkphasen)
# Stattdessen: Hat sich der Screen geaendert seit letztem Check?
# Wenn nicht UND Telegram kaputt: dann erst Alarm
check_aria_responsive() {
    if ! tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
        return 1
    fi
    CURRENT_HASH=$(tmux_aria capture-pane -t "$TMUX_SESSION" -p -S -100 2>/dev/null | md5sum | cut -d' ' -f1)
    HASH_FILE="/tmp/aria-screen-hash"

    if [ -f "$HASH_FILE" ]; then
        LAST_HASH=$(cat "$HASH_FILE" 2>/dev/null)
        if [ "$CURRENT_HASH" = "$LAST_HASH" ]; then
            # Screen unveraendert - aber Aria wartet vielleicht einfach auf Telegram
            if check_telegram_healthy; then
                log "Responsiveness-Check: Screen unveraendert aber Telegram OK - wartet auf Nachrichten"
                echo "$CURRENT_HASH" > "$HASH_FILE"
                return 0
            else
                log "ARIA_UNRESPONSIVE: Screen unveraendert UND Telegram kaputt"
                return 1
            fi
        fi
    fi

    echo "$CURRENT_HASH" > "$HASH_FILE"
    log "Responsiveness-Check: OK (Screen-Aenderung erkannt)"
    return 0
}

# Auto-Debug: Analysiert Watchdog-Log bei wiederholten Fehlern
trigger_debug_analysis() {
    # Pruefen ob Aria 2x in 10 Min neugestartet wurde
    TEN_MIN_AGO=$(date -d '10 minutes ago' '+%Y-%m-%d %H:%M:%S' 2>/dev/null)
    if [ -z "$TEN_MIN_AGO" ]; then
        return
    fi
    RESTART_COUNT=$(grep -c "starte neu\|Restart fehlgeschlagen" "$LOG" 2>/dev/null | tail -1)
    RECENT_RESTARTS=$(tail -20 "$LOG" | grep -c "starte neu\|Restart fehlgeschlagen")
    if [ "$RECENT_RESTARTS" -lt 3 ]; then
        return
    fi
    # Bereits ein Auto-Debug in den letzten 30 Min?
    if tail -20 "$LOG" | grep -q "AUTO-DEBUG TRIGGERED"; then
        return
    fi
    # M4-Fix: Bei aktiven 529-Fehlern keinen claude -p starten - macht es schlimmer
    # Stattdessen nur Telegram-Notify ohne API-Call
    RECENT_529=$(grep -c "529\|overloaded\|Overloaded" "$LOG" 2>/dev/null)
    if [ "$RECENT_529" -gt 0 ] && tail -30 "$LOG" | grep -qi "529\|overloaded"; then
        log "AUTO-DEBUG SKIPPED: Aktive 529-Overloaded-Fehler erkannt - kein API-Call"
        telegram_notify "$(printf '<b>Aria: Zu viele Restarts + 529 Overloaded</b>\n\nAnthropics Server sind ueberlastet. Aria pausiert bis sich die Lage beruhigt.\nManuelle Pruefung: <code>tail -30 /var/log/aria-watchdog.log</code>')"
        return
    fi
    log "AUTO-DEBUG TRIGGERED: Zu viele Restarts ($RECENT_RESTARTS in letzten Log-Eintraegen)"
    # HINWEIS: claude -p funktioniert nicht mit CLAUDE_CODE_OAUTH_TOKEN (Max Plan).
    # claude -p braucht ANTHROPIC_API_KEY den wir nicht haben (LRN-20260409).
    # Stattdessen: Log-Snippet direkt per Telegram schicken.
    LOG_SNIPPET=$(tail -20 "$LOG" | sed 's/[<>&]/./g')
    telegram_notify "$(printf '<b>Aria Auto-Debug: Zu viele Restarts</b>\n\nLetzte Watchdog-Eintraege:\n<pre>%s</pre>\n\nManuell pruefen: <code>tail -50 /var/log/aria-watchdog.log</code>' "$LOG_SNIPPET")"
    log "AUTO-DEBUG: Log-Snippet an Telegram gesendet (kein claude -p, kein API-Key)"
}

# Prueft ob OAuth-Token abgelaufen ist (aus stderr Log)
# Gibt 0 zurueck wenn Token OK, 1 wenn abgelaufen
check_oauth_error() {
    if [ -f /var/log/aria-stderr.log ]; then
        if tail -20 /var/log/aria-stderr.log 2>/dev/null | grep -qi "oauth token has expired\|authentication_error\|401.*token"; then
            return 1
        fi
    fi
    return 0
}

# KAR-516: Pane-401-Detection — sucht im tmux-Screen nach Auth-Failure-Patterns.
# Verhindert dass Aria stundenlang "Please run /login" antwortet ohne Eingriff.
# Pattern Source: tatsaechliche 401-Output-Strings aus Session 19247869 am 22.05.
# Gibt 0 zurueck wenn Pane sauber, 1 wenn 401-Pattern im sichtbaren Screen.
PANE_401_COOLDOWN_FILE="/tmp/aria-401-restart-cooldown"
PANE_401_COOLDOWN_SECONDS=1800  # 30 Min Cooldown zwischen 401-Auto-Restarts (gegen Loops)
# Fix 2026-06-24: bare '401[^0-9]' entfernt — matchte JEDES 401 im Pane (transiente
# HTTP-401, die Claude selbst per Retry abfaengt, sogar Gespraeche ueber den 401-Bug)
# und loeste False-Positive-Restarts mitten in laufender Arbeit aus. Echte Auth-
# Failures zeigen IMMER eine der expliziten Strings unten — die reichen.
PANE_401_PATTERN='Please run /login|authentication_failed|Invalid authentication credentials|Invalid API key|OAuth token has expired'
PANE_401_STRIKE_FILE="/tmp/aria-401-strike-count"
check_pane_401() {
    if ! tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
        rm -f "$PANE_401_STRIKE_FILE"
        return 0
    fi
    # Letzte 200 Zeilen scannen — neueste Auth-Fehler liegen unten
    local pane
    pane=$(tmux_aria capture-pane -t "$TMUX_SESSION" -p -S -200 2>/dev/null)
    if echo "$pane" | grep -qE "$PANE_401_PATTERN"; then
        # Debounce: erst nach 2 aufeinanderfolgenden Checks (~2 Min) restarten.
        # Ein transienter Auth-Fehler, der bis zum naechsten Check verschwindet,
        # loest KEINEN Restart aus. Ein echter abgelaufener Token bleibt stehen
        # und triggert nach 2 Strikes weiterhin den Self-Heal-Restart.
        local strikes
        strikes=$(cat "$PANE_401_STRIKE_FILE" 2>/dev/null || echo 0)
        strikes=$((strikes + 1))
        echo "$strikes" > "$PANE_401_STRIKE_FILE"
        if [ "$strikes" -ge 2 ]; then
            rm -f "$PANE_401_STRIKE_FILE"
            return 1
        fi
        log "PANE_401_STRIKE: ${strikes}/2 (Debounce — kein Restart bis Pattern persistiert)"
        return 0
    fi
    # Pane sauber -> Strike-Counter zuruecksetzen
    rm -f "$PANE_401_STRIKE_FILE"
    return 0
}

# 12.08.2026: confirm_trust() entfernt (Watchdog-Architektur-Fix, siehe Kommentar
# oben bei TMUX_SOCK). Die Funktion gehoerte zum alten manuellen Restart-Pfad, der
# selbst eine root-tmux-Session mit dem veralteten aria-wrapper.sh baute — GENAU der
# Pfad, der root-privilegierte Bypass-Permissions-Verweigerung ausloeste (Post-Mortem
# 2026-07-14) und seither jeden "Trust-Dialog Timeout" in diesem Log erzeugt hat. Der
# neue Restart-Pfad (Schritt 2 unten) geht ueber `systemctl restart aria.service` —
# das laeuft als aria, mit dem gepflegten, aktuellen wrapper.sh, gegen ein Arbeits-
# verzeichnis dessen Trust laengst akzeptiert ist. Kein Trust-Dialog mehr zu bestaetigen.
# Die OAuth-Erkennung (Token abgelaufen -> 4h-Cooldown) lebt jetzt in
# check_restart_ready() weiter, an der gleichen Stelle im neuen Wartepfad.

# Wartet bis Aria den Prompt-Cursor zeigt
wait_for_ready() {
    for i in $(seq 1 45); do
        sleep 2
        if ! tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
            return 1
        fi
        if tmux_aria capture-pane -t "$TMUX_SESSION" -p 2>/dev/null | grep -q "^❯"; then
            return 0
        fi
    done
    return 1
}

# 12.08.2026 (Watchdog-Architektur-Fix): wartet nach `systemctl restart aria.service`
# auf den Prompt und unterscheidet dabei einen abgelaufenen OAuth-Token vom
# allgemeinen Fall — dafuer bringt weiteres Warten/Retry nichts, der lange
# 4h-Cooldown ersetzt den kurzen. Ersetzt die OAuth-Erkennung, die frueher in
# confirm_trust() lebte (siehe Kommentar dort).
# Rueckgabe: 0 = bereit, 1 = Timeout/echter Fehler, 2 = OAuth-Fehler (Cooldown gesetzt)
check_restart_ready() {
    if wait_for_ready; then
        return 0
    fi
    if ! check_oauth_error; then
        log "AUTH_ERROR: OAuth-Token abgelaufen - kein weiterer Restart bis Token erneuert"
        telegram_notify "$(printf '🔑 <b>Aria: OAuth-Token abgelaufen</b>\n\nBitte neuen Token setzen:\n<code>claude /login</code>\n\nRestarts pausiert bis Token erneuert wird.')"
        date +%s > "$COOLDOWN_FILE"
        echo "14400" > "${COOLDOWN_FILE}.duration"
        return 2
    fi
    return 1
}

# Prueft und heilt kritische Systemdienste (Self-Healing)
check_critical_services() {
    local SERVICES=("aria-chat-logger" "aria-api")
    for svc in "${SERVICES[@]}"; do
        if ! systemctl is-active --quiet "$svc" 2>/dev/null; then
            log "SERVICE_DOWN: $svc ist nicht aktiv - starte neu"
            systemctl start "$svc" 2>/dev/null
            sleep 2
            if systemctl is-active --quiet "$svc" 2>/dev/null; then
                log "SERVICE_RECOVERED: $svc erfolgreich neugestartet"
                telegram_notify "$(printf '<b>Aria Self-Heal:</b> %s war down — automatisch neugestartet.' "$svc")"
            else
                log "SERVICE_FAILED: $svc konnte nicht neugestartet werden"
                telegram_notify "$(printf '<b>Aria Watchdog:</b> %s down und Restart fehlgeschlagen!' "$svc")"
            fi
        fi
    done
}

# --- Hauptlogik ---

# Schritt 0: Orphan-Prozesse aufraeumen + kritische Services pruefen
cleanup_orphans
check_critical_services

# Schritt 1: Pruefe ob Claude schon laeuft
if pgrep -x claude > /dev/null 2>&1; then
    if tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
        PANE_PID=$(tmux_aria list-panes -t "$TMUX_SESSION" -F '#{pane_pid}' 2>/dev/null | head -1)
        if [ -n "$PANE_PID" ]; then
            PANE_CMD=$(ps -p "$PANE_PID" -o comm= 2>/dev/null)
            CLAUDE_IN_PANE=$(pgrep -P "$PANE_PID" -x claude 2>/dev/null)
            # Wrapper erzeugt: tmux -> bash -> bash(wrapper) -> claude
            # Daher auch Enkel-Prozesse pruefen
            if [ -z "$CLAUDE_IN_PANE" ]; then
                for child in $(pgrep -P "$PANE_PID" 2>/dev/null); do
                    CLAUDE_IN_PANE=$(pgrep -P "$child" -x claude 2>/dev/null)
                    [ -n "$CLAUDE_IN_PANE" ] && break
                done
            fi
            if [ "$PANE_CMD" = "claude" ] || [ -n "$CLAUDE_IN_PANE" ]; then
                # Alles OK: Session-Backup aktualisieren
                tmux_aria capture-pane -t "$TMUX_SESSION" -p > "$SESSION_BACKUP" 2>/dev/null

                # Session-ID laufend speichern fuer Resume nach Crash
                CLAUDE_PID="${CLAUDE_IN_PANE:-$PANE_PID}"
                if [ -f "/root/.claude/sessions/${CLAUDE_PID}.json" ]; then
                    CURRENT_SID=$(python3 -c "import json; print(json.load(open('/root/.claude/sessions/${CLAUDE_PID}.json'))['sessionId'])" 2>/dev/null)
                    if [ -n "$CURRENT_SID" ]; then
                        echo "$CURRENT_SID" > /root/.aria-session-id.tmp
                        mv /root/.aria-session-id.tmp /root/.aria-session-id
                    fi
                fi

                # TELEGRAM-CHECK - ohne Telegram ist Aria taub
                # Grace Period: Nach Restart brauchen Plugins Zeit zum Laden
                SKIP_TELEGRAM=0
                if [ -f "$GRACE_FILE" ]; then
                    GRACE_TIME=$(cat "$GRACE_FILE" 2>/dev/null)
                    NOW=$(date +%s)
                    GRACE_ELAPSED=$((NOW - GRACE_TIME))
                    if [ "$GRACE_ELAPSED" -lt "$GRACE_SECONDS" ]; then
                        SKIP_TELEGRAM=1
                        log "Telegram-Check uebersprungen (Grace Period, ${GRACE_ELAPSED}s/${GRACE_SECONDS}s)"
                    else
                        rm -f "$GRACE_FILE"
                    fi
                fi
                if [ "$SKIP_TELEGRAM" = "0" ]; then
                    if check_telegram_healthy; then
                        reset_telegram_fail_counter
                        # Aria mit --channels laeuft korrekt -> Manual-Mode aufheben
                        rm -f "/tmp/aria-manual-mode" 2>/dev/null
                    else
                        log "Telegram kaputt bei laufender Session - Komplett-Restart"
                        # Restart-Sentinel schreiben damit Aria danach den Grund weiss
                        cat > /root/.aria-restart-sentinel.json << SENTINEL
{
  "reason": "Telegram-Plugin nicht erreichbar (Watchdog)",
  "timestamp": "$(date -Iseconds)",
  "force": 0
}
SENTINEL
                        telegram_notify "$(printf '⚠️ Telegram-Plugin war kaputt. Aria wird neugestartet.')"
                        tmux_aria kill-session -t "$TMUX_SESSION" 2>/dev/null
                        pkill -x claude 2>/dev/null
                        pkill -f "bun.*server\.ts" 2>/dev/null
                        pkill -f "bun.*telegram" 2>/dev/null
                        sleep 2
                        pkill -9 -f "bun.*server\.ts" 2>/dev/null
                        exit 1
                    fi
                fi

                # KAR-516: Pane-401-Check — Auth-Failure im sichtbaren Output detection
                if ! check_pane_401; then
                    # Fix 2026-06-24: Pane-Match allein loest KEINEN Restart aus.
                    # check_oauth_error liest Claudes stderr-Log (kein Gespraechs-Echo):
                    #   0 = stderr sauber  -> Pane zeigt nur Anzeige-/Gespraechs-Text
                    #       (z.B. Aria redet ueber 401/login) -> NICHT restarten
                    #   1 = echter Auth-Error bestaetigt -> Restart erlaubt
                    if check_oauth_error; then
                        PANE_401_COOLDOWN_OK=0
                        log "PANE_401: Pane-Match aber stderr sauber — kein echter Auth-Error, kein Restart"
                    else
                        PANE_401_COOLDOWN_OK=1
                    fi
                    if [ -f "$PANE_401_COOLDOWN_FILE" ]; then
                        LAST_401_RESTART=$(cat "$PANE_401_COOLDOWN_FILE" 2>/dev/null)
                        NOW=$(date +%s)
                        ELAPSED=$((NOW - LAST_401_RESTART))
                        if [ "$ELAPSED" -lt "$PANE_401_COOLDOWN_SECONDS" ]; then
                            PANE_401_COOLDOWN_OK=0
                            log "PANE_401_DETECTED: aber Cooldown aktiv (${ELAPSED}s/${PANE_401_COOLDOWN_SECONDS}s) — kein Auto-Restart"
                        fi
                    fi
                    if [ "$PANE_401_COOLDOWN_OK" = "1" ]; then
                        log "PANE_401_DETECTED: Auth-Failure im Pane — Auto-Restart wird ausgeloest"
                        date +%s > "$PANE_401_COOLDOWN_FILE"
                        cat > /root/.aria-restart-sentinel.json << SENTINEL
{
  "reason": "401-Auth-Failure im Pane (Watchdog KAR-516)",
  "timestamp": "$(date -Iseconds)",
  "force": 1
}
SENTINEL
                        telegram_notify "$(printf '🔑 <b>Aria 401-Self-Heal</b>\nAuth-Failure im Pane erkannt (Please run /login / 401).\nRestart wird ausgeloest. Wenn das wiederholt passiert: <code>claude /login</code> oder OAuth-Token erneuern.')"
                        tmux_aria kill-session -t "$TMUX_SESSION" 2>/dev/null
                        pkill -x claude 2>/dev/null
                        pkill -f "bun.*server\.ts" 2>/dev/null
                        sleep 2
                        exit 1
                    fi
                fi

                # Double-Session Guard
                kill_duplicate_sessions

                # Responsiveness-Check alle 30 Minuten (jeder 15. Run)
                COUNTER=$(cat "$CHECK_COUNTER_FILE" 2>/dev/null || echo 0)
                COUNTER=$((COUNTER + 1))
                echo "$COUNTER" > "$CHECK_COUNTER_FILE"
                if [ $((COUNTER % 6)) -eq 0 ]; then
                    if ! check_aria_responsive; then
                        log "Responsiveness-Check fehlgeschlagen - pruefe erneut (1/3)"
                        sleep 10
                        if ! check_aria_responsive; then
                            log "Responsiveness-Check fehlgeschlagen (2/3) - letzter Versuch"
                            sleep 10
                            if ! check_aria_responsive; then
                                log "Responsiveness-Check 3x fehlgeschlagen - Restart wird ausgeloest"
                                telegram_notify "$(printf '⚠️ Aria reagiert nicht auf Health-Checks (3x). Restart wird ausgeloest.')"
                                # Session killen damit Schritt 2 greift beim naechsten Run
                                tmux_aria kill-session -t "$TMUX_SESSION" 2>/dev/null
                                pkill -x claude 2>/dev/null
                                trigger_debug_analysis
                                exit 1
                            fi
                        fi
                    fi
                fi

                exit 0
            fi
        fi
    fi
    # Claude laeuft, aber nicht sauber in der aria tmux-Session erkannt.
    # Health-API als Fallback: Wenn /health "online" sagt, laeuft Aria wirklich.
    # KAR-794: Retry statt Single-Shot. Am 2026-06-25 hat EIN transienter Health-Wackler
    # (aria-control-v3 auf :9998 im Hochlauf) gereicht, um einen gesunden, arbeitenden
    # Claude (PID 860584) als "verwaist" zu killen -> Kais verlor Kontext mitten in der
    # Arbeit. Vor jedem Kill 3x / ~15s pruefen; ein einzelner Wackler killt nichts mehr.
    HEALTH_OK=0
    for hc in 1 2 3; do
        HEALTH_RESP=$(curl -s --max-time 3 "http://localhost:9998/health" 2>/dev/null)
        # KAR-794 KERNFIX: Endpoint liefert bare "online\n" OHNE Quotes. Das alte
        # Pattern grep -q '"online"' (MIT Quotes) hat NIE gematcht -> Health-Fallback
        # war seit jeher tot -> jede unklare Prozess-Detection ging direkt zum Kill.
        # grep -qiw matcht sowohl bare "online" als auch JSON "status":"online".
        if echo "$HEALTH_RESP" | grep -qiw 'online'; then
            HEALTH_OK=1
            break
        fi
        [ "$hc" -lt 3 ] && sleep 5
    done
    if [ "$HEALTH_OK" = "1" ]; then
        log "Prozess-Detection unklar, aber Health-API sagt online (nach Retry) - kein Restart"
        tmux_aria capture-pane -t "$TMUX_SESSION" -p > "$SESSION_BACKUP" 2>/dev/null
        exit 0
    fi
    # Health sagt nach 3 Versuchen offline oder nicht erreichbar - echtes Problem
    ARIA_CLAUDE=$(pgrep -f "claude.*channels.*telegram" 2>/dev/null)
    if [ -n "$ARIA_CLAUDE" ]; then
        # Aria-Claude existiert aber tmux-Session fehlt - verwaist!
        # KAR-794: Ein claude MIT --channels telegram ist mit hoher Wahrscheinlichkeit
        # eine arbeitende Aria-Session. Vor dem Kill den sichtbaren Kontext sichern,
        # damit nach dem Neustart nichts spurlos verloren geht.
        log "Verwaister Aria-Claude ($ARIA_CLAUDE) gefunden - Checkpoint + killen und neu starten"
        tmux_aria capture-pane -t "$TMUX_SESSION" -p -S -2000 > "$SESSION_BACKUP" 2>/dev/null
        cp "$SESSION_BACKUP" "/root/.aria-killed-context-$(date +%Y%m%d-%H%M%S).txt" 2>/dev/null
        kill "$ARIA_CLAUDE" 2>/dev/null
        sleep 2
        kill -9 "$ARIA_CLAUDE" 2>/dev/null
        # Weiter zu Schritt 2 (Neustart)
    else
        # Nur Debug-Session(s) ohne Telegram - Aria muss neu gestartet werden
        log "Nur Debug-Claude gefunden (kein Telegram) - Aria muss neu gestartet werden"
        # Weiter zu Schritt 2 (Neustart)
    fi
fi

# Schritt 2: Claude laeuft NICHT. Starten.
log "Aria offline - starte neu"

# Auto-Debug pruefen bei wiederholten Restarts
trigger_debug_analysis

# Alte tote tmux-Session aufraeumen
if tmux_aria has-session -t "$TMUX_SESSION" 2>/dev/null; then
    tmux_aria capture-pane -t "$TMUX_SESSION" -p > "$SESSION_BACKUP" 2>/dev/null
    tmux_aria kill-session -t "$TMUX_SESSION" 2>/dev/null
    log "Tote tmux-Session bereinigt"
    sleep 2
fi

# ALLES was Telegram-Bot heisst sicherheitshalber killen vor Neustart
pkill -f "bun.*telegram.*server" 2>/dev/null
pkill -f "channels.*telegram" 2>/dev/null
sleep 2

# Sicherstellen dass wirklich kein alter Bot-Prozess haengt
if pgrep -f "bun.*telegram" > /dev/null 2>&1; then
    pkill -9 -f "bun.*telegram" 2>/dev/null
    sleep 1
    log "Telegram-Bot Prozesse mit SIGKILL bereinigt"
fi

# Grace Period setzen BEVOR der Start, damit der naechste Watchdog-Run nicht sofort Telegram checkt
date +%s > "$GRACE_FILE"

# 12.08.2026 Watchdog-Architektur-Fix (Root-Cause: brain/post-mortem/2026-07-14-root-migration.md,
# Vollbefund: brain/02-Wissen/watchdog-incident-2026-08-12.md). Der alte Neustart baute HIER
# manuell eine EIGENE root-tmux-Session mit dem veralteten aria-wrapper.sh (Stand 11.05., vor der
# root->aria-Migration) — lief als root, GENAU der Fall, den Claude Code seit 2.1.x hart verweigert
# ("--dangerously-skip-permissions cannot be used with root/sudo"). Das war der Ausloeser fuer den
# 10h-Crash-Loop am 14.07. und fuer jeden seitherigen "Trust-Dialog Timeout"-Fehlschlag in diesem
# Log. aria.service (User=aria, Restart=always) + das AKTUELLE wrapper.sh sind seit der Migration
# die einzige gepflegte Startlogik (wrapper.sh-Kopf: "Kein Watchdog, systemd Restart=always ist der
# Watchdog") — der Watchdog ruft sie jetzt tatsaechlich auf, statt an ihr vorbei eine zweite,
# kaputte Welt zu bauen. Kein Trust-Dialog mehr abzuwarten: das Arbeitsverzeichnis ist als aria
# laengst akzeptiert, wrapper.sh erzeugt seine eigene, korrekt user-scoped tmux-Session selbst
# (stale-Socket-Handling liegt jetzt dort, in seinem eigenen "tmux kill-session"-Vorlauf).
if [ "$DRYRUN" = "1" ]; then
    log "DRYRUN: wuerde 'systemctl reset-failed aria.service' (falls failed) + 'systemctl restart aria.service' ausfuehren"
    exit 0
fi

if systemctl is-failed --quiet aria.service 2>/dev/null; then
    log "aria.service im failed-State (StartLimitBurst erreicht) - reset-failed vor Restart"
    systemctl reset-failed aria.service 2>/dev/null
fi
systemctl restart aria.service 2>/dev/null

check_restart_ready
READY_RESULT=$?
if [ "$READY_RESULT" -eq 2 ]; then
    # Auth-Fehler: Langer Cooldown bereits gesetzt in check_restart_ready
    log "FEHLER: OAuth-Token abgelaufen - 4h Cooldown aktiv, kein weiterer Restart"
    exit 1
elif [ "$READY_RESULT" -ne 0 ]; then
    log "FEHLER: Restart fehlgeschlagen - Cooldown aktiviert (${COOLDOWN_SECONDS}s)"
    date +%s > "$COOLDOWN_FILE"
    telegram_notify "$(printf '❌ Aria Restart fehlgeschlagen (systemctl restart aria.service).\nCooldown 10 Min aktiv.\n<code>journalctl -u aria.service -n 40 --no-pager</code> pruefen.')"
    exit 1
fi

log "Aria bereit (systemctl restart aria.service, wrapper.sh hat Kontext-Restore gehandhabt)"

# Double-Session Guard nach Neustart
sleep 3
kill_duplicate_sessions

exit 0
