#!/usr/bin/env bash
# The distributed payload is a setup kit. All owner-generated files stay outside it.
set -euo pipefail
APPDIR="${APPDIR:-$(cd -- "$(dirname -- "$0")" && pwd)}"
identity="$(cat "$APPDIR/payload-id")"
[[ "$identity" =~ ^[a-f0-9]{64}$ ]] || { echo 'Invalid AppImage payload identity' >&2; exit 1; }
data="${WXL_APPIMAGE_DATA_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/Wipeout2K97XL}"
[[ "$data" == /* ]] || { echo 'AppImage data directory must be absolute' >&2; exit 2; }
install="$data/versions/$identity"
profile="$data/profile"
mkdir -p -- "$data/versions" "$profile/saves"
# Serialize installation and first-time profile seeding; release before launching.
exec 9>"$data/install.lock"
flock 9
if [[ ! -f "$install/.appimage-ready" ]]; then
    mkdir -p -- "$install"
    cp -a -- "$APPDIR/usr/share/wipeoutxl/kit/." "$install/"
    mkdir -p -- "$install/.appimage-python"
    cp -a -- "$APPDIR/usr/python/." "$install/.appimage-python/"
    for file in input.ini keybinds.ini; do
        [[ -e "$profile/$file" ]] || cp -- "$install/$file" "$profile/$file"
    done
    [[ -e "$profile/settings.toml" ]] || : >"$profile/settings.toml"
    [[ -e "$profile/mods-state.toml" ]] || printf 'format_version = 2\n' >"$profile/mods-state.toml"
    # Save directories remain shared even when the game atomically replaces a card.
    for base in "$install" "$install/build-release"; do
        mkdir -p -- "$base/mods"
        ln -sfn -- "$profile/saves" "$base/saves"
    done
    : >"$install/.appimage-ready"
fi
flock -u 9
exec 9>&-
# Config writers replace files atomically, which would replace a file symlink.
# Copy the shared profile in, then commit changed files after the player exits.
exec 8>"$data/profile.lock"
flock -n 8 || { echo 'Wipeout2K97XL is already running with this profile' >&2; exit 1; }
for base in "$install" "$install/build-release"; do
    for file in input.ini keybinds.ini settings.toml; do
        cp -p -- "$profile/$file" "$base/$file"
    done
    cp -p -- "$profile/mods-state.toml" "$base/mods/state.toml"
done

# Keep dependencies available even when the setup host exits to rebuild.
# Preserve the host loader environment for SDL, graphics drivers and build tools.
# Bundled Python alone resolves private dependencies through its ELF RUNPATH.
export RETCOMM_PYTHON="${RETCOMM_PYTHON:-$install/.appimage-python/bin/python3}"
export PATH="$install/.appimage-python/bin:$PATH"
export PYTHONNOUSERSITE=1
unset PYTHONHOME PYTHONPATH
export SSL_CERT_FILE="${SSL_CERT_FILE:-$install/.appimage-python/ssl/cert.pem}"
export WIPEOUT2K97XL_PROJECT_ROOT="$install"

# Steam Input supplies a standard virtual gamepad for Deck and Steam Controller 2026.
# Disabling duplicate direct devices is confined to this child process.
case "${WXL_STEAM_INPUT_MODE:-steam}" in
    steam)
        export SDL_JOYSTICK_HIDAPI_STEAM="${SDL_JOYSTICK_HIDAPI_STEAM:-0}"
        export SDL_JOYSTICK_HIDAPI_STEAMDECK="${SDL_JOYSTICK_HIDAPI_STEAMDECK:-0}"
        ;;
    direct-deck)
        export SDL_JOYSTICK_HIDAPI_STEAMDECK="${SDL_JOYSTICK_HIDAPI_STEAMDECK:-1}"
        ;;
    *) echo 'WXL_STEAM_INPUT_MODE must be steam or direct-deck' >&2; exit 2 ;;
esac
export SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD="${SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD:-1}"
cd -- "$install"
"$install/Wipeout2K97XL" "$@" &
child=$!
trap 'kill -TERM "$child" 2>/dev/null || true' TERM INT
status=0
wait "$child" || status=$?
if kill -0 "$child" 2>/dev/null; then wait "$child" || status=$?; fi
trap - TERM INT
for file in input.ini keybinds.ini settings.toml mods-state.toml; do
    relative="$file"
    [[ "$file" != mods-state.toml ]] || relative=mods/state.toml
    latest=""
    for base in "$install" "$install/build-release"; do
        candidate="$base/$relative"
        if [[ -f "$candidate" ]] && ! cmp -s -- "$candidate" "$profile/$file"; then
            if [[ -z "$latest" || ! "$latest" -nt "$candidate" ]]; then latest="$candidate"; fi
        fi
    done
    [[ -z "$latest" ]] || cp -p -- "$latest" "$profile/$file"
done
exit "$status"
