#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────────────
#  The-Y CRM — Probe-Wiederherstellung (empfohlen: wöchentlich). Läuft auf dem Server im Installationsordner (braucht Docker).
#  Spielt eine Datenbank-Sicherung in eine WEGWERF-Datenbank (eigener Container OHNE Netzwerk, wird danach gelöscht), bringt sie
#  mit der installierten Version auf den neuesten Stand (Migrationen wie beim App-Start) und prüft Stichproben.
#  Die echte Datenbank, App, Dateien und Sicherungen werden NIE verändert (Sicherungen nur lesend eingebunden).
#     bash restore-test.sh                        # neueste Sicherung aus ./backups
#     bash restore-test.sh backups/db-….sql.gz    # bestimmte Sicherung
#  Wöchentlich automatisch (crontab -e):  0 5 * * 0  cd ~/the-y-crm && bash restore-test.sh >> backups/restore-test.log 2>&1
#  Überwachung (optional): RESTORE_TEST_PING_URL (sonst BACKUP_PING_URL aus .env) bekommt bei Erfolg einen Ping, sonst …/fail.
#  Weitere Schalter: RESTORE_TEST_IMAGE (Standard CRM_IMAGE:CRM_TAG aus .env), RESTORE_TEST_PG_IMAGE (postgres:16-alpine),
#  RESTORE_TEST_NAME (Container-Name). 1.1.52 (Review F14).
# ─────────────────────────────────────────────────────────────────────────────
set -euo pipefail
cd "$(dirname "$0")"
envval(){ grep -E "^$1=" .env 2>/dev/null | tail -n 1 | cut -d= -f2- | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'\$/\1/"; }
IMG="${RESTORE_TEST_IMAGE:-$(envval CRM_IMAGE || true)}"; IMG="${IMG:-theyat/crm-app}"
case "$IMG" in *:*) ;; *) TAG="$(envval CRM_TAG || true)"; IMG="$IMG:${TAG:-latest}" ;; esac
PGIMG="${RESTORE_TEST_PG_IMAGE:-postgres:16-alpine}"
DBU="$(envval POSTGRES_USER || true)"; DBU="${DBU:-crm}"
NAME="${RESTORE_TEST_NAME:-theycrm-restoretest-$$}"
PING="${RESTORE_TEST_PING_URL:-$(envval BACKUP_PING_URL || true)}"
PW="rt$(head -c 12 /dev/urandom | od -An -tx1 | tr -d ' \n')"
log(){ echo "[restore-test $(date -u '+%F %T')] $*"; }
ping_url(){ [ -n "$PING" ] || return 0; curl -fsS -m 10 -o /dev/null "$1" 2>/dev/null || wget -q -T 10 -O /dev/null "$1" 2>/dev/null || true; }
fail(){ log "RESTORE_TEST_FEHLER: $*"; ping_url "${PING%/}/fail"; exit 1; }
cleanup(){ docker rm -f -v "$NAME" >/dev/null 2>&1 || true; }
trap cleanup EXIT

command -v docker >/dev/null 2>&1 || fail "Docker fehlt."
[ -f restore.sh ] || fail "restore.sh fehlt in $(pwd) (aktuelle Fassung aus dem Repository holen, siehe SELF-HOSTING.md)."
F="${1:-}"
if [ -z "$F" ]; then F=$(ls -1 backups/db-[0-9]*-[0-9]*.sql.gz 2>/dev/null | LC_ALL=C sort | tail -n 1 || true); fi
[ -n "$F" ] && [ -f "$F" ] || fail "Keine Datenbank-Sicherung gefunden (${F:-backups/db-*.sql.gz})."
FDIR=$(cd "$(dirname "$F")" && pwd); FBASE=$(basename "$F")
log "Probe mit $FBASE (Version $IMG) …"

# 1) Wegwerf-Postgres ohne Netzwerk; Sicherung + restore.sh nur lesend.
docker run -d --name "$NAME" --network none --label the-y.restore-test=1 \
  -e POSTGRES_USER="$DBU" -e POSTGRES_PASSWORD="$PW" -e POSTGRES_DB=crm \
  -v "$FDIR:/probe:ro" -v "$(pwd)/restore.sh:/usr/local/bin/restore.sh:ro" "$PGIMG" >/dev/null || fail "Wegwerf-Datenbank startet nicht ($PGIMG)."
for _ in $(seq 1 90); do docker exec "$NAME" pg_isready -q -h 127.0.0.1 -U "$DBU" -d crm 2>/dev/null && break; sleep 1; done
docker exec "$NAME" pg_isready -q -h 127.0.0.1 -U "$DBU" -d crm 2>/dev/null || fail "Wegwerf-Datenbank nicht bereit."

# 2) Mit dem ECHTEN restore.sh einspielen (prüft Datei, eine Transaktion, Zeilenzahlen).
OUT=$(docker exec -e PGHOST=127.0.0.1 -e POSTGRES_USER="$DBU" -e POSTGRES_PASSWORD="$PW" -e POSTGRES_DB=crm -e BACKUP_DIR=/probe -e RESTORE_STOP_SERVICES= \
  "$NAME" sh /usr/local/bin/restore.sh --ja --ohne-sicherheitskopie "/probe/$FBASE" 2>&1) || { echo "$OUT" | tail -n 8; fail "Einspielen fehlgeschlagen."; }
echo "$OUT" | grep -E "Datei in Ordnung|abgeschlossen und geprüft" || true

# 3) Migrationen der installierten Version (wie beim App-Start) — Netz nur zum Wegwerf-Container (localhost).
docker image inspect "$IMG" >/dev/null 2>&1 || fail "Image $IMG ist auf diesem Server nicht vorhanden."
MOUT=$(docker run --rm --network "container:$NAME" -e DATABASE_URL="postgres://$DBU:$PW@127.0.0.1:5432/crm" --entrypoint sh "$IMG" \
  -c 'cd /app && npm run migrate 2>&1') || { echo "$MOUT" | tail -n 8; fail "Migrationen der installierten Version scheitern auf dieser Sicherung."; }
NEU=$(echo "$MOUT" | grep -c '^> migrate' || true)

# 4) Stichproben.
psqlq(){ docker exec "$NAME" psql -X -q -At -U "$DBU" -d crm -v ON_ERROR_STOP=1 -c "$1"; }
FILES=$(docker run --rm --network none --entrypoint sh "$IMG" -c 'ls -1 /app/db/migrations' | grep '\.sql$' | LC_ALL=C sort)
DONE=$(psqlq "select name from _migrations" | LC_ALL=C sort)
FEHLT=$(comm -23 <(echo "$FILES") <(echo "$DONE") | wc -l | tr -d ' ')
[ "$FEHLT" = 0 ] || fail "$FEHLT Migrationen der installierten Version fehlen nach dem Einspielen."
TEN=$(psqlq "select count(*) from tenants"); USR=$(psqlq "select count(*) from users")
[ "$TEN" -ge 1 ] || fail "Keine Konten (tenants) in der Sicherung."
[ "$USR" -ge 1 ] || fail "Keine Nutzer in der Sicherung."
STICH=$(psqlq "select (select count(*) from contacts) || ' Kontakte, ' || (select count(*) from conversations) || ' Gespräche, ' || (select count(*) from messages) || ' Nachrichten'") \
  || fail "Stichprobe auf Kontakte/Gespräche/Nachrichten fehlgeschlagen."
ping_url "$PING"
log "RESTORE_TEST_OK $FBASE: $TEN Konto/Konten, $USR Nutzer, $STICH; $NEU Migration(en) nachgezogen, Schema auf Stand von $IMG."
