#!/usr/bin/env bash
# install-native.sh — build release of ltk + crustace + forge and install
# them as a system Wayland session so the display manager (GDM/SDDM)
# shows "Crustace" in its session dropdown. Idempotent; safe to re-run
# after pulling new commits. Tested on Fedora 41/42 (mutable /usr).
#
# Logs everything to /tmp/install-forge.log so a botched run can be
# diagnosed after the fact.
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
LOG="/tmp/install-forge.log"
LTK_SHARE="/usr/share/ltk-themes"

# Everything below is mirrored to $LOG without losing the live tty output.
exec > >(tee -a "$LOG") 2>&1
echo
echo "==> install-native.sh starting at $(date -u +%FT%TZ)"
echo "    log: $LOG"
echo

# ── pre-flight ────────────────────────────────────────────────────────────────
[ -d "$HERE/forge"    ] || { echo "ERROR: $HERE/forge not found"    >&2; exit 1; }
[ -d "$HERE/crustace" ] || { echo "ERROR: $HERE/crustace not found" >&2; exit 1; }
[ -d "$HERE/ltk"      ] || { echo "ERROR: $HERE/ltk not found"      >&2; exit 1; }

if ! command -v cargo >/dev/null; then
    echo "ERROR: cargo not in PATH. Install rustup or fedora's rust package." >&2
    exit 1
fi

# Refuse to run as root: we want the build artefacts to be owned by the
# normal user; only the install steps escalate with sudo.
if [ "$(id -u)" -eq 0 ]; then
    echo "ERROR: don't run this script as root. It will sudo for install steps." >&2
    exit 1
fi

# Prime sudo once up front so the user types their password at the very
# start and isn't prompted again mid-build.
echo "==> sudo will be required for the install steps below."
sudo -v
( while true; do sudo -nv; sleep 60; done; ) 2>/dev/null &
SUDO_KEEPALIVE_PID=$!
trap '[ -n "${SUDO_KEEPALIVE_PID:-}" ] && kill "$SUDO_KEEPALIVE_PID" 2>/dev/null || true' EXIT

# ── build ─────────────────────────────────────────────────────────────────────
# ltk is a path-dep of crustace and forge — cargo picks it up automatically.
# We don't `cargo build` it separately because its release artifacts aren't
# what gets installed (forge / crustace static-link against it).
echo "==> Building crustace (release)..."
cargo build --release --manifest-path "$HERE/crustace/Cargo.toml" \
    2>&1 | grep -E "^error|^Compiling|^Finished|^error\[" || true

echo "==> Building forge   (release, --features winit)..."
# winit feature stays on even for the native install so the same binary
# can also be used for nested-winit testing via `forge --winit`.
cargo build --release --features winit --manifest-path "$HERE/forge/Cargo.toml" \
    2>&1 | grep -E "^error|^Compiling|^Finished|^error\[" || true

[ -x "$HERE/forge/target/release/forge"       ] || { echo "ERROR: forge release binary missing"    >&2; exit 1; }
[ -x "$HERE/crustace/target/release/crustace" ] || { echo "ERROR: crustace release binary missing" >&2; exit 1; }
echo "==> Build OK"
echo

# ── install ───────────────────────────────────────────────────────────────────
echo "==> sudo make install (forge)..."
sudo make -C "$HERE/forge" install

echo "==> sudo make install (crustace)..."
sudo make -C "$HERE/crustace" install

# crustace-session.sh needs to find the LTK theme assets at runtime.
# The packaged paths default to /usr/share/ltk-themes; mirror the in-tree
# themes there so the installed session matches what we develop against.
echo "==> Mirroring ltk themes → $LTK_SHARE"
sudo install -d "$LTK_SHARE"
sudo cp -r --no-preserve=ownership "$HERE/ltk/themes/." "$LTK_SHARE/"

# Inject LTK_THEMES_DIR into the installed session launcher if it's not
# already exported there — without this the installed crustace falls back
# to a built-in monochrome theme on a fresh system.
SESSION="/usr/bin/crustace-session"
if [ -f "$SESSION" ] && ! grep -q 'LTK_THEMES_DIR' "$SESSION"; then
    echo "==> Patching $SESSION to export LTK_THEMES_DIR=$LTK_SHARE"
    sudo sed -i "/^export XDG_CURRENT_DESKTOP/i export LTK_THEMES_DIR=$LTK_SHARE" "$SESSION"
fi

# ── verify ────────────────────────────────────────────────────────────────────
echo
echo "==> Verifying install..."
ok=true
for f in /usr/bin/forge /usr/bin/crustace /usr/bin/crustace-session \
         /usr/share/wayland-sessions/crustace.desktop \
         /usr/share/crustace/session-init ; do
    if [ -e "$f" ]; then
        printf '    OK  %s\n' "$f"
    else
        printf '    !!  MISSING %s\n' "$f"
        ok=false
    fi
done
$ok || { echo "ERROR: install incomplete, see above" >&2; exit 1; }

echo
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "  Install complete."
echo
echo "  Next steps:"
echo "    1. Log out of the current GNOME session."
echo "    2. In the greeter (bottom-right gear icon), choose 'Crustace'."
echo "    3. Log in as usual."
echo
echo "  Recovery:"
echo "    - GNOME stays in the session dropdown — pick it again to revert."
echo "    - If forge hangs at login, switch to a text TTY (Ctrl+Alt+F3) and"
echo "      run 'pkill -9 forge crustace' then return with Ctrl+Alt+F1/F2."
echo "    - 'cd $HERE/forge && sudo make uninstall' (also do crustace)"
echo "      followed by 'sudo rm /usr/share/wayland-sessions/crustace.desktop'"
echo "      reverts the install entirely."
echo
echo "  Log: $LOG"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
