#!/usr/bin/env bash
# Launch the built Amiga example in FS-UAE. Defaults to PATTERN.
#
# Kickstart and Workbench:
#   - If toolchains/emulators/support/kickstart.rom is present, it is
#     used as the Kickstart ROM. Otherwise FS-UAE's built-in AROS ROM
#     is used (less compatible with OCS Intuition but requires no
#     licensed files).
#   - If toolchains/emulators/support/workbench.adf is present, it is
#     inserted into DF0: and the Amiga boots Workbench. The user
#     launches the example from the JOEYLIB drawer on the desktop.
#   - If Workbench is not present, AmigaDOS boots directly from DH0:,
#     executes s/startup-sequence, and auto-runs the requested example.
#
# Always on A500 hardware (OCS chipset). Our HAL only uses OCS
# features so this matches real-hardware behavior.
#
#   scripts/run-amiga.sh           # runs Pattern
#   scripts/run-amiga.sh hello     # runs Hello
#   scripts/run-amiga.sh draw      # runs Draw
#   scripts/run-amiga.sh staxi     # runs Taxi (Space Taxi)
#
# Argument is any built example name (case-insensitive); the script
# normalizes it to PascalCase (first letter upper, rest lower) which
# is the JoeyLib convention for Amiga binary filenames. Special
# aliases: "staxi" / "spacetaxi" -> "Taxi" (the Amiga binary name).

set -euo pipefail

if [[ $# -gt 1 ]]; then
    echo "usage: $0 [example-name]" >&2
    exit 2
fi

prog=${1:-pattern}
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
bin_dir=$repo/build/amiga/bin
support=$repo/toolchains/emulators/support

prog_lower=${prog,,}
# Project-name aliases (input -> Amiga binary name). On Amiga the
# Space Taxi binary is "Taxi", not "Staxi" or "Spacetaxi".
case "$prog_lower" in
    staxi|spacetaxi) prog_lower=taxi ;;
esac
file=${prog_lower^}

# An example may live either directly in bin_dir (Pattern, Hello, etc.)
# or inside its own subdir alongside a per-example DATA/ tree (Taxi).
# Prefer the subdir layout if present.
if [[ -f "$bin_dir/$file/$file" ]]; then
    bin_path=$bin_dir/$file/$file
    bin_extra_dir=$bin_dir/$file
elif [[ -f "$bin_dir/$file" ]]; then
    bin_path=$bin_dir/$file
    bin_extra_dir=
else
    echo "$file not built. Run 'make amiga' first." >&2
    echo "  looked for:" >&2
    echo "    $bin_dir/$file/$file" >&2
    echo "    $bin_dir/$file" >&2
    echo "available examples in $bin_dir:" >&2
    find "$bin_dir" -maxdepth 1 -type f -executable -printf '%f\n' >&2 2>/dev/null || true
    find "$bin_dir" -maxdepth 2 -type f -executable -printf '%P\n' >&2 2>/dev/null \
        | grep '/' >&2 || true
    exit 1
fi

kickstart=$support/kickstart.rom
workbench=$support/workbench.adf

# Stage a fresh hard-drive directory containing both example binaries
# plus an s/startup-sequence that auto-invokes the chosen one. The
# startup-sequence only runs when booting directly from the hard
# drive (i.e. no Workbench floppy); Workbench takes over boot if
# present and the user launches manually.
work=$(mktemp -d -t joeylib-amiga.XXXXXX)
# Preserve any diagnostic dumps Pattern writes to the virtual HD
# (copper.txt, etc.) before the temp dir is removed on script exit.
# Also stage UBER's joeylog.txt back to build/amiga/bin/ so the
# tools/uber-perf-table picks it up at the standard path.
dump_keep=/tmp/joeylib-amiga-dump
trap 'mkdir -p "$dump_keep"; cp "$work"/*.txt "$dump_keep"/ 2>/dev/null; cp "$work"/joeylog.txt "$bin_dir/joeylog.txt" 2>/dev/null; rm -rf "$work"' EXIT

mkdir -p "$work/s"
# Stage every built top-level binary (executable file at top of bin_dir,
# no extension on Amiga). DATA/ is copied separately below.
find "$bin_dir" -maxdepth 1 -type f -executable -exec cp -t "$work/" {} +
# Stage the top-level DATA folder (test.mod, test.sfx) the audio demo
# loads from the boot volume at runtime.
if [[ -d "$bin_dir/DATA" ]]; then
    cp -r "$bin_dir/DATA" "$work/"
fi
# If the chosen example lives in its own subdir (Taxi/), stage the
# binary AND its sibling DATA tree -- the subdir's DATA replaces the
# top-level one if there's a conflict. We rsync-merge so existing
# entries (e.g. test.mod) survive alongside Taxi's font.jas, levels/,
# sprites/, tiles/.
if [[ -n "$bin_extra_dir" ]]; then
    cp "$bin_path" "$work/$file"
    if [[ -d "$bin_extra_dir/DATA" ]]; then
        mkdir -p "$work/DATA"
        cp -r "$bin_extra_dir/DATA/." "$work/DATA/"
    fi
fi
# ':' prefix anchors to the root of the current volume; otherwise
# AmigaDOS looks in C: and the command is not found.
echo ":$file" > "$work/s/startup-sequence"

fsargs=(
    --amiga_model=A500
    --fast_memory=2048
    --hard_drive_0="$work"
    --hard_drive_0_label=JOEYLIB
    # Mouse-handling overrides for VM hosts where FS-UAE's default
    # relative-mode grab fights with the hypervisor's own pointer
    # integration. automatic_input_grab=0 stops FS-UAE from grabbing
    # the pointer on focus; middle_click_ungrab=1 is a fallback so a
    # middle-click releases any grab that does occur; mouse_integration=1
    # asks FS-UAE to track host pointer position directly instead of
    # sampling relative deltas.
    --automatic_input_grab=0
    --middle_click_ungrab=1
    --mouse_integration=1
    # Speed overrides: floppy_drive_speed=800 runs the floppy at 8x so
    # the Workbench boot finishes in a few seconds instead of a minute.
    # accuracy=0 and fast_copper=1 are deliberately NOT set -- they
    # compromise copper timing, which our per-scanline palette swaps
    # depend on.
    --floppy_drive_speed=800
)

if [[ -f $kickstart ]]; then
    fsargs+=(--kickstart_file="$kickstart")
fi

if [[ -f $workbench ]]; then
    fsargs+=(--floppy_drive_0="$workbench")
    cat <<EOF
FS-UAE booting Workbench from DF0:. Once the desktop appears:
  1. Double-click the JOEYLIB disk icon.
  2. From the Window menu, pick "Show > All Files" (Workbench hides
     files that have no .info icon by default).
  3. Double-click $file to run it.
Alternatively open a Shell (Workbench > Tools > Shell), type 'cd
JOEYLIB:' then '$file'.
EOF
else
    cat <<EOF
FS-UAE booting directly from the JOEYLIB hard drive. $file will
auto-run via s/startup-sequence. Drop a Workbench 3.1 ADF at
$workbench to boot the GUI instead.
EOF
fi

# Intentionally no exec: we need the bash EXIT trap to fire so the
# scratch dir gets cleaned up (and any diagnostic dumps preserved).
# exec would replace the shell and skip trap execution.
fs-uae "${fsargs[@]}"
