#!/usr/bin/env bash
# Arcanum Nexus — universal Linux installer for Arcanum Imperium
#
# Works on Ubuntu/Debian (apt), Fedora/RHEL (dnf), Arch (pacman),
# openSUSE (zypper), and any distro with libfuse2 available.
#
# What it does:
#   1. Detects distro and installs libfuse2 if missing (required by AppImage)
#   2. Fetches latest version metadata from arcanum-nexus.com
#   3. Downloads the .AppImage to ~/.local/bin/
#   4. Verifies SHA-256
#   5. Makes it executable
#   6. Extracts icon and creates a .desktop entry (so the game appears in your
#      application launcher / menu)
#   7. Optionally launches the game
#
# Usage:
#   curl -fsSL https://arcanum-nexus.com/games/install/imperium.sh | bash
#
# Non-interactive flags:
#   ARCANUM_NO_LAUNCH=1   skip the "launch now" prompt
#   ARCANUM_NO_FUSE=1     skip the libfuse2 install step (you handle it)
#   ARCANUM_PREFIX=/some  install AppImage under this dir instead of ~/.local

set -euo pipefail

# ── Game-specific variables (substituted at deploy time) ────────────────
GAME="imperium"
GAME_TITLE="Arcanum Imperium"
GAME_COMMENT="2D real-time strategy by Arcanum Nexus"
CDN_HOST="https://arcanum-nexus.com"

# ── Output helpers ─────────────────────────────────────────────────────
TTY_OK=0; [ -t 1 ] && TTY_OK=1
c_blue()   { [ "$TTY_OK" = 1 ] && printf '\033[1;34m%s\033[0m\n' "$*" || printf '%s\n' "$*"; }
c_green()  { [ "$TTY_OK" = 1 ] && printf '\033[1;32m%s\033[0m\n' "$*" || printf '%s\n' "$*"; }
c_yellow() { [ "$TTY_OK" = 1 ] && printf '\033[1;33m%s\033[0m\n' "$*" || printf '%s\n' "$*"; }
c_red()    { [ "$TTY_OK" = 1 ] && printf '\033[1;31m%s\033[0m\n' "$*" >&2 || printf '%s\n' "$*" >&2; }
die()      { c_red "$*"; exit 1; }

trap 'c_red "==> Aborted on error (line $LINENO)."' ERR

# ── Banner ─────────────────────────────────────────────────────────────
c_blue "═══════════════════════════════════════════════"
c_blue "   Arcanum Nexus — ${GAME_TITLE}"
c_blue "   Universal Linux installer (AppImage)"
c_blue "═══════════════════════════════════════════════"
echo

# ── Sanity ─────────────────────────────────────────────────────────────
command -v curl     >/dev/null || die "curl is required. Install it first (e.g. 'sudo apt install curl')."
command -v chmod    >/dev/null || die "chmod missing — broken environment?"
command -v mktemp   >/dev/null || die "mktemp missing."

# ── 1. Detect distro ───────────────────────────────────────────────────
DISTRO="unknown"
PKG_FAMILY="unknown"
if [ -r /etc/os-release ]; then
    # shellcheck disable=SC1091
    . /etc/os-release
    DISTRO="${ID:-unknown}"
    case "${ID_LIKE:-}${ID:-}" in
        *debian*|*ubuntu*)             PKG_FAMILY="debian";;
        *fedora*|*rhel*|*centos*)      PKG_FAMILY="rpm";;
        *arch*|*manjaro*)              PKG_FAMILY="arch";;
        *suse*|*opensuse*)             PKG_FAMILY="suse";;
    esac
fi
c_yellow "Distro:    ${DISTRO}"
c_yellow "Pkg fam:   ${PKG_FAMILY}"

# ── 2. Ensure libfuse2 is available (AppImage runtime dep) ────────────
need_fuse2() {
    # FUSE3 systems still need libfuse.so.2 for older AppImages.
    if ldconfig -p 2>/dev/null | grep -q 'libfuse\.so\.2'; then return 1; fi
    if [ -e /usr/lib/x86_64-linux-gnu/libfuse.so.2 ] \
       || [ -e /usr/lib64/libfuse.so.2 ] \
       || [ -e /usr/lib/libfuse.so.2 ]; then return 1; fi
    return 0
}

if [ -z "${ARCANUM_NO_FUSE:-}" ] && need_fuse2; then
    c_yellow "==> libfuse2 not found — required by AppImage runtime."
    SUDO=""
    if [ "$(id -u)" != "0" ]; then
        if command -v sudo >/dev/null; then SUDO="sudo"
        else die "Root or sudo required to install libfuse2. Re-run as root, install libfuse2 manually, or set ARCANUM_NO_FUSE=1 and install it yourself."
        fi
    fi
    case "${PKG_FAMILY}" in
        debian) $SUDO apt-get update -qq && $SUDO apt-get install -y libfuse2 ;;
        rpm)
            if command -v dnf >/dev/null; then $SUDO dnf install -y fuse fuse-libs
            else $SUDO yum install -y fuse fuse-libs; fi ;;
        arch)   $SUDO pacman -S --noconfirm --needed fuse2 ;;
        suse)   $SUDO zypper -n install fuse libfuse2 ;;
        *)
            c_red "Cannot install libfuse2 automatically on ${DISTRO}."
            c_red "Install 'libfuse2' / 'fuse' (FUSE 2.x) manually, then re-run."
            exit 2 ;;
    esac
    c_green "libfuse2 installed."
else
    c_green "libfuse2 OK."
fi

# ── 3. Fetch metadata ──────────────────────────────────────────────────
c_blue "==> Fetching latest version..."
META_URL="${CDN_HOST}/games/dist/${GAME}/latest.json"
META=$(curl -fsSL --retry 3 --retry-delay 1 "${META_URL}") \
    || die "Cannot reach ${META_URL}"

extract() { printf '%s' "$META" | python3 -c "
import json, sys
d = json.load(sys.stdin)
keys = '$1'.split('.')
cur = d
for k in keys:
    cur = cur.get(k) if isinstance(cur, dict) else None
    if cur is None: break
print(cur if cur is not None else '')
" 2>/dev/null; }

# Fallback to sed if python3 missing
if ! command -v python3 >/dev/null; then
    extract() { printf '%s' "$META" | tr ',' '\n' | sed -nE "s/.*\"$1\": *\"([^\"]+)\".*/\1/p" | head -1; }
fi

VERSION=$(extract version)
URL_PATH=$(extract platform.linux.url)
FILENAME=$(extract platform.linux.filename)
SHA=$(extract platform.linux.sha256)
SIZE=$(extract platform.linux.size)

[ -n "$URL_PATH" ] && [ -n "$FILENAME" ] || die "No Linux build registered in latest.json yet."

DOWNLOAD_URL="${CDN_HOST}${URL_PATH}"
c_green "  version:  ${VERSION}"
c_green "  file:     ${FILENAME}"
c_green "  size:     $((SIZE / 1024 / 1024)) MB"
c_green "  sha256:   ${SHA:0:16}…${SHA: -8}"

# ── 4. Install paths ───────────────────────────────────────────────────
PREFIX="${ARCANUM_PREFIX:-$HOME/.local}"
INSTALL_DIR="${PREFIX}/bin"
DESKTOP_DIR="${HOME}/.local/share/applications"
ICON_DIR="${HOME}/.local/share/icons/hicolor/256x256/apps"
mkdir -p "${INSTALL_DIR}" "${DESKTOP_DIR}" "${ICON_DIR}"

DEST="${INSTALL_DIR}/${FILENAME}"
STABLE="${INSTALL_DIR}/arcanum-${GAME}.AppImage"  # version-less symlink

# ── 5. Download ───────────────────────────────────────────────────────
c_blue "==> Downloading to ${DEST}..."
if [ -f "${DEST}" ] && [ -n "${SHA}" ] && command -v sha256sum >/dev/null; then
    if [ "$(sha256sum "${DEST}" | awk '{print $1}')" = "${SHA}" ]; then
        c_yellow "  Already downloaded and matches sha — skipping."
    else
        rm -f "${DEST}"
    fi
fi
[ -f "${DEST}" ] || curl -fL --progress-bar "${DOWNLOAD_URL}" -o "${DEST}"

# ── 6. Verify SHA-256 ──────────────────────────────────────────────────
if [ -n "${SHA}" ] && command -v sha256sum >/dev/null; then
    c_blue "==> Verifying SHA-256..."
    ACTUAL=$(sha256sum "${DEST}" | awk '{print $1}')
    [ "${ACTUAL}" = "${SHA}" ] || die "SHA-256 mismatch! Expected ${SHA}, got ${ACTUAL}"
    c_green "  Checksum verified."
fi

# ── 7. Make executable + stable symlink ────────────────────────────────
chmod +x "${DEST}"
ln -sfn "${DEST}" "${STABLE}"
c_green "==> Installed: ${DEST}"
c_green "    Stable link: ${STABLE}"

# ── 8. Extract icon ────────────────────────────────────────────────────
ICON=""
TMPDIR=$(mktemp -d)
(
    cd "${TMPDIR}"
    "${DEST}" --appimage-extract '*.png' >/dev/null 2>&1 || true
    if [ -f squashfs-root/.DirIcon ]; then
        cp -L squashfs-root/.DirIcon "${ICON_DIR}/arcanum-${GAME}.png" 2>/dev/null || true
    elif ls squashfs-root/usr/share/icons/hicolor/*/apps/*.png >/dev/null 2>&1; then
        cp "$(ls -S squashfs-root/usr/share/icons/hicolor/*/apps/*.png | head -1)" \
           "${ICON_DIR}/arcanum-${GAME}.png" 2>/dev/null || true
    elif ls squashfs-root/*.png >/dev/null 2>&1; then
        cp "$(ls -S squashfs-root/*.png | head -1)" \
           "${ICON_DIR}/arcanum-${GAME}.png" 2>/dev/null || true
    fi
    rm -rf squashfs-root
)
rm -rf "${TMPDIR}"
if [ -f "${ICON_DIR}/arcanum-${GAME}.png" ]; then
    ICON="${ICON_DIR}/arcanum-${GAME}.png"
    c_green "==> Icon installed: ${ICON}"
fi

# ── 9. Create .desktop entry ───────────────────────────────────────────
DESKTOP="${DESKTOP_DIR}/arcanum-${GAME}.desktop"
cat > "${DESKTOP}" <<EOF
[Desktop Entry]
Type=Application
Name=${GAME_TITLE}
Comment=${GAME_COMMENT}
GenericName=Game
Exec=${STABLE}
Icon=${ICON:-arcanum-${GAME}}
Terminal=false
Categories=Game;
StartupNotify=true
StartupWMClass=${GAME_TITLE}
X-Arcanum-Game=${GAME}
X-Arcanum-Version=${VERSION}
EOF
chmod +x "${DESKTOP}"
c_green "==> Menu entry: ${DESKTOP}"

if command -v update-desktop-database >/dev/null; then
    update-desktop-database "${DESKTOP_DIR}" 2>/dev/null || true
fi
if command -v gtk-update-icon-cache >/dev/null && [ -n "${ICON}" ]; then
    gtk-update-icon-cache "$HOME/.local/share/icons/hicolor" -t 2>/dev/null || true
fi

# ── 10. PATH advice ────────────────────────────────────────────────────
case ":${PATH}:" in
    *":${INSTALL_DIR}:"*) ;;
    *)
        c_yellow "==> Note: ${INSTALL_DIR} is not in your PATH."
        c_yellow "    Add this to your ~/.bashrc / ~/.zshrc:"
        c_yellow "        export PATH=\"${INSTALL_DIR}:\$PATH\""
        c_yellow "    Or run by full path: ${STABLE}" ;;
esac

# ── 11. Launch ─────────────────────────────────────────────────────────
echo
c_green "═══════════════════════════════════════════════"
c_green "  Install complete."
c_green "  Launch from your menu, or run:"
c_green "    ${STABLE}"
c_green "═══════════════════════════════════════════════"

if [ -z "${ARCANUM_NO_LAUNCH:-}" ] && [ -e /dev/tty ]; then
    echo
    printf "Launch %s now? [Y/n] " "${GAME_TITLE}" > /dev/tty
    read -r yn < /dev/tty || yn=""
    case "${yn}" in
        [Nn]*) c_blue "OK — start later via the menu or '${STABLE}'." ;;
        *)     c_blue "Launching..."; setsid -f "${STABLE}" </dev/null >/dev/null 2>&1 || "${STABLE}" & ;;
    esac
fi
