#!/usr/bin/env bash
# Zeita VPN Client — запускает локальный HTTPS-портал и открывает браузер
set -euo pipefail

APP_DIR="$(cd "$(dirname "$0")" && pwd)"
PORTAL="$APP_DIR/portal"
PORT="${VPN_PORTAL_PORT:-8787}"
URL="https://127.0.0.1:${PORT}/"
PID_FILE="$APP_DIR/zeita-vpn.pid"
LOG_FILE="$APP_DIR/zeita-vpn.log"

export VPN_BIN="${VPN_BIN:-/opt/cisco/anyconnect/bin/vpn}"
export VPN_PORTAL_PORT="$PORT"
export VPN_DEFAULT_SERVER="${VPN_DEFAULT_SERVER:-psc-vpn.zeita.host}"
export VPN_PORTAL_CERT="${VPN_PORTAL_CERT:-$PORTAL/certs/portal.crt}"
export VPN_PORTAL_KEY="${VPN_PORTAL_KEY:-$PORTAL/certs/portal.key}"

die() { echo "Ошибка: $*" >&2; exit 1; }

need_cmd() {
  command -v "$1" >/dev/null 2>&1 || die "не найдено: $1"
}

need_cmd python3
need_cmd openssl

python3 -c 'import pexpect' 2>/dev/null || die "нужен пакет python3-pexpect (sudo apt install python3-pexpect)"

if [[ ! -x "$VPN_BIN" ]]; then
  cat >&2 <<EOF
AnyConnect CLI не найден: $VPN_BIN

Скачайте и установите клиент:
  Windows: https://zeita.host/anyconnect/anyconnect-win-4.9.00086-core-vpn-webdeploy-k9.exe
  macOS:   https://zeita.host/anyconnect/anyconnect-macos-4.9.00086-webdeploy-k9.pkg
  Linux:   https://zeita.host/anyconnect/anyconnect-linux64-4.9.00086-webdeploy-k9.pkg

После установки запустите Zeita VPN снова.
EOF
  exit 1
fi

# TLS certs (per-machine)
mkdir -p "$PORTAL/certs"
if [[ ! -f "$PORTAL/certs/ca.crt" || ! -f "$VPN_PORTAL_CERT" || ! -f "$VPN_PORTAL_KEY" ]]; then
  echo "Создаю локальный TLS-сертификат…"
  openssl genrsa -out "$PORTAL/certs/ca.key" 2048 2>/dev/null
  openssl req -x509 -new -nodes -key "$PORTAL/certs/ca.key" -sha256 -days 3650 \
    -out "$PORTAL/certs/ca.crt" \
    -subj "/C=RU/O=Zeita Host/OU=Local Dev CA/CN=Zeita VPN Portal Local CA" 2>/dev/null
  openssl genrsa -out "$VPN_PORTAL_KEY" 2048 2>/dev/null
  openssl req -new -key "$VPN_PORTAL_KEY" -out "$PORTAL/certs/portal.csr" \
    -subj "/C=RU/O=Zeita Host/OU=VPN Portal/CN=localhost" 2>/dev/null
  cat > "$PORTAL/certs/portal.ext" <<'EOF'
basicConstraints=CA:FALSE
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:localhost,IP:127.0.0.1,DNS:vpn-portal.local
EOF
  openssl x509 -req -in "$PORTAL/certs/portal.csr" -CA "$PORTAL/certs/ca.crt" -CAkey "$PORTAL/certs/ca.key" \
    -CAcreateserial -out "$VPN_PORTAL_CERT" -days 825 -sha256 -extfile "$PORTAL/certs/portal.ext" 2>/dev/null
  rm -f "$PORTAL/certs/portal.csr" "$PORTAL/certs/portal.ext" "$PORTAL/certs/ca.srl"
  chmod 600 "$PORTAL/certs/ca.key" "$VPN_PORTAL_KEY"
  chmod 644 "$PORTAL/certs/ca.crt" "$VPN_PORTAL_CERT"
  if [[ -x "$PORTAL/trust-ca.sh" ]]; then
    "$PORTAL/trust-ca.sh" >/dev/null 2>&1 || true
  fi
fi

stop_old() {
  if [[ -f "$PID_FILE" ]]; then
    old=$(cat "$PID_FILE" 2>/dev/null || true)
    if [[ -n "${old:-}" ]] && kill -0 "$old" 2>/dev/null; then
      kill "$old" 2>/dev/null || true
      sleep 0.3
    fi
    rm -f "$PID_FILE"
  fi
  if command -v fuser >/dev/null 2>&1; then
    fuser -k "${PORT}/tcp" >/dev/null 2>&1 || true
    sleep 0.2
  fi
}

open_browser() {
  # give server a moment
  for _ in 1 2 3 4 5 6 7 8 9 10; do
    if curl -sk --connect-timeout 1 "$URL" >/dev/null 2>&1; then
      break
    fi
    sleep 0.3
  done
  if command -v xdg-open >/dev/null 2>&1; then
    xdg-open "$URL" >/dev/null 2>&1 || true
  elif command -v firefox >/dev/null 2>&1; then
    firefox "$URL" >/dev/null 2>&1 || true
  fi
}

cleanup() {
  if [[ -f "$PID_FILE" ]]; then
    pid=$(cat "$PID_FILE" 2>/dev/null || true)
    [[ -n "${pid:-}" ]] && kill "$pid" 2>/dev/null || true
    rm -f "$PID_FILE"
  fi
}
trap cleanup EXIT INT TERM

stop_old

echo "Zeita VPN Client"
echo "  Портал: $URL"
echo "  AnyConnect: $VPN_BIN"
echo "  Лог: $LOG_FILE"
echo "  Остановка: Ctrl+C"
echo

cd "$PORTAL"
python3 "$PORTAL/server.py" >>"$LOG_FILE" 2>&1 &
echo $! >"$PID_FILE"
sleep 0.5
kill -0 "$(cat "$PID_FILE")" 2>/dev/null || die "сервер не запустился — см. $LOG_FILE"

open_browser

# keep launcher alive while server runs
while kill -0 "$(cat "$PID_FILE")" 2>/dev/null; do
  sleep 1
done
