#!/usr/bin/env bash
set -euo pipefail
APPDIR="${APPDIR:-$(cd "$(dirname "$0")" && pwd)}"
VERSION="$(cat "$APPDIR/setup/VERSION")"
DATA_ROOT="${XDG_DATA_HOME:-$HOME/.local/share}/superbomberman5"
mkdir -p "$DATA_ROOT"
# Serialize first extraction and never replace the player's generated files.
exec 9>"$DATA_ROOT/.setup.lock"
flock 9
DEST="$DATA_ROOT/$VERSION"
if [[ ! -f "$DEST/.appimage-ready" ]]; then
  if [[ -e "$DEST" ]]; then
    echo "Incomplete setup at $DEST; move it aside before retrying." >&2
    exit 1
  fi
  TEMP="$(mktemp -d "$DATA_ROOT/.setup-XXXXXX")"
  trap 'rm -rf -- "$TEMP"' EXIT
  cp -a "$APPDIR/setup/." "$TEMP/"
  chmod -R u+w "$TEMP"
  # A newer AppImage (the updater replaces the file) starts a new version
  # folder: bring the player's own files from the newest earlier one. The game
  # itself is rebuilt from the ROM by the launcher's Generate & rebuild.
  PREV="$(ls -1dt "$DATA_ROOT"/*/.appimage-ready 2>/dev/null | head -n 1 || true)"
  if [[ -n "$PREV" ]]; then
    PREV="$(dirname "$PREV")"
    for item in rom.cfg config.ini keybinds.ini saves mods/preloaded/state.toml; do
      if [[ -e "$PREV/$item" ]]; then
        mkdir -p "$TEMP/$(dirname "$item")"
        cp -a "$PREV/$item" "$TEMP/$item"
      fi
    done
  fi
  touch "$TEMP/.appimage-ready"
  mv "$TEMP" "$DEST"
  trap - EXIT
fi
flock -u 9
# The game folder is $DEST, not the folder holding the .AppImage file. The host
# anchors config, rom.cfg, saves, mods and its own project lookup to $APPIMAGE's
# folder when that is set (meant for AppImages that run inside the read-only
# mount). Ours runs a writable copy here, so with $APPIMAGE visible the setup
# host never found its tree: no "Generate & rebuild" wizard, PLAY enabled, and
# "This is a setup build" on PLAY. Keep the path for the updater only.
APPIMAGE_FILE="${SB5_APPIMAGE:-${APPIMAGE:-}}"
unset APPIMAGE
if [[ -n "$APPIMAGE_FILE" ]]; then
  export SB5_APPIMAGE="$APPIMAGE_FILE"
  # v2.2.6 and earlier wrote the player's files beside the .AppImage; bring them
  # into the game folder once, never over files already there.
  SIDE="$(dirname "$APPIMAGE_FILE")"
  if [[ ! -e "$DEST/.appimage-side-files" && "$SIDE" != "$DEST" && -d "$SIDE" ]]; then
    for item in config.ini keybinds.ini netplay_secret saves mods/preloaded/state.toml; do
      if [[ -e "$SIDE/$item" && ! -e "$DEST/$item" ]]; then
        mkdir -p "$DEST/$(dirname "$item")"
        cp -a "$SIDE/$item" "$DEST/$item" || true
      fi
    done
    touch "$DEST/.appimage-side-files"
  fi
fi
export LD_LIBRARY_PATH="$DEST${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
# Audio client libraries (PulseAudio) that minimal systems such as WSL lack:
# without them SDL finds no sound backend and the game cannot start. Only the
# ones the system does not have are copied next to the game and appended last,
# so an installed library always wins.
if [[ -d "$APPDIR/fallback-libs" ]]; then
  LDCONFIG="$(command -v ldconfig || echo /sbin/ldconfig)"
  SYSTEM_LIBS="$("$LDCONFIG" -p 2>/dev/null | awk '/x86-64/ {print $1}' || true)"
  FALLBACK="$DEST/.fallback-libs"
  rm -rf "$FALLBACK"
  for lib in "$APPDIR"/fallback-libs/*.so*; do
    name="$(basename "$lib")"
    if ! grep -qxF "$name" <<<"$SYSTEM_LIBS"; then
      mkdir -p "$FALLBACK"
      cp "$lib" "$FALLBACK/$name"
    fi
  done
  if [[ -d "$FALLBACK" ]]; then
    export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$FALLBACK"
    echo "AppRun: using bundled $(ls "$FALLBACK" | tr '\n' ' ')" >&2
  fi
fi
# WSLg plays sound through PulseAudio over RDP; a longer buffer stops crackling.
if [[ -n "${WSL_DISTRO_NAME:-}" ]] || grep -qi microsoft /proc/sys/kernel/osrelease 2>/dev/null; then
  export PULSE_LATENCY_MSEC="${PULSE_LATENCY_MSEC:-60}"
  # WSLg's Mesa can fall back to llvmpipe (software rendering) even when the
  # GPU is exposed through /dev/dxg; the game then runs below 60 fps and the
  # sound crackles. Ask for the D3D12 driver unless the player chose one.
  if [[ -e /dev/dxg && -z "${GALLIUM_DRIVER:-}" ]]; then
    export GALLIUM_DRIVER=d3d12
  fi
fi
cd "$DEST"
HOST="$DEST/SuperBomberman5SNESRecomp"
if [[ -x "$DEST/build/SuperBomberman5SNESRecomp" ]]; then
  HOST="$DEST/build/SuperBomberman5SNESRecomp"
fi
exec "$HOST" "$@"
