#!/usr/bin/env bash
# make-iigs-disk.sh - Build the JOEYLIB ProDOS disk image (joey.2mg) that
# run-iigs-mame.sh and run-iigs.sh mount as the data disk (flop4). It holds
# the launchable example binaries as ProDOS type $B3 (S16 / GS-OS apps) in a
# volume named JOEYLIB, so GS/OS Finder lists and launches them.
#
# A 3.5" floppy caps at 800KB, which cannot hold every example at once.
# Examples are added in priority order (small primitive demos first); any that
# would overflow the volume are skipped with a warning rather than corrupting
# the image. Override the set with JOEY_DISK_EXAMPLES="DRAW SPRITE ...".
#
# Usage: scripts/make-iigs-disk.sh [output.2mg]
# Requires: toolchains/env.sh sourced (LLVM816_ROOT), built IIgs examples.
set -euo pipefail

repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
: "${LLVM816_ROOT:?make-iigs-disk.sh: source toolchains/env.sh first}"
CADIUS="${CADIUS:-$LLVM816_ROOT/tools/cadius/cadius}"
BINDIR="${BINDIR:-$repo/build/iigs/bin}"
OUT="${1:-$BINDIR/joey.2mg}"
VOL=JOEYLIB

[ -x "$CADIUS" ] || { echo "make-iigs-disk.sh: cadius not found at $CADIUS" >&2; exit 2; }

# Priority order: small primitive demos first so DRAW/PATTERN/etc. always fit;
# the large AGI build lands last and is dropped if the floppy is full.
order=(${JOEY_DISK_EXAMPLES:-DRAW PATTERN KEYS JOY SPRITE UBER ADV2 ADV AGI})

work=$(mktemp -d -t joeylib-disk.XXXXXX)
trap 'rm -rf "$work"' EXIT

rm -f "$OUT"
"$CADIUS" CREATEVOLUME "$OUT" "$VOL" 800KB >/dev/null

# Writable save area for the save-file API (joey/file.h -> jlSave*). GS/OS's
# libc has no mkdir, but the IIgs save HAL creates SAVES/ at runtime via GS/OS
# Create; prestaging it here as well means saves work even before that call and
# on a first run. Set JOEY_SKIP_SAVES_PRESTAGE=1 to omit it (tests runtime
# creation in isolation).
if [ -z "${JOEY_SKIP_SAVES_PRESTAGE:-}" ]; then
    "$CADIUS" CREATEFOLDER "$OUT" "/$VOL/SAVES" >/dev/null
fi

freeBlocks() {
    "$CADIUS" CATALOG "$OUT" 2>/dev/null \
        | grep -oE 'Free : [0-9]+' | grep -oE '[0-9]+' | head -1
}

added=()
skipped=()
for name in "${order[@]}"; do
    bin="$BINDIR/$name"
    [ -f "$bin" ] || continue
    sz=$(stat -c%s "$bin")
    # data blocks + one index block per 256 data blocks + a little dir slack
    need=$(( (sz + 511) / 512 + (sz + 131071) / 131072 + 2 ))
    if [ "$need" -gt "$(freeBlocks)" ]; then
        skipped+=("$name")
        continue
    fi
    # ProDOS type $B3 (S16/GS-OS application), aux $0000.
    cp "$bin" "$work/$name#B30000"
    "$CADIUS" ADDFILE "$OUT" "/$VOL" "$work/$name#B30000" >/dev/null
    rm -f "$work/$name#B30000"
    if "$CADIUS" CATALOG "$OUT" 2>/dev/null | grep -qE "^  $name +S16"; then
        added+=("$name")
    else
        skipped+=("$name")
    fi
done

# The NTP replayer binary (audio): jlpAudioInit fopen()s "ntpplayer" from
# the volume at runtime (see src/iigs/audio_full.c NTP_PATH). Plain ProDOS
# BIN ($06) file. Skipped with a warning if it doesn't fit or wasn't built.
if [ -n "${NTP_BIN:-}" ] && [ -f "$NTP_BIN" ]; then
    ntpSz=$(stat -c%s "$NTP_BIN")
    ntpNeed=$(( (ntpSz + 511) / 512 + 2 ))
    if [ "$ntpNeed" -le "$(freeBlocks)" ]; then
        cp "$NTP_BIN" "$work/NTPPLAYER#060000"
        "$CADIUS" ADDFILE "$OUT" "/$VOL" "$work/NTPPLAYER#060000" >/dev/null
        rm -f "$work/NTPPLAYER#060000"
        added+=(NTPPLAYER)
    else
        skipped+=(NTPPLAYER)
    fi
fi

# Space Taxi runtime data: the game fopen()s a DATA/ tree (levels/*.dat,
# tiles/tbank*.tbk, sprites/sprites.spr, font.tbk -- see stRender.c /
# stLevel.c). Packed only when STAXI made it onto the disk, from the IIgs
# asset bake at examples/spacetaxi/generated/iigs (levels and .spr are
# cross-target; .tbk banks are IIgs-baked -- assetLoad.c validates the
# header target byte). GS/OS ProDOS lookups are case-insensitive, so the
# uppercase ProDOS names match the game's lowercase fopen paths.
staxiData="$repo/examples/spacetaxi/generated/iigs"
if [[ " ${added[*]:-} " == *" STAXI "* ]]; then
    if [ -d "$staxiData" ]; then
        "$CADIUS" CREATEFOLDER "$OUT" "/$VOL/DATA" >/dev/null
        "$CADIUS" CREATEFOLDER "$OUT" "/$VOL/DATA/LEVELS" >/dev/null
        "$CADIUS" CREATEFOLDER "$OUT" "/$VOL/DATA/TILES" >/dev/null
        "$CADIUS" CREATEFOLDER "$OUT" "/$VOL/DATA/SPRITES" >/dev/null
        dataAdded=0
        while IFS= read -r f; do
            rel=${f#"$staxiData/"}
            dir=$(dirname "$rel")
            base=$(basename "$rel")
            dst="/$VOL/DATA"
            if [ "$dir" != "." ]; then
                dst="/$VOL/DATA/${dir^^}"
            fi
            cp "$f" "$work/${base^^}#060000"
            "$CADIUS" ADDFILE "$OUT" "$dst" "$work/${base^^}#060000" >/dev/null
            rm -f "$work/${base^^}#060000"
            dataAdded=$((dataAdded + 1))
        done < <(find "$staxiData" -type f | sort)
        added+=("DATA[$dataAdded files]")
    else
        echo "  WARNING: STAXI packed without its DATA tree ($staxiData missing)" >&2
    fi
fi

echo "iigs-disk: $OUT  (volume /$VOL)"
echo "  added:   ${added[*]:-none}"
if [ ${#skipped[@]} -gt 0 ]; then
    echo "  SKIPPED (800KB floppy full): ${skipped[*]}"
    echo "  -> mount a single-example disk via JOEY_DISK_EXAMPLES=\"NAME\" $0"
fi
