#!/usr/bin/env bash
# wk-ios — turn-key WebKit DOM bridge for the iOS Simulator's Safari.
#
# WHY: Maestro/mobile-cli read the native XCUITest a11y tree, which collapses Safari's
# web content into unlabeled nodes. The DOM itself is fully addressable via WebKit's
# Remote Inspector. This wrapper wires up ios-webkit-debug-proxy (iwdp) against the
# running Simulator and evaluates JS in the frontmost Safari page — same power as
# `playwright-cli eval` on desktop, but on the REAL iOS engine.
#
# USAGE:
#   bin/wk-ios "<js-expression>"     # evaluate JS in the sim's Safari, print result
#   bin/wk-ios --url                 # just print the page WebSocket URL
#   bin/wk-ios --stop                # stop the background iwdp proxy this script started
#
# ENV: WK_IOS_PORT (default 9221) — iwdp device-list port; pages are served on WK_IOS_PORT+1.
#
# REQUIRES: brew install ios-webkit-debug-proxy ; python3 ; Node >= 22.4 ; a booted iOS
# Simulator with Safari on a page (bin/mcli set-app com.apple.mobilesafari; bin/mcli open-url <url>).
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
PORT="${WK_IOS_PORT:-9221}"
PAGE_PORT=$((PORT + 1))
IWDP_LOG="${TMPDIR:-/tmp}/wk-ios-iwdp-$PORT.log"
IWDP_PIDFILE="${TMPDIR:-/tmp}/wk-ios-iwdp-$PORT.pid"

# Stop only the proxy we started (recorded in our pidfile) — never other users' iwdp.
stop_proxy() {
  if [[ -f "$IWDP_PIDFILE" ]]; then
    PID="$(cat "$IWDP_PIDFILE" 2>/dev/null || true)"
    if [[ -n "$PID" ]]; then kill "$PID" 2>/dev/null || true; fi
    rm -f "$IWDP_PIDFILE"
  fi
}

if [[ "${1:-}" == "--stop" ]]; then stop_proxy; echo "iwdp stopped"; exit 0; fi

command -v ios_webkit_debug_proxy >/dev/null || { echo "missing: brew install ios-webkit-debug-proxy" >&2; exit 1; }
command -v python3 >/dev/null || { echo "missing: python3 (parses the iwdp page list)" >&2; exit 1; }

# 1) Find the simulator's web inspector unix socket.
SOCK="$(lsof -U 2>/dev/null | grep -oE '/private/var/tmp/[^ ]+webinspectord_sim.socket' | head -1 || true)"
[[ -n "$SOCK" ]] || { echo "no webinspectord_sim socket — is a Simulator booted with Safari open?" >&2; exit 1; }

# 2) Ensure iwdp is running against that socket on our ports.
if ! curl -s "http://localhost:$PORT/json" >/dev/null 2>&1; then
  ios_webkit_debug_proxy -c "null:$PORT,:$PAGE_PORT-$((PAGE_PORT + 100))" -F -s "unix:$SOCK" > "$IWDP_LOG" 2>&1 &
  echo $! > "$IWDP_PIDFILE"
  for _ in $(seq 1 20); do curl -s "http://localhost:$PORT/json" >/dev/null 2>&1 && break; sleep 0.25; done
fi

# 3) Resolve the frontmost page's WebSocket URL: the LAST page that is not about:blank
#    (iwdp lists pages in creation order; the newest non-blank one is what the user sees).
#    Retry briefly: right after iwdp starts, :$PORT answers before the page list is populated.
WS=""
for _ in $(seq 1 20); do
  WS="$(curl -s "http://localhost:$PAGE_PORT/json" 2>/dev/null | python3 -c 'import sys,json
d=json.load(sys.stdin)
p=[x for x in d if x.get("url") and x["url"]!="about:blank"] or d
print(p[-1]["webSocketDebuggerUrl"] if p else "")' 2>/dev/null || true)"
  [[ -n "$WS" ]] && break
  sleep 0.25
done
[[ -n "$WS" ]] || { echo "no inspectable Safari page found on :$PAGE_PORT (open a URL in the sim Safari first)" >&2; exit 1; }

if [[ "${1:-}" == "--url" ]]; then echo "$WS"; exit 0; fi
[[ $# -ge 1 ]] || { echo "usage: wk-ios \"<js-expression>\" | --url | --stop" >&2; exit 2; }

# 4) Evaluate via the Target-wrapped WebKit protocol bridge.
WK_WS="$WS" node "$HERE/wkeval.mjs" "$1"
