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

if [[ $# -lt 1 ]]; then
  echo "Usage: tools/pw <playwright-cli-command> [args...]" >&2
  exit 1
fi

for arg in "$@"; do
  if [[ "$arg" == "--session" || "$arg" == "--session="* ]]; then
    echo "Do not pass --session directly. Use PLAYWRIGHT_SHARED_SESSION." >&2
    exit 2
  fi
done

CODEX_HOME="${CODEX_HOME:-$HOME/.codex}"
PWCLI="${PWCLI:-$CODEX_HOME/skills/playwright/scripts/playwright_cli.sh}"
SESSION="${PLAYWRIGHT_SHARED_SESSION:-codex-shared}"
LOCK_TIMEOUT="${PLAYWRIGHT_SHARED_LOCK_TIMEOUT:-120}"
LOCK_DIR="${PLAYWRIGHT_SHARED_LOCK_DIR:-/tmp/pw-shared-session.lock}"
INIT_MODE="${PLAYWRIGHT_SHARED_INIT_MODE:-headed}"

if ! command -v npx >/dev/null 2>&1; then
  echo "npx is required." >&2
  exit 1
fi
if [[ ! -x "$PWCLI" ]]; then
  echo "Playwright wrapper not found or not executable: $PWCLI" >&2
  exit 1
fi

acquire_lock() {
  local start_ts now lock_pid lock_mtime
  start_ts="$(date +%s)"
  while ! mkdir "$LOCK_DIR" 2>/dev/null; do
    lock_pid=""
    if [[ -f "$LOCK_DIR/pid" ]]; then
      lock_pid="$(cat "$LOCK_DIR/pid" 2>/dev/null || true)"
    fi
    if [[ -z "$lock_pid" ]]; then
      lock_mtime="$(stat -f %m "$LOCK_DIR" 2>/dev/null || echo 0)"
      now="$(date +%s)"
      if (( now - lock_mtime >= 5 )); then
        rm -rf "$LOCK_DIR" 2>/dev/null || true
        continue
      fi
    fi
    if [[ -n "$lock_pid" ]] && ! kill -0 "$lock_pid" 2>/dev/null; then
      rm -rf "$LOCK_DIR" 2>/dev/null || true
      continue
    fi
    now="$(date +%s)"
    if (( now - start_ts >= LOCK_TIMEOUT )); then
      echo "Timeout waiting for Playwright shared-session lock: $LOCK_DIR" >&2
      exit 1
    fi
    sleep 1
  done
  printf "%s\n" "$$" > "$LOCK_DIR/pid"
  trap 'rm -rf "$LOCK_DIR" 2>/dev/null || true' EXIT INT TERM
}

run_pw() {
  "$PWCLI" --session "$SESSION" "$@"
}

is_missing_session_error() {
  local text="$1"
  if echo "$text" | rg -qi "session.*not found|no browser|not open|closed"; then
    return 0
  fi
  return 1
}

acquire_lock

cmd=("$@")
verb="${cmd[0]}"

if [[ "$verb" == "open" ]]; then
  url=""
  for (( i = 1; i < ${#cmd[@]}; i++ )); do
    arg="${cmd[$i]}"
    if [[ "$arg" != -* ]]; then
      url="$arg"
      break
    fi
  done

  if [[ -n "$url" ]]; then
    set +e
    out="$(run_pw snapshot 2>&1)"
    code=$?
    set -e
    if [[ $code -eq 0 ]]; then
      run_pw goto "$url"
      run_pw snapshot
      exit 0
    fi
    if ! is_missing_session_error "$out"; then
      echo "$out" >&2
      exit $code
    fi
  fi
fi

if [[ "$verb" != "open" ]]; then
  set +e
  out="$(run_pw "${cmd[@]}" 2>&1)"
  code=$?
  set -e
  if [[ $code -eq 0 ]]; then
    echo "$out"
    exit 0
  fi
  if is_missing_session_error "$out"; then
    set +e
    if [[ "$INIT_MODE" == "headless" ]]; then
      run_pw open about:blank >/dev/null 2>&1
      init_code=$?
    elif [[ "$INIT_MODE" == "headed" ]]; then
      run_pw open about:blank --headed >/dev/null 2>&1
      init_code=$?
      if [[ $init_code -ne 0 ]]; then
        run_pw open about:blank >/dev/null 2>&1
        init_code=$?
      fi
    else
      run_pw open about:blank --headed >/dev/null 2>&1
      init_code=$?
      if [[ $init_code -ne 0 ]]; then
        run_pw open about:blank >/dev/null 2>&1
        init_code=$?
      fi
    fi
    set -e
    if [[ $init_code -ne 0 ]]; then
      echo "Failed to initialize shared Playwright session." >&2
      exit 1
    fi
    run_pw "${cmd[@]}"
    exit 0
  fi
  echo "$out" >&2
  exit $code
fi

run_pw "${cmd[@]}"
