#!/bin/sh
# AppImage entry point. Tokens (@NAME@) are stamped by tools/package_appimage.sh
# from packaging/release/app.conf, so this file is title-neutral.
#
# psxrecomp anchors settings, assets, saves, cache, and mods to argv[0]. Inside
# an AppImage that anchor is a read-only squashfs mount, so everything writable
# is seeded into a per-user data directory and the runtime is invoked through a
# symlink that lives there.
set -eu

if [ -z "${APPDIR:-}" ]; then
    echo "@APP_NAME@: APPDIR is not set; launch this through the AppImage runtime." >&2
    exit 1
fi

if [ -n "${@ENV_PREFIX@_DATA_DIR:-}" ]; then
    data_dir=$@ENV_PREFIX@_DATA_DIR
else
    if [ -n "${XDG_DATA_HOME:-}" ]; then
        data_home=$XDG_DATA_HOME
    elif [ -n "${HOME:-}" ]; then
        data_home=$HOME/.local/share
    else
        echo "@APP_NAME@: HOME is not set; set @ENV_PREFIX@_DATA_DIR explicitly." >&2
        exit 1
    fi
    data_dir=$data_home/@EXE_NAME@
fi

payload=$APPDIR/usr/share/@PAYLOAD_DIR@
runtime=$APPDIR/usr/bin/@EXE_NAME@

if [ ! -x "$runtime" ] || [ ! -f "$payload/@GAME_TOML@" ]; then
    echo "@APP_NAME@: AppImage payload is incomplete." >&2
    exit 1
fi

mkdir -p "$data_dir" "$data_dir/saves" "$data_dir/cache" "$data_dir/mods"

# Release-owned resources: refreshed every launch so an AppImage update can
# repair or extend its bundled catalog without touching user settings, memory
# cards, installed third-party mods, or generated cache data.
for tree in assets bios licenses; do
    if [ -d "$payload/$tree" ]; then
        mkdir -p "$data_dir/$tree"
        cp -a "$payload/$tree/." "$data_dir/$tree/"
        chmod -R u+rwX "$data_dir/$tree"
    fi
done
if [ -d "$payload/mods" ]; then
    # Bundled packages belong to the release. Merging would retain removed
    # speed/debug mods after an upgrade. Player packages and state live beside
    # this directory and must survive the refresh.
    rm -rf -- "$data_dir/mods/bundled"
    cp -a "$payload/mods/." "$data_dir/mods/"
    chmod -R u+rwX "$data_dir/mods"
fi

# The bundled overlay cache is a head start, but the cache is also written by
# the running game as it discovers new code. Seed without clobbering: the
# release's shards fill in what is missing, and anything the player has already
# built stays. -n is essential here; -a alone would overwrite user shards on
# every launch.
if [ -d "$payload/cache" ]; then
    mkdir -p "$data_dir/cache"
    cp -a -n "$payload/cache/." "$data_dir/cache/" 2>/dev/null || true
    chmod -R u+rwX "$data_dir/cache"
fi

# The bundled overlay toolchain (pinned relocatable CPython + compile_overlays
# + the recompiler + headers) is what lets a player with no compiler installed
# turn a newly captured overlay into native code instead of interpreting it
# forever. The runtime gates that on <exe-dir>/overlay_toolchain/python/bin/
# python3 existing, and <exe-dir> is THIS data directory (the runtime is invoked
# through the symlink below), not the payload.
#
# LINKED, not copied: it is ~78 MB and entirely read-only at runtime, so copying
# it on every launch would be pure cost. The AppImage mounts at a fresh path
# each run, so the link is repointed every launch rather than left to dangle.
# A real directory here is left ALONE -- that is a toolchain the player or a
# packaging variant put there on purpose, and it wins.
if [ -d "$payload/overlay_toolchain" ]; then
    if [ -L "$data_dir/overlay_toolchain" ] || [ ! -e "$data_dir/overlay_toolchain" ]; then
        ln -sfn "$payload/overlay_toolchain" "$data_dir/overlay_toolchain"
    fi
fi

for file in @GAME_TOML@ LICENSE README.md RELEASE.txt RELEASE_NOTES.md START_HERE.txt AOT_CACHE_AUDIT.json; do
    if [ -f "$payload/$file" ]; then
        cp -f "$payload/$file" "$data_dir/$file"
        chmod u+rw "$data_dir/$file"
    fi
done

# input.ini and keybinds.ini become user-owned after first launch.
if [ ! -f "$data_dir/input.ini" ] && [ -f "$payload/input.ini" ]; then
    cp "$payload/input.ini" "$data_dir/input.ini"
    chmod u+rw "$data_dir/input.ini"
fi

# Stamped by package_appimage.sh from packaging/release/VERSION so the layout
# marker never drifts from the artifact name.
printf '%s\n' "@VERSION@" > "$data_dir/.appimage-layout-version"

if [ "${@ENV_PREFIX@_SEED_ONLY:-0}" = "1" ]; then
    printf '%s\n' "$data_dir"
    exit 0
fi

launcher=$data_dir/.@EXE_NAME@-runtime
ln -sfn "$runtime" "$launcher"
export @ENV_PREFIX@_APPIMAGE_PATH=${APPIMAGE:-}
unset APPIMAGE

export PATH="$APPDIR/usr/bin${PATH:+:$PATH}"
export LD_LIBRARY_PATH="$APPDIR/usr/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export XDG_DATA_DIRS="$APPDIR/usr/share${XDG_DATA_DIRS:+:$XDG_DATA_DIRS}"

cd "$data_dir"
exec "$launcher" "$@"
