#!/usr/bin/env bash
# Zeita VPN Client — фоновый портал + браузер, без терминала
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"
VPN_BIN="${VPN_BIN:-/opt/cisco/anyconnect/bin/vpn}"

export VPN_BIN
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}"

notify() {
  if command -v notify-send >/dev/null 2>&1; then
    notify-send -a "Zeita VPN" "$@" >/dev/null 2>&1 || true
  fi
}

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

portal_http_ok() {
  curl -sk --connect-timeout 1 --max-time 2 "$URL" >/dev/null 2>&1
}

portal_pid_alive() {
  if [[ -f "$PID_FILE" ]]; then
    local pid
    pid=$(cat "$PID_FILE" 2>/dev/null || true)
    if [[ -n "${pid:-}" ]] && kill -0 "$pid" 2>/dev/null; then
      return 0
    fi
  fi
  return 1
}

command -v python3 >/dev/null 2>&1 || die "нужен python3 — запустите Install-ZeitaVPN.sh"
command -v openssl >/dev/null 2>&1 || die "нужен openssl — запустите Install-ZeitaVPN.sh"
python3 -c 'import pexpect' 2>/dev/null || die "нужен python3-pexpect — запустите Install-ZeitaVPN.sh"
[[ -x "$VPN_BIN" ]] || die "AnyConnect не найден ($VPN_BIN). Запустите Install-ZeitaVPN.sh"

mkdir -p "$PORTAL/certs"
if [[ ! -f "$PORTAL/certs/ca.crt" || ! -f "$VPN_PORTAL_CERT" || ! -f "$VPN_PORTAL_KEY" ]]; then
  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"
  [[ -x "$PORTAL/trust-ca.sh" ]] && "$PORTAL/trust-ca.sh" >/dev/null 2>&1 || true
fi

# Уже отвечает (наш или другой локальный портал) — только открыть браузер
if portal_http_ok; then
  :
elif portal_pid_alive; then
  # PID жив, но HTTP ещё не поднялся — подождём ниже
  :
else
  # Ротация огромного лога
  if [[ -f "$LOG_FILE" ]] && [[ "$(wc -c <"$LOG_FILE" 2>/dev/null || echo 0)" -gt 1048576 ]]; then
    mv -f "$LOG_FILE" "${LOG_FILE}.old" 2>/dev/null || true
  fi
  cd "$PORTAL"
  nohup python3 "$PORTAL/server.py" >>"$LOG_FILE" 2>&1 &
  echo $! >"$PID_FILE"
  disown || true
  sleep 0.7
  if ! portal_pid_alive && ! portal_http_ok; then
    # Порт мог быть занят чужим живым порталом
    if portal_http_ok; then
      :
    else
      die "сервер не запустился — см. $LOG_FILE"
    fi
  fi
fi

for _ in $(seq 1 25); do
  if portal_http_ok; then
    break
  fi
  sleep 0.2
done
portal_http_ok || die "портал не отвечает на $URL — см. $LOG_FILE"

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

notify "Zeita VPN" "Портал открыт. Отключение — кнопкой в браузере."
exit 0
