#!/usr/bin/env bash
# verify-amiga-input.sh - Typed-character acceptance gate for the Amiga
# port. Boots the Keys example off a directory hard drive in FS-UAE
# under Xvfb, types the RetroNet definition-of-done string with xdotool
# (real X key events, so ':' goes through the emulated shift and
# keymap.library's MapRawKey), then presses Escape. On exit Keys logs
# its full received-character history as hex to joeylog.txt on the boot
# volume -- which is the staged host directory -- and the harness
# compares that against the typed ASCII.
#
# Usage:   scripts/verify-amiga-input.sh
# Requires: fs-uae, Xvfb, xdotool; build/amiga/bin/Keys (make amiga);
#           toolchains/emulators/support/kickstart.rom.
set -euo pipefail

repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
bin_dir=$repo/build/amiga/bin
kickstart=$repo/toolchains/emulators/support/kickstart.rom

target="192.168.1.10:6510"

[ -f "$bin_dir/Keys" ] || { echo "verify-amiga-input: build Keys first (make amiga)" >&2; exit 2; }
[ -f "$kickstart" ] || { echo "verify-amiga-input: missing $kickstart" >&2; exit 2; }

work=$(mktemp -d -t joeylib-amiga-input.XXXXXX)
display_num=$((RANDOM % 500 + 300))
cleanup() {
    [ -n "${fsuae_pid:-}" ] && kill "$fsuae_pid" 2>/dev/null
    [ -n "${xvfb_pid:-}" ]  && kill "$xvfb_pid" 2>/dev/null
    rm -rf "$work"
}
trap cleanup EXIT

mkdir -p "$work/hd/s"
cp "$bin_dir/Keys" "$work/hd/"
echo ":Keys" > "$work/hd/s/startup-sequence"

Xvfb ":$display_num" -screen 0 1024x768x24 >/dev/null 2>&1 &
xvfb_pid=$!
sleep 1

# --fullscreen=1 is REQUIRED under a WM-less Xvfb: SDL only accepts
# keyboard input once its window has input focus, no window manager
# ever grants it to a plain window, and xdotool's windowfocus/
# XSendEvent routes are ignored by SDL. A fullscreen SDL window takes
# focus itself, after which plain XTEST typing (xdotool without
# --window) lands in the emulated Amiga.
DISPLAY=":$display_num" fs-uae \
    --amiga_model=A500 \
    --fast_memory=2048 \
    --kickstart_file="$kickstart" \
    --hard_drive_0="$work/hd" \
    --hard_drive_0_label=JOEYLIB \
    --fullscreen=1 \
    --initial_input_grab=1 \
    --floppy_drive_speed=800 \
    >/dev/null 2>&1 &
fsuae_pid=$!

# Boot AmigaDOS off the directory HD and let startup-sequence launch
# Keys. No sentinel channel here, so give it a generous fixed wait.
sleep 28

# XTEST keyboard events land in whatever window HAS focus, and under
# a WM-less Xvfb the fullscreen SDL window latches it on its own
# schedule -- so wait until getwindowfocus actually reports the FS-UAE
# window before typing, nudging with windowfocus while waiting.
win=$(DISPLAY=":$display_num" xdotool search --name -- "FS-UAE" | head -1)
for i in $(seq 1 30); do
    focus=$(DISPLAY=":$display_num" xdotool getwindowfocus 2>/dev/null || true)
    [ -n "$win" ] && [ "$focus" = "$win" ] && break
    [ -n "$win" ] && DISPLAY=":$display_num" xdotool windowfocus --sync "$win" 2>/dev/null || true
    sleep 1
    [ -z "$win" ] && win=$(DISPLAY=":$display_num" xdotool search --name -- "FS-UAE" | head -1)
done

# Up to three attempts: type, press Escape, then look for the typed=
# line Keys logs on exit. The verdict compares the history's SUFFIX
# against the target, so a partially-delivered early attempt can't
# poison a complete later one -- the proof is that the final 17
# characters arrived in order through the queue.
log="$work/hd/joeylog.txt"
delivered=""
for attempt in 1 2 3; do
    DISPLAY=":$display_num" xdotool type --delay 200 -- "$target"
    sleep 2
    # Hold Escape across several emulated frames: an instantaneous
    # down+up can land inside ONE drainMessages pass, where set-then-
    # clear in the same poll is invisible to the edge predicate.
    DISPLAY=":$display_num" xdotool keydown Escape
    sleep 0.5
    DISPLAY=":$display_num" xdotool keyup Escape
    for i in $(seq 1 10); do
        if [ -f "$log" ] && grep -q "typed=" "$log"; then
            delivered=1
            break 2
        fi
        sleep 1
    done
done
if [ -z "$delivered" ]; then
    echo "verify-amiga-input: FAIL - no typed= line in joeylog.txt (keystrokes never landed?)" >&2
    ls -la "$work/hd" >&2
    exit 1
fi

typedHex=$(grep -o "typed=[0-9A-Fa-f]*" "$log" | tail -1 | cut -d= -f2)
expect=$(printf '%s' "$target" | od -A n -t x1 | tr -d ' \n' | tr 'a-f' 'A-F')
echo "VERIFY-AMIGA-INPUT typed=$typedHex"
case "$typedHex" in
    *"$expect")
        echo "verify-amiga-input: PASS (typed \"$target\", all ${#target} chars arrived via jlInputGetChar)"
        ;;
    *)
        echo "verify-amiga-input: FAIL" >&2
        echo "  expected suffix: $expect" >&2
        echo "  got:             $typedHex" >&2
        exit 1
        ;;
esac
