#!/usr/bin/env bash
# Boot Canary and drive it into the Stage 02 mission from save slot 01, then
# LEAVE IT RUNNING (unlike grab_tutorial.sh, which snapshots and exits) so a
# live control loop can attach to /dev/shm.
#
# Nav is the verified route: title -> LOAD GAME -> slot 01 -> YES -> READY ROOM
# -> TAKE OFF. With `--hangar` it stops in the HANGAR instead so a loadout can
# be picked first.
set -u
MODE="${1:-fly}"
export HOME=/sylph-home/re SDL_AUDIODRIVER=dummy DISPLAY=:98
SD="$(cd "$(dirname "$0")" && pwd)"
SHOTS=/sylph-home/re/shots

alive(){ ps -o pid=,stat= -C xenia_canary 2>/dev/null | awk '$2 !~ /^Z/ {print $1}'; }

# DO NOT `setsid` THE DISPLAY OR THE EMULATOR. They used to be detached into
# their own sessions so they would outlive the shell that started them. What
# that actually bought was the opposite: a process nothing owns is a process
# nothing keeps alive, and both were being reaped a couple of minutes in — the
# long-standing "Xvfb and the emulator die on their own every few minutes" note.
# MEASURED WRONG 2026-08-10: a harness-tracked BACKGROUND task does not protect
# them either — the display was lost 11 s in, at the turn boundary. Run this
# whole script as ONE BLOCKING FOREGROUND call and leave Xvfb, openbox
# and xenia as its children: they then live exactly as long as the session does.
# `nohup` still shields them from a stray HUP; the exit-status wrapper means a
# death is reported with the server's own account instead of being inferred.
ensure_display(){
  if ! xdpyinfo -display "$DISPLAY" >/dev/null 2>&1; then
    rm -f "/tmp/.X${DISPLAY#:}-lock" 2>/dev/null || true
    nohup bash -c 'Xvfb "$0" -screen 0 1280x720x24 -ac -nolisten tcp \
        +extension GLX +extension RANDR >/tmp/xvfb98.log 2>&1
      echo "$(date +%T) XVFB EXIT $? (128+N means signal N)" >>/tmp/xvfb-exit.log' \
      "$DISPLAY" </dev/null >/dev/null 2>&1 &
    for _ in $(seq 1 50); do xdpyinfo -display "$DISPLAY" >/dev/null 2>&1 && break; sleep 0.2; done
    nohup env DISPLAY="$DISPLAY" HOME=/sylph-home openbox </dev/null >/tmp/openbox98.log 2>&1 &
    sleep 1
  fi
  xdpyinfo -display "$DISPLAY" >/dev/null 2>&1 || { echo "DISPLAY UNAVAILABLE"; exit 1; }
}
step(){ vgamepad dpad "$1"; sleep 0.25; vgamepad dpad center; sleep 0.7; }
shot(){ screenshot "$SHOTS/$1" >/dev/null 2>&1; }

pkill -x xenia_canary 2>/dev/null; sleep 2
[ -n "$(alive)" ] && { kill -9 $(alive) 2>/dev/null; sleep 2; }
rm -f /dev/shm/xenia_memory_* /dev/shm/xenia_code_cache_* 2>/dev/null
ensure_display

cd /sylph-home/re
nohup run-canary --audio --apu=sdl --log_mask=13 \
  --logged_profile_slot_0_xuid=E0300000EFBEA3D4 </dev/null >/dev/null 2>&1 &
sleep 5
"$SD/skip_intro.sh" 600 || { echo "BOOT FAILED (skip_intro exit $?)"; exit 1; }
sleep 14                       # main menu is not input-ready before this

step down                      # NEW GAME -> LOAD GAME
vgamepad tap A 250; sleep 8    # save list, slot 01 preselected
vgamepad tap A 250; sleep 4    # "Load game?" -- cursor starts on NO
step up
vgamepad tap A 250
sleep 28                       # -> READY ROOM
shot "lm-readyroom.png"

if [ "$MODE" = "--hangar" ]; then
  step down; step down         # BRIEFINGS -> HANGAR
  vgamepad tap A 250; sleep 12
  shot "lm-hangar.png"
  echo "STOPPED IN HANGAR"; exit 0
fi

step up                        # BRIEFINGS -> TAKE OFF
vgamepad tap A 250
# The launch cinematic + stage load + objective card is NOT a fixed 75 s under
# lavapipe; wait for the flight HUD itself.
"$SD/wait_flight.sh" 300 || { echo "NEVER REACHED FLIGHT"; exit 1; }
shot "lm-flight.png"
echo "IN FLIGHT (emulator left running)"
