#!/usr/bin/env bash
# Evidence run for #23372. Must run under `headless-desktop` (Xvfb 1920x1080x24 + D-Bus).
# usage: capture-run.sh <before|after> <label> [key=value ...]
#   stall=1        pin the db with /tmp/i23372/pin.py before launch
#   release=<s>    touch flag-release at t=s
#   end=<s>        stop recording + quit at t=s (SIGTERM to the Electron process group)
#   stills=a,b,c   root-window stills at those seconds
#   second=<s>     launch a second instance at t=s
#   quit=<s>       SIGTERM Electron's main pid at t=s, then check the backend child is gone
#   theme=<GTK_THEME value>
#   port=<n>       pin the backend port (default 47723) so a concurrent app cannot steal it
#   wsl=1          seed desktop-settings.json with wslOnly+wslBackendEnabled (F8, harness-only)
set -u
side=$1; label=$2; shift 2
stall=0 release= end=20 stills= second= quit= theme=Adwaita wsl=0 port=47723
for kv in "$@"; do eval "$kv"; done
case $side in before) wt=/home/ubuntu/wt/issue-23372-before;; after) wt=/home/ubuntu/wt/issue-23372;; esac
out=/tmp/i23372-ev/runs/$side-$label; home=/tmp/i23372-ev/home-$side-$label
rm -rf "$out" "$home"; mkdir -p "$out" "$home/userdata"
cp /home/ubuntu/wt/issue-23372/.t3/userdata/statev2.sqlite "$home/userdata/"
db=$home/userdata/statev2.sqlite
[ "$wsl" = 1 ] && echo '{"wslBackendEnabled":true,"wslOnly":true}' > "$home/userdata/desktop-settings.json"
rm -f /tmp/i23372/flag-pinned /tmp/i23372/flag-release
if [ "$stall" = 1 ]; then
  python3 -I /tmp/i23372/pin.py "$db" > "$out/pin.log" 2>&1 & pinpid=$!
  while [ ! -e /tmp/i23372/flag-pinned ]; do sleep 0.5; done
fi
{ echo "side=$side head=$(git -C $wt rev-parse --short=10 HEAD) display=$DISPLAY theme=$theme";
  echo "Xvfb -screen 0 1920x1080x24 (headless-desktop), root $(import -window root png:- | identify -format %wx%h -)"; } > "$out/env.txt"
ffmpeg -loglevel error -f x11grab -video_size 1920x1080 -framerate 10 -i "$DISPLAY" \
  -c:v libx264 -preset veryfast -crf 28 -pix_fmt yuv420p "$out/rec.mp4" & ffpid=$!
sleep 1
t0=$(date +%s.%N); echo "$t0" > "$out/t0"
rel() { awk -v a="$(date +%s.%N)" -v b="$t0" 'BEGIN{printf "%7.1f", a-b}'; }
cd "$wt/apps/desktop"
T3CODE_PORT=$port T3CODE_HOME=$home GTK_THEME=$theme setsid ./node_modules/.bin/electron dist-electron/main.cjs \
  --no-sandbox --disable-gpu > >(while IFS= read -r l; do echo "t=$(rel) $l"; done > "$out/electron.log") 2>&1 &
epid=$!; echo "$epid" > "$out/pgid"
./node_modules/.bin/electron --version > "$out/electron-version" 2>/dev/null &
IFS=, read -ra st <<< "$stills"
for t in $(seq 1 "$end"); do
  sleep "$(awk -v t0="$t0" -v t="$t" -v n="$(date +%s.%N)" 'BEGIN{d=t0+t-n; print (d>0?d:0)}')"
  for s in "${st[@]}"; do [ "$s" = "$t" ] && import -window root "$out/still-$t.png"; done
  [ "$t" = "$release" ] && { touch /tmp/i23372/flag-release; echo "t=$(rel) RELEASE" >> "$out/marks"; }
  if [ "$t" = "$second" ]; then
    echo "t=$(rel) SECOND INSTANCE" >> "$out/marks"
    T3CODE_PORT=$port T3CODE_HOME=$home GTK_THEME=$theme ./node_modules/.bin/electron dist-electron/main.cjs \
      --no-sandbox --disable-gpu > "$out/second.log" 2>&1; echo "second exit $?" >> "$out/marks"
  fi
  if [ "$t" = "$quit" ]; then
    # $epid is the node .bin shim; signal Electron's real main process and track every
    # descendant (the backend child may sit in its own process group).
    emain=$(ps -o pid=,comm= --ppid "$epid" | awk '$2=="electron"{print $1; exit}')
    desc() { ps -e -o pid=,ppid= | awk -v r="$1" '{p[$1]=$2} END{for(i in p){j=i; while(j in p && j!=r && j>1) j=p[j]; if(j==r && i!=r) print i}}'; }
    tree=$(desc "$epid")
    backend=$(for q in $tree; do ps -o pid=,args= -p "$q"; done | awk '/apps\/server\/dist\/bin.mjs/{print $1; exit}')
    { echo "electron main=$emain backend child=$backend (pgid $(ps -o pgid= -p "$backend" | tr -d ' '))"; for q in $tree; do ps -o pid=,ppid=,pgid=,args= -p "$q" | cut -c1-170; done; } > "$out/ps-before-quit.txt"
    echo "t=$(rel) SIGTERM electron main $emain" >> "$out/marks"; kill -TERM "$emain"
    for i in $(seq 1 30); do kill -0 "$emain" 2>/dev/null || break; sleep 0.5; done
    echo "t=$(rel) electron main alive=$(kill -0 $emain 2>/dev/null && echo yes || echo no)" >> "$out/marks"
    sleep 3
    { echo "survivors of the pre-quit tree (blank = none):"; for q in $tree; do ps -o pid=,pgid=,args= -p "$q" | cut -c1-170; done; echo "end"; echo "backend $backend alive=$(kill -0 "$backend" 2>/dev/null && echo yes || echo no)"; echo "electron main $emain alive=$(kill -0 "$emain" 2>/dev/null && echo yes || echo no)"; } > "$out/ps-after-quit.txt"
  fi
done
kill -TERM -- -"$epid" 2>/dev/null; sleep 5; kill -KILL -- -"$epid" 2>/dev/null
kill -INT "$ffpid"; wait "$ffpid" 2>/dev/null
[ -n "${pinpid:-}" ] && { touch /tmp/i23372/flag-release; wait "$pinpid"; }
rm -f /tmp/i23372/flag-pinned /tmp/i23372/flag-release
grep -nE 'connecting splash|backend ready|main window created|httpReadiness|timedOut|second-instance|activate' "$out/electron.log" | cut -c1-260 > "$out/key-lines.txt"
echo "done $out"
