#!/usr/bin/env bash
set -euo pipefail

ADMIN_USERNAME="${E2E_LOGIN_USERNAME:-e2e_admin}"
ADMIN_PASSWORD="${E2E_LOGIN_PASSWORD:-E2EAdmin@123456}"
ADMIN_EMAIL="${E2E_LOGIN_EMAIL:-e2e_admin@example.com}"
BOOTSTRAP_SECRET_VALUE="${E2E_BOOTSTRAP_SECRET:-${BOOTSTRAP_SECRET:-e2e-bootstrap-secret-0123456789abcdefghijklmnopqrstuvwxyz}}"
BROWSER_PORT="${E2E_CDP_PORT:-0}"
BACKEND_PORT="${E2E_BACKEND_PORT:-0}"
FRONTEND_PORT="${E2E_FRONTEND_PORT:-0}"

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
FRONTEND_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"
PROJECT_ROOT="$(cd -- "$SCRIPT_DIR/../../.." && pwd)"
TMP_ROOT="$(mktemp -d -t ums-playwright-e2e-XXXXXX)"
DATA_ROOT="$TMP_ROOT/data"
SMTP_CAPTURE_FILE="$TMP_ROOT/smtp-capture.jsonl"
SERVER_BIN="$TMP_ROOT/ums-server"
mkdir -p "$DATA_ROOT"

backend_pid=''
frontend_pid=''
smtp_pid=''

cleanup() {
  local exit_code=$?
  for pid in "$frontend_pid" "$backend_pid" "$smtp_pid"; do
    if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
      kill "$pid" 2>/dev/null || true
      wait "$pid" 2>/dev/null || true
    fi
  done
  rm -rf "$TMP_ROOT"
  exit "$exit_code"
}
trap cleanup EXIT INT TERM

get_free_port() {
  python3 - <<'PY'
import socket
s = socket.socket()
s.bind(('127.0.0.1', 0))
print(s.getsockname()[1])
s.close()
PY
}

wait_url_ready() {
  local url="$1"
  local label="$2"
  local attempts="${3:-120}"
  local delay="${4:-0.5}"
  for ((i=0; i<attempts; i++)); do
    if curl -fsS "$url" >/dev/null 2>&1; then
      return 0
    fi
    sleep "$delay"
  done
  echo "$label did not become ready: $url" >&2
  return 1
}

SELECTED_BACKEND_PORT="$BACKEND_PORT"
if [[ "$SELECTED_BACKEND_PORT" == "0" ]]; then
  SELECTED_BACKEND_PORT="$(get_free_port)"
fi
SELECTED_FRONTEND_PORT="$FRONTEND_PORT"
if [[ "$SELECTED_FRONTEND_PORT" == "0" ]]; then
  SELECTED_FRONTEND_PORT="$(get_free_port)"
fi
SELECTED_SMTP_PORT="$(get_free_port)"

BACKEND_BASE_URL="http://127.0.0.1:${SELECTED_BACKEND_PORT}"
FRONTEND_BASE_URL="http://127.0.0.1:${SELECTED_FRONTEND_PORT}"
SQLITE_PATH="$DATA_ROOT/user_management.e2e.db"

cd "$PROJECT_ROOT"
go build -o "$SERVER_BIN" ./cmd/server

echo "playwright e2e backend: $BACKEND_BASE_URL"
echo "playwright e2e frontend: $FRONTEND_BASE_URL"
echo "playwright e2e smtp: 127.0.0.1:$SELECTED_SMTP_PORT"
echo "playwright e2e sqlite: $SQLITE_PATH"

node "$SCRIPT_DIR/mock-smtp-capture.mjs" --port "$SELECTED_SMTP_PORT" --output "$SMTP_CAPTURE_FILE" >"$TMP_ROOT/smtp.log" 2>&1 &
smtp_pid=$!
sleep 0.5
if ! kill -0 "$smtp_pid" 2>/dev/null; then
  cat "$TMP_ROOT/smtp.log" >&2 || true
  echo "smtp capture server failed to start" >&2
  exit 1
fi

(
  export SERVER_PORT="$SELECTED_BACKEND_PORT"
  export DATABASE_DBNAME="$SQLITE_PATH"
  export SERVER_MODE='debug'
  export SERVER_FRONTEND_URL="$FRONTEND_BASE_URL"
  export CORS_ALLOWED_ORIGINS="$FRONTEND_BASE_URL,http://localhost:${SELECTED_FRONTEND_PORT}"
  export LOGGING_OUTPUT='stdout'
  export DISABLE_RATE_LIMIT='1'
  export EMAIL_HOST='127.0.0.1'
  export EMAIL_PORT="$SELECTED_SMTP_PORT"
  export EMAIL_FROM_EMAIL='noreply@test.local'
  export EMAIL_FROM_NAME='UMS E2E'
  export JWT_SECRET='e2e-test-jwt-secret-at-least-32-bytes-long-for-security'
  export BOOTSTRAP_SECRET="$BOOTSTRAP_SECRET_VALUE"
  exec "$SERVER_BIN"
) >"$TMP_ROOT/backend.log" 2>&1 &
backend_pid=$!

if ! wait_url_ready "$BACKEND_BASE_URL/health" 'backend'; then
  cat "$TMP_ROOT/backend.log" >&2 || true
  exit 1
fi

(
  cd "$FRONTEND_ROOT"
  export VITE_API_PROXY_TARGET="$BACKEND_BASE_URL"
  export VITE_API_BASE_URL='/api/v1'
  exec env -u NODE_ENV npm run dev -- --host 127.0.0.1 --port "$SELECTED_FRONTEND_PORT"
) >"$TMP_ROOT/frontend.log" 2>&1 &
frontend_pid=$!

if ! wait_url_ready "$FRONTEND_BASE_URL" 'frontend'; then
  cat "$TMP_ROOT/frontend.log" >&2 || true
  exit 1
fi

cd "$FRONTEND_ROOT"
export E2E_LOGIN_USERNAME="$ADMIN_USERNAME"
export E2E_LOGIN_PASSWORD="$ADMIN_PASSWORD"
export E2E_LOGIN_EMAIL="$ADMIN_EMAIL"
export E2E_BOOTSTRAP_SECRET="$BOOTSTRAP_SECRET_VALUE"
export BOOTSTRAP_SECRET="$BOOTSTRAP_SECRET_VALUE"
export E2E_EXPECT_ADMIN_BOOTSTRAP='1'
export E2E_EXTERNAL_WEB_SERVER='1'
export E2E_MANAGED_BROWSER='1'
export E2E_BASE_URL="$FRONTEND_BASE_URL"
export E2E_SMTP_CAPTURE_FILE="$SMTP_CAPTURE_FILE"

env -u NODE_ENV node ./scripts/run-playwright-cdp-e2e.mjs
