#!/usr/bin/env bash
# =========================================
# HX-KI · SERVER-ANALYSE v1 (READ-ONLY)
# - Generalisierbar für alle HX-KI-Server
# - Architektur + Runtime
# - KEINE Löschungen, KEINE Änderungen
# - Output: /opt/hx-ki/inventory/hxki_server_analyse_<HOST>_<TS>.txt
# =========================================

set -euo pipefail

HOST="$(hostname -f 2>/dev/null || hostname)"
NOW="$(date +%Y%m%d-%H%M%S)"
REPORT_DIR="/opt/hx-ki/inventory"
REPORT="${REPORT_DIR}/hxki_server_analyse_${HOST}_${NOW}.txt"

mkdir -p "${REPORT_DIR}"

log() {
  echo "$@" | tee -a "${REPORT}"
}

sep() {
  log
  log "-----------------------------------------"
}

log "========================================="
log " HX-KI · SERVER-ANALYSE v1"
log " Host:   ${HOST}"
log " Datum:  ${NOW}"
log "========================================="
log

# 1) SYSTEM / OS / KERNEL
log "[1] SYSTEM · OS · KERNEL"
log "-----------------------------------------"
log "uname -a:"
uname -a 2>&1 | tee -a "${REPORT}"
log
log "/etc/os-release (relevant):"
if [ -f /etc/os-release ]; then
  grep -E '^(PRETTY_NAME|NAME|VERSION)=' /etc/os-release 2>/dev/null | tee -a "${REPORT}" || cat /etc/os-release | tee -a "${REPORT}"
else
  log "  /etc/os-release nicht gefunden."
fi
log
log "uptime:"
uptime 2>&1 | tee -a "${REPORT}"
sep

# 2) CPU / RAM / STORAGE
log "[2] HARDWARE · SPEICHER · PLATZ"
log "-----------------------------------------"
log "CPU:"
lscpu 2>/dev/null | sed -n '1,10p' | tee -a "${REPORT}" || log "  lscpu nicht verfügbar."
log
log "RAM (free -h):"
free -h 2>/dev/null | tee -a "${REPORT}" || log "  free nicht verfügbar."
log
log "Storage (df -h / und /opt /data, falls vorhanden):"
df -h / 2>/dev/null | tee -a "${REPORT}" || log "  df / fehlgeschlagen."
[ -d /opt ] && df -h /opt 2>/dev/null | tee -a "${REPORT}" || true
[ -d /data ] && df -h /data 2>/dev/null | tee -a "${REPORT}" || true
sep

# 3) NETZWERK / OFFENE PORTS (Architektur-Sicht)
log "[3] NETZWERK · INTERFACES · PORTS"
log "-----------------------------------------"
log "IP / Interfaces (ip -brief addr):"
ip -brief addr 2>/dev/null | tee -a "${REPORT}" || log "  ip nicht verfügbar."
log
log "Routen (ip route):"
ip route 2>/dev/null | tee -a "${REPORT}" || log "  ip route nicht verfügbar."
log
log "Offene TCP/UDP-Ports (ss -tulpen, Kurzform):"
ss -tulpen 2>/dev/null | tee -a "${REPORT}" || log "  ss nicht verfügbar."
sep

# 4) DOCKER · ARCHITEKTUR + RUNTIME
log "[4] DOCKER · ARCHITEKTUR + RUNTIME"
log "-----------------------------------------"
if command -v docker >/dev/null 2>&1; then
  log "docker version (Kurzinfo):"
  docker version --format 'Client: {{.Client.Version}} · Server: {{.Server.Version}}' 2>/dev/null | tee -a "${REPORT}" || log "  docker version fehlgeschlagen."
  log
  log "Laufende Container (Names, Image, Command, Status, Ports):"
  docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Command}}\t{{.Status}}\t{{.Ports}}" 2>/dev/null | tee -a "${REPORT}" || log "  docker ps fehlgeschlagen."
  log
  log "Alle Container (inkl. exited):"
  docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}" 2>/dev/null | tee -a "${REPORT}" || log "  docker ps -a fehlgeschlagen."
  log

  log "Docker-Networks:"
  docker network ls 2>/dev/null | tee -a "${REPORT}" || log "  docker network ls fehlgeschlagen."
  log

  log "Docker-Volumes:"
  docker volume ls 2>/dev/null | tee -a "${REPORT}" || log "  docker volume ls fehlgeschlagen."
  log

  log "Docker Images (Kurzliste):"
  docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 2>/dev/null | tee -a "${REPORT}" || log "  docker images fehlgeschlagen."
  log

  # 4a) ARCHITEKTUR-METADATEN JE CONTAINER
  log "Container-Architektur-Details (Compose-Labels, Volumes, Networks):"
  for cname in $(docker ps --format '{{.Names}}' 2>/dev/null); do
    log
    log "  >>> Container: ${cname}"
    docker inspect "${cname}" \
      --format '    Labels: {{json .Config.Labels}}' 2>/dev/null | tee -a "${REPORT}" || log "    Labels konnten nicht gelesen werden."
    docker inspect "${cname}" \
      --format '    Mounts: {{json .Mounts}}' 2>/dev/null | tee -a "${REPORT}" || log "    Mounts konnten nicht gelesen werden."
    docker inspect "${cname}" \
      --format '    Networks: {{json .NetworkSettings.Networks}}' 2>/dev/null | tee -a "${REPORT}" || log "    Networks konnten nicht gelesen werden."
  done

else
  log "Docker ist nicht installiert oder nicht im PATH."
fi
sep

# 5) /opt · ARCHITEKTURBAUM (HX-KI)
log "[5] /opt · ARCHITEKTURBAUM"
log "-----------------------------------------"
if [ -d /opt ]; then
  log "ls -al /opt:"
  ls -al /opt 2>&1 | tee -a "${REPORT}"
  log

  if [ -d /opt/hx-ki ]; then
    log "ls -al /opt/hx-ki (Top-Level):"
    ls -al /opt/hx-ki 2>&1 | tee -a "${REPORT}"
    log

    log "/opt/hx-ki Unterstruktur (maxdepth 3):"
    find /opt/hx-ki -maxdepth 3 -type d 2>/dev/null | tee -a "${REPORT}"
  else
    log "/opt/hx-ki existiert nicht."
  fi
else
  log "/opt existiert nicht."
fi
sep

# 6) /data · WORKSPACE-EBENE
log "[6] /data · WORKSPACE"
log "-----------------------------------------"
if [ -d /data ]; then
  log "ls -al /data:"
  ls -al /data 2>&1 | tee -a "${REPORT}"
  log
  # nur eine Ebene tiefer auflisten, um nicht zu fluten
  for d in /data/*; do
    [ -d "$d" ] || continue
    log "Inhalt von $(basename "$d") (maxdepth 2):"
    find "$d" -maxdepth 2 -type d -o -maxdepth 1 -type f 2>/dev/null | tee -a "${REPORT}"
    log
  done
else
  log "/data existiert nicht."
fi
sep

# 7) DOCKER-COMPOSE / BAUPLÄNE
log "[7] DOCKER-COMPOSE · BAUPLÄNE"
log "-----------------------------------------"
if [ -d /opt ]; then
  log "Gefundene docker-compose.yml / compose.yml unter /opt (maxdepth 6):"
  find /opt -maxdepth 6 -type f \( -name "docker-compose.yml" -o -name "compose.yml" \) 2>/dev/null | tee -a "${REPORT}" || log "  keine Compose-Dateien gefunden."
  log

  # Optional: ersten Zeilen jeder Compose-Datei (Architekturüberblick)
  while IFS= read -r f; do
    [ -f "$f" ] || continue
    log ">>> Auszug aus: $f"
    sed -n '1,40p' "$f" 2>/dev/null | tee -a "${REPORT}"
    log
  done < <(find /opt -maxdepth 4 -type f \( -name "docker-compose.yml" -o -name "compose.yml" \) 2>/dev/null || true)
else
  log "kein /opt → keine Compose-Suche."
fi
sep

# 8) ENV-FILES / KONFIG (ohne Inhalte zu leaken, nur Pfade)
log "[8] ENV-FILES / KONFIG-PFADE"
log "-----------------------------------------"
if [ -d /opt/hx-ki ]; then
  log "ENV-ähnliche Dateien unter /opt/hx-ki (nur Pfade, kein Inhalt):"
  find /opt/hx-ki -maxdepth 4 -type f \( -name ".env" -o -name "*.env" -o -name "*.env.local" \) 2>/dev/null | tee -a "${REPORT}" || log "  keine ENV-Dateien gefunden."
else
  log "/opt/hx-ki existiert nicht → keine ENV-Suche."
fi
sep

# 9) POSTGRES / DATENBANK-ÜBERSICHT (wenn Container vorhanden)
log "[9] POSTGRES · DATENBANK-ÜBERSICHT"
log "-----------------------------------------"
if command -v docker >/dev/null 2>&1; then
  # versuche, einen Postgres-Container zu finden (heuristisch)
  PG_CONT="$(docker ps --format '{{.Names}} {{.Image}}' 2>/dev/null | grep -Ei 'postgres' | head -n1 | awk '{print $1}')"
  if [ -n "${PG_CONT}" ]; then
    log "Gefundener Postgres-Container: ${PG_CONT}"
    # env dumpen (aber ohne Passwort-Werte im Klartext, nur Keys sichtbar machen)
    log "Postgres-Env (nur Keys):"
    docker inspect "${PG_CONT}" --format '{{range .Config.Env}}{{println .}}{{end}}' 2>/dev/null \
      | sed 's/=.*/=***MASKIERT***/' | tee -a "${REPORT}" || log "  Env nicht lesbar."

    # versuche, DB-Liste zu holen (generisch)
    log
    log "Datenbanken in dieser Instanz (psql -l, falls möglich):"
    docker exec -it "${PG_CONT}" psql -U postgres -c "\l" 2>/dev/null | tee -a "${REPORT}" || \
    docker exec -it "${PG_CONT}" psql -U hxki -c "\l" 2>/dev/null | tee -a "${REPORT}" || \
    log "  psql -l konnte nicht generisch ausgeführt werden (User/Pass unbekannt)."
  else
    log "Kein laufender Postgres-Container gefunden."
  fi
else
  log "Docker nicht verfügbar → keine Postgres-Analyse."
fi
sep

log "========================================="
log " ENDE · SERVER-ANALYSE v1"
log " Report: ${REPORT}"
log "========================================="
