#!/usr/bin/env bash
#
# Update-Script für WebSSH auf Servern
# Führt alle Schritte zur Installation/Konfiguration von WebSSH aus.
#
# Als root ausführen!
#

set -euo pipefail

[[ $(id -u) -eq 0 ]] || { echo "Bitte als root ausführen!"; exit 1; }

PANEL_ROOT=/var/www/system/htdocs/whfpanel
SERVICE_DIR="${PANEL_ROOT}/services/webssh"
NGINX_SITES_ENABLED=/etc/nginx/sites-enabled
# Nginx-Config: 20_whf_panel (WHF-Server) oder 20-default.conf
SUDOERS_FILE=/etc/sudoers.d/whfpanel-webssh

MYSQL_CNF=/root/.my.cnf
MYSQL_DB=syscp

# WebSSH-Sudo-User (der User, unter dem der WebSSH-Service läuft)
WEBSSH_USER="syscp"

# Alle Prozesse von WebSSH_user beenden (|| true: kein Fehler wenn nichts läuft)
pkill -u "$WEBSSH_USER" || true


log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }

# --- 1. MySQL-Tabelle anlegen ---
log "Schritt 1: MySQL-Tabelle panel_webssh_tokens anlegen..."
mariadb --defaults-extra-file="$MYSQL_CNF" "$MYSQL_DB" <<'EOSQL'
CREATE TABLE IF NOT EXISTS `panel_webssh_tokens` (
  `token` varchar(64) NOT NULL,
  `customerid` int(11) NOT NULL,
  `loginname` varchar(255) NOT NULL,
  `session_hash` varchar(64) NOT NULL,
  `created_at` int(11) NOT NULL,
  `expires_at` int(11) NOT NULL,
  `used_at` int(11) DEFAULT NULL,
  `ipaddress` varchar(45) NOT NULL,
  `useragent` varchar(255) NOT NULL,
  PRIMARY KEY (`token`),
  KEY `idx_customerid` (`customerid`),
  KEY `idx_session_hash` (`session_hash`),
  KEY `idx_expires_at` (`expires_at`),
  KEY `idx_used_at` (`used_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
EOSQL
log "  ✓ Tabelle angelegt"

# --- 2. npm install (falls nötig) ---
log "Schritt 2: npm install im WebSSH-Service-Verzeichnis..."
if ! command -v npm &>/dev/null; then
  log "  npm nicht gefunden, installiere npm..."
  apt-get update -qq
  apt-get install -y npm
fi
cd "$SERVICE_DIR"
npm install
log "  ✓ npm install abgeschlossen"

# --- 3. whfpanel_webssh_shell installieren ---
log "Schritt 3: whfpanel_webssh_shell nach /usr/local/bin kopieren..."
cp -f "$SERVICE_DIR/whfpanel_webssh_shell" /usr/local/bin/whfpanel_webssh_shell
chown root:root /usr/local/bin/whfpanel_webssh_shell
chmod 0755 /usr/local/bin/whfpanel_webssh_shell
log "  ✓ Installiert"

# --- 4. Sudoers-Regel für WebSSH ---
log "Schritt 4: Sudoers-Regel erstellen..."
if ! command -v sudo &>/dev/null; then
  log "  sudo nicht gefunden, installiere sudo..."
  apt-get update -qq
  apt-get install -y sudo
  log "  ✓ sudo installiert"
fi
cat > "$SUDOERS_FILE" <<EOSUDO
# WHFPanel WebSSH - automatisch von update_webssh.sh angelegt
${WEBSSH_USER} ALL=(root) NOPASSWD: /usr/local/bin/whfpanel_webssh_shell *
EOSUDO
chmod 0440 "$SUDOERS_FILE"
if ! visudo -c -f "$SUDOERS_FILE" 2>/dev/null; then
  log "  FEHLER: Sudoers-Syntax ungültig!"
  rm -f "$SUDOERS_FILE"
  exit 1
fi
log "  ✓ Sudoers-Regel angelegt"

# --- 5. Nginx-Konfiguration ---
log "Schritt 5: Nginx-Konfiguration anpassen..."
NGINX_CONF=""
for cand in "${NGINX_SITES_ENABLED}/20_whf_panel" "${NGINX_SITES_ENABLED}/20-default.conf"; do
  if [[ -f "$cand" ]]; then
    NGINX_CONF="$cand"
    break
  fi
done
if [[ -z "$NGINX_CONF" ]]; then
  log "  WARNUNG: Weder 20_whf_panel noch 20-default.conf in ${NGINX_SITES_ENABLED} gefunden, überspringe Nginx-Konfiguration"
else
  log "  Verwende: $NGINX_CONF"
  if grep -q 'location = /webssh/ws' "$NGINX_CONF" 2>/dev/null; then
    log "  WebSSH-Nginx-Block bereits vorhanden, überspringe"
  else
    NGINX_SNIPPET=$(mktemp)
    cat > "$NGINX_SNIPPET" <<'EONGINX'

    ## Websocket für WebSSH
    location = /webssh/ws {
      proxy_pass http://127.0.0.1:9137/webssh/ws;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;

      proxy_read_timeout 3600s;
      proxy_send_timeout 3600s;

      proxy_buffering off;
    }

    location ^~ /webssh/static/ {
      proxy_pass http://127.0.0.1:9137/webssh/static/;
      proxy_set_header Host $host;
      expires 7d;
      add_header Cache-Control "public, max-age=604800, immutable";
    }

    location = whfpanel/bin {
        deny all;
    }

    location = whfpanel/services {
        deny all;
    }

    location = whfpanel/scripts {
        deny all;
    }

EONGINX
    # Nach der ersten server_name-Zeile einfügen
    awk -v snippet="$NGINX_SNIPPET" '
      /server_name[^;]*;/ && !done {
        print
        while ((getline line < snippet) > 0) print line
        close(snippet)
        done=1
        next
      }
      { print }
    ' "$NGINX_CONF" > "${NGINX_CONF}.tmp" && mv "${NGINX_CONF}.tmp" "$NGINX_CONF"
    rm -f "$NGINX_SNIPPET"
    log "  ✓ Nginx-Konfiguration aktualisiert"
  fi

  log "  Nginx-Konfiguration testen..."
  nginx -t
  log "  Nginx neu laden..."
  systemctl reload nginx 2>/dev/null || service nginx reload
  log "  ✓ Nginx neu geladen"
fi

# --- 6. Crontab-Eintrag für @reboot ---
log "Schritt 6: Crontab-Eintrag für $WEBSSH_USER hinzufügen..."
CRON_ENTRY="@reboot /var/www/system/htdocs/whfpanel/services/webssh/start.sh &"
CURRENT_CRON=$(crontab -l -u "$WEBSSH_USER" 2>/dev/null || true)
if echo "$CURRENT_CRON" | grep -qF "webssh/start.sh"; then
  log "  Crontab-Eintrag bereits vorhanden"
else
  (echo "$CURRENT_CRON"; echo "$CRON_ENTRY") | crontab -u "$WEBSSH_USER" -
  log "  ✓ Crontab-Eintrag hinzugefügt"
fi

# --- 7. WebSSH-Service starten bzw. neu starten ---
log "Schritt 7: WebSSH-Service starten bzw. neu starten..."
mkdir -p /var/www/system/logs
if pgrep -f "webssh/start.sh" >/dev/null 2>&1 || ss -tlnp 2>/dev/null | grep -q ':9137'; then
  log "  WebSSH-Service läuft, stoppe für Neustart..."
  pkill -f "webssh/start.sh" 2>/dev/null || true
  fuser -k 9137/tcp 2>/dev/null || true
  sleep 2
  for _ in 1 2 3 4 5; do
    ss -tlnp 2>/dev/null | grep -q ':9137' || break
    log "  Warte auf Freigabe von Port 9137..."
    sleep 2
  done
fi
log "  Starte WebSSH-Service..."
su - "$WEBSSH_USER" -c "cd $SERVICE_DIR && nohup ./start.sh >>/var/www/system/logs/whfpanel-webssh.log 2>&1 &" 2>/dev/null || \
sudo -u "$WEBSSH_USER" bash -c "cd $SERVICE_DIR && nohup ./start.sh >>/var/www/system/logs/whfpanel-webssh.log   &"
sleep 2
if ss -tlnp 2>/dev/null | grep -q ':9137'; then
  log "  ✓ WebSSH-Service gestartet"
else
  log "  WARNUNG: Service starten möglicherweise fehlgeschlagen. Prüfe Log: /var/www/system/logs/whfpanel-webssh.log"
fi

log ""
log "=== WebSSH-Update abgeschlossen ==="
