#!/bin/sh
#
# KEEPALIVED-NEUSTARTKONTROLLE (für Knoten 2 – hier als BACKUP erwartet)
# Beobachtend – keine Veränderungen.
#

set -u

BASE="/path/to/vpn-platform"
HA_DIR="${BASE}/ha"
LOG_DIR="${BASE}/logs/keepalived"
CONTAINER="keepalived-vpn-ha-node2"   # Platzhalter
STAMP="$(date '+%Y-%m-%d_%H-%M-%S')"
LOG_FILE="${LOG_DIR}/keepalived-neustartkontrolle-node2_${STAMP}.log"
LATEST_FILE="${LOG_DIR}/keepalived-neustartkontrolle-node2_latest.log"

mkdir -p "${LOG_DIR}" || {
    echo "FEHLER: Log-Verzeichnis konnte nicht erstellt werden." >&2
    exit 10
}

exec 3>&1
exec >>"${LOG_FILE}" 2>&1

log_line() {
    LEVEL="$1"
    shift
    printf '%s [%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "${LEVEL}" "$*"
}

section() {
    printf '\n============================================================\n'
    log_line "SECTION" "$*"
    printf '============================================================\n'
}

run_cmd() {
    DESCRIPTION="$1"
    shift
    log_line "INFO" "${DESCRIPTION}"
    "$@"
    RC=$?
    log_line "RESULT" "Exit-Code=${RC}"
    return "${RC}"
}

section "START DER NEUSTARTKONTROLLE (Knoten 2)"
log_line "INFO" "Diese Kontrolle verändert nichts."

section "CONTAINERSTATUS"
run_cmd "Containerstatus" \
    docker inspect --format \
    'Name={{.Name}} Status={{.State.Status}} Running={{.State.Running}} StartedAt={{.State.StartedAt}} FinishedAt={{.State.FinishedAt}} ExitCode={{.State.ExitCode}} RestartCount={{.RestartCount}} Error={{.State.Error}}' \
    "${CONTAINER}"

section "TMPFS UND PID"
run_cmd "Mount von /run" \
    docker exec "${CONTAINER}" sh -c "mount | grep ' on /run '"

run_cmd "PID-Dateien" \
    docker exec "${CONTAINER}" sh -c "ls -la /run/keepalived && printf 'keepalived.pid=' && cat /run/keepalived/keepalived.pid && printf 'vrrp.pid=' && cat /run/keepalived/vrrp.pid"

run_cmd "Keepalived-Prozesse" \
    docker exec "${CONTAINER}" sh -c "ps | grep '[k]eepalived'"

section "KEEPALIVED-LOGS SEIT DEM NEUSTART"
run_cmd "Letzte 180 Logzeilen" \
    docker logs --timestamps --tail 180 "${CONTAINER}"

section "VPN-HEALTHCHECK"
if [ -x "${HA_DIR}/scripts/check-vpn.sh" ]; then
    "${HA_DIR}/scripts/check-vpn.sh"
    HEALTH_RC=$?
else
    sh "${HA_DIR}/scripts/check-vpn.sh"
    HEALTH_RC=$?
fi
log_line "RESULT" "check-vpn.sh Exit-Code=${HEALTH_RC}"

section "VRRP-ZUSTAND UND VIP"
CURRENT_STATE="UNBEKANNT"
if [ -r "${HA_DIR}/state/current" ]; then
    CURRENT_STATE="$(cat "${HA_DIR}/state/current" 2>/dev/null || echo UNBEKANNT)"
    log_line "INFO" "Zustandsdatei=${CURRENT_STATE}"
else
    log_line "WARN" "Zustandsdatei fehlt: ${HA_DIR}/state/current"
fi

VIP_PRESENT=0
if ip addr show eth0 2>/dev/null | grep -q '192\.168\.xxx\.xxx/24'; then
    VIP_PRESENT=1
    log_line "INFO" "VIP 192.168.xxx.xxx ist auf eth0 vorhanden."
else
    log_line "INFO" "VIP 192.168.xxx.xxx ist auf eth0 nicht vorhanden."
fi

section "ABSCHLUSSBEWERTUNG"
STATUS="$(docker inspect --format '{{.State.Status}}' "${CONTAINER}" 2>/dev/null || echo missing)"
RESTARTS="$(docker inspect --format '{{.RestartCount}}' "${CONTAINER}" 2>/dev/null || echo unknown)"
HAS_TMPFS=0
HAS_DAEMON_ERROR=0
HAS_STARTUP=0

docker exec "${CONTAINER}" sh -c "mount | grep -q ' on /run type tmpfs '" >/dev/null 2>&1 && HAS_TMPFS=1
docker logs --tail 180 "${CONTAINER}" 2>&1 | grep -q 'daemon is already running' && HAS_DAEMON_ERROR=1
docker logs --tail 180 "${CONTAINER}" 2>&1 | grep -q 'Startup complete' && HAS_STARTUP=1

log_line "INFO" "Status=${STATUS}"
log_line "INFO" "RestartCount=${RESTARTS}"
log_line "INFO" "tmpfs_auf_run=${HAS_TMPFS}"
log_line "INFO" "Startup_complete=${HAS_STARTUP}"
log_line "INFO" "daemon_is_already_running=${HAS_DAEMON_ERROR}"
log_line "INFO" "Healthcheck_ExitCode=${HEALTH_RC}"
log_line "INFO" "VRRP_Zustand=${CURRENT_STATE}"
log_line "INFO" "VIP_vorhanden=${VIP_PRESENT}"

BASE_OK=0
if [ "${STATUS}" = "running" ] \
   && [ "${HAS_TMPFS}" -eq 1 ] \
   && [ "${HAS_STARTUP}" -eq 1 ] \
   && [ "${HAS_DAEMON_ERROR}" -eq 0 ] \
   && [ "${HEALTH_RC}" -eq 0 ]; then
    BASE_OK=1
fi

ROLE_OK=0
case "${CURRENT_STATE}" in
    *BACKUP*)
        if [ "${VIP_PRESENT}" -eq 0 ]; then
            ROLE_OK=1
            log_line "INFO" "Normalzustand: Knoten 2 ist BACKUP und trägt keine VIP."
        else
            log_line "WARN" "BACKUP meldet sich, trägt aber dennoch die VIP."
        fi
        ;;
    *MASTER*)
        if [ "${VIP_PRESENT}" -eq 1 ]; then
            ROLE_OK=1
            log_line "WARN" "Knoten 2 ist MASTER und trägt die VIP. Das ist nur bei Failover korrekt."
        else
            log_line "WARN" "MASTER meldet sich, aber die VIP fehlt."
        fi
        ;;
    *FAULT*|*STOPPED*)
        log_line "WARN" "Fehlerzustand: ${CURRENT_STATE}"
        ;;
    *)
        log_line "WARN" "Unklarer VRRP-Zustand: ${CURRENT_STATE}"
        ;;
esac

if [ "${BASE_OK}" -eq 1 ] && [ "${ROLE_OK}" -eq 1 ]; then
    log_line "SUCCESS" "Der Keepalived-Container von Knoten 2 hat den Neustart sauber überstanden."
else
    log_line "WARN" "Die Neustartprüfung ist nicht vollständig erfolgreich."
fi

cp "${LOG_FILE}" "${LATEST_FILE}" 2>/dev/null || true

printf '\nKontrolle für Knoten 2 abgeschlossen.\n' >&3
printf 'Logdatei:\n%s\n' "${LOG_FILE}" >&3
printf 'Aktuelle Kopie:\n%s\n' "${LATEST_FILE}" >&3
exit 0