#!/usr/bin/env bash
# ci-with-test-display.sh — run browser/GUI commands on a private Xvfb display.
# audience: CI on dedicated boxes (debian1/2) and local GUI smoke tests.
#
# WHY: self-hosted runners often inherit DISPLAY=:0 from a login session that forwards
# to a developer workstation. Headed Chromium/GTK then opens windows on the laptop.
set -euo pipefail

if [[ $# -eq 0 ]]; then
  printf '%s\n' 'usage: ci-with-test-display.sh <command...>' >&2
  exit 2
fi

command -v Xvfb >/dev/null 2>&1 || {
  printf '%s\n' 'ci-with-test-display: Xvfb not found' >&2
  exit 1
}

xvfb_pid=""
cleanup() {
  [[ -n "$xvfb_pid" ]] || return 0
  kill "$xvfb_pid" 2>/dev/null || true
  wait "$xvfb_pid" 2>/dev/null || true
}
trap cleanup EXIT

probe_display() {
  local candidate="$1"
  if command -v xdotool >/dev/null 2>&1; then
    DISPLAY="$candidate" xdotool getdisplaygeometry >/dev/null 2>&1
  elif command -v xdpyinfo >/dev/null 2>&1; then
    DISPLAY="$candidate" xdpyinfo >/dev/null 2>&1
  else
    printf '%s\n' 'ci-with-test-display: xdotool or xdpyinfo required to verify the display' >&2
    exit 1
  fi
}

# X listens on abstract sockets, so a /tmp/.X11-unix probe misses displays already
# taken; claim one by starting on it and stepping to the next number on failure.
display=""
for number in $(seq 90 99); do
  candidate=":${number}"
  Xvfb "$candidate" -screen 0 1280x1024x24 -nolisten tcp >/dev/null 2>&1 &
  xvfb_pid=$!
  for _ in $(seq 1 200); do
    if ! kill -0 "$xvfb_pid" 2>/dev/null; then
      break
    fi
    if probe_display "$candidate"; then
      display="$candidate"
      break
    fi
    sleep 0.05
  done
  if [[ -n "$display" ]]; then
    break
  fi
  cleanup
  xvfb_pid=""
done

if [[ -z "$display" ]]; then
  printf '%s\n' 'ci-with-test-display: no usable private X11 display in :90-:99' >&2
  exit 1
fi

export DISPLAY="$display"
unset WAYLAND_DISPLAY
export GDK_BACKEND=x11

exec "$@"
