#!/usr/bin/env bash
# Ancient Orbit for Linux (Wine). Sets up an own Wine prefix with .NET 4.7.2 + fonts, installs the launcher from the
# official update server (sha256 checked) and adds an "Ancient Orbit" menu entry. The launcher then downloads and
# updates the game itself, as on Windows.
#
#   bash install-linux.sh            install (or repair) and start
#   bash install-linux.sh --start    just start
#   bash install-linux.sh --remove   remove everything this script made
set -euo pipefail

SERVER="https://backpage.ancientorbit.org"
BASE="${XDG_DATA_HOME:-$HOME/.local/share}/ancientorbit"
export WINEPREFIX="$BASE/prefix"
export WINEARCH=win64
export WINEDEBUG=-all
GAME="$WINEPREFIX/drive_c/AncientOrbit"
BIN="$HOME/.local/bin/ancientorbit"
DESKTOP="${XDG_DATA_HOME:-$HOME/.local/share}/applications/ancientorbit.desktop"

say()  { printf '\033[1;36m==>\033[0m %s\n' "$*"; }
fail() { printf '\033[1;31mError:\033[0m %s\n' "$*" >&2; exit 1; }

start_game() {
    [ -f "$GAME/AncientOrbitLauncher.exe" ] || fail "Ancient Orbit is not installed yet - run: bash install-linux.sh"
    cd "$GAME"
    exec wine AncientOrbitLauncher.exe "$@"
}

case "${1:-}" in
    --start) shift; start_game "$@" ;;
    --remove)
        say "Removing $BASE, $BIN and the menu entry"
        rm -rf "$BASE" "$BIN" "$DESKTOP"
        say "Done."
        exit 0 ;;
esac

# ---- what we need -----------------------------------------------------------------------------------------------
missing=()
for c in wine winetricks curl sha256sum; do command -v "$c" >/dev/null 2>&1 || missing+=("$c"); done
if [ ${#missing[@]} -gt 0 ]; then
    echo "Missing: ${missing[*]}"
    echo
    echo "Install them first, for example:"
    echo "  Ubuntu / Mint / Debian : sudo apt install wine64 wine32 winetricks curl"
    echo "  Fedora                 : sudo dnf install wine winetricks curl"
    echo "  Arch / Manjaro         : sudo pacman -S wine winetricks curl"
    echo "  openSUSE               : sudo zypper install wine winetricks curl"
    exit 1
fi
say "Wine: $(wine --version 2>/dev/null || echo unknown)"

# ---- the Wine prefix: .NET 4.7.2 for the launcher, the Windows fonts for the game's texts ---------------------------
mkdir -p "$BASE"
if [ ! -f "$BASE/.prefix-ready" ]; then
    say "Creating the Wine prefix in $WINEPREFIX"
    wineboot -u >/dev/null 2>&1 || true
    say "Installing .NET Framework 4.7.2 and fonts (this takes 5-15 minutes, installer windows may pop up)"
    winetricks -q --force dotnet472 corefonts tahoma || fail "winetricks failed - see the output above"
    winetricks -q win10 >/dev/null 2>&1 || true
    touch "$BASE/.prefix-ready"
else
    say "Wine prefix already set up"
fi

# ---- the launcher from the update server (it updates itself and downloads the game) --------------------------------
say "Downloading the launcher"
manifest="$(curl -fsSL "$SERVER/api/update/manifest")" || fail "could not reach $SERVER"
mkdir -p "$GAME"
for file in AncientOrbitLauncher.exe AncientOrbitLauncher.exe.config; do
    hash="$(printf '%s' "$manifest" | grep -o "\"path\":\"$file\",\"size\":[0-9]*,\"sha256\":\"[0-9a-f]*\"" | grep -o '[0-9a-f]\{64\}' | head -n1)"
    [ -n "$hash" ] || fail "$file is not in the update manifest"
    curl -fsSL "$SERVER/update/obj/$hash" -o "$GAME/$file.part" || fail "download of $file failed"
    echo "$hash  $GAME/$file.part" | sha256sum -c --status || { rm -f "$GAME/$file.part"; fail "$file: checksum mismatch"; }
    mv -f "$GAME/$file.part" "$GAME/$file"
done

# ---- start command + menu entry ----------------------------------------------------------------------------------
mkdir -p "$(dirname "$BIN")" "$(dirname "$DESKTOP")"
cat > "$BIN" <<EOF
#!/usr/bin/env bash
export WINEPREFIX="$WINEPREFIX"
export WINEARCH=win64
export WINEDEBUG=-all
cd "$GAME"
exec wine AncientOrbitLauncher.exe "\$@"
EOF
chmod +x "$BIN"
cat > "$DESKTOP" <<EOF
[Desktop Entry]
Type=Application
Name=Ancient Orbit
Comment=Ancient Orbit space MMO
Exec=$BIN
Path=$GAME
Icon=applications-games
Terminal=false
Categories=Game;
EOF
command -v update-desktop-database >/dev/null 2>&1 && update-desktop-database "$(dirname "$DESKTOP")" >/dev/null 2>&1 || true

say "Installed. Start it from your menu (Ancient Orbit) or with: $BIN"
say "Starting the launcher..."
start_game
