#!/usr/bin/env bash
# fetch-launcher.sh — download all FjordLauncherUnlocked release assets for
# offline LAN hosting, then create stable-name symlinks for the landing page.
#
# Guests use FjordLauncherUnlocked (Prism/PolyMC fork with authlib-injector
# built in). We mirror every release asset under mirror/launcher/<tag>/ and
# maintain a `latest` symlink → <tag>. Caddy serves this at /launcher/latest/…
#
# The landing page (landing/src/data/site.ts) links to FIXED filenames so the
# links survive launcher version bumps. After download this script resolves and
# symlinks those stable names to the real versioned assets:
#   fjord-windows-setup.exe     → Windows Setup .exe (x64)
#   fjord-macos.dmg             → macOS .dmg
#   fjord-linux-x86_64.AppImage → Linux x86_64 .AppImage
#
# Cautious by design: halts on any error, and if a stable-name category matches
# 0 or >1 candidate it prints the candidates and exits non-zero rather than
# guessing. Idempotent — re-runs overwrite symlinks and re-download safely.
# mirror/ is gitignored — only this script is tracked.
set -euo pipefail

REPO="hero-persson/FjordLauncherUnlocked"
DEST_ROOT="$(dirname "$0")/../mirror/launcher"
API="https://api.github.com/repos/${REPO}/releases/latest"

command -v curl >/dev/null || { echo "curl required" >&2; exit 1; }
command -v jq   >/dev/null || { echo "jq required"   >&2; exit 1; }

meta="$(curl -fsSL "$API")"
tag="$(jq -r '.tag_name' <<<"$meta")"
[ -n "$tag" ] && [ "$tag" != "null" ] || { echo "no tag_name resolved" >&2; exit 1; }

dest="${DEST_ROOT}/${tag}"
mkdir -p "$dest"
echo "Fetching FjordLauncher ${tag} → ${dest}"

mapfile -t urls < <(jq -r '.assets[].browser_download_url' <<<"$meta")
[ "${#urls[@]}" -gt 0 ] || { echo "no assets found" >&2; exit 1; }

for url in "${urls[@]}"; do
  fname="$(basename "$url")"
  echo "  ↓ ${fname}"
  curl -fSL --retry 3 -o "${dest}/${fname}" "$url"
done

# stable symlink for the landing page to reference
ln -sfn "$tag" "${DEST_ROOT}/latest"

# --- stable-name symlinks --------------------------------------------------
# Resolve exactly one asset filename per category from the downloaded set.
# Halt (print candidates, exit 1) on 0 or >1 matches — never guess.
#
# $1 = human label, $2 = stable link name, then patterns:
#   $3 = include regex (must match), $4 = exclude regex ("" = none)
# Matching is case-insensitive against the basenames in $dest.
link_stable() {
  local label="$1" link="$2" include="$3" exclude="${4:-}"
  local -a names candidates=()
  mapfile -t names < <(cd "$dest" && ls -1)
  local n
  for n in "${names[@]}"; do
    shopt -s nocasematch
    if [[ "$n" =~ $include ]] && { [ -z "$exclude" ] || ! [[ "$n" =~ $exclude ]]; }; then
      candidates+=("$n")
    fi
    shopt -u nocasematch
  done

  if [ "${#candidates[@]}" -ne 1 ]; then
    echo "error: ${label}: expected exactly 1 candidate, found ${#candidates[@]}" >&2
    printf '  candidate: %s\n' "${candidates[@]}" >&2
    echo "  (include=/${include}/ exclude=/${exclude}/) — refusing to guess" >&2
    exit 1
  fi

  ln -sfn "${candidates[0]}" "${dest}/${link}"
  echo "  ${link} → ${candidates[0]}"
}

echo "Resolving stable-name symlinks:"
# Windows MSVC Setup .exe, x64 only (exclude arm64/aarch64 and the MinGW build).
link_stable "Windows MSVC Setup .exe (x64)" "fjord-windows-setup.exe" \
  'msvc-setup.*\.exe$' '(arm64|aarch64)'
# macOS .dmg.
link_stable "macOS .dmg" "fjord-macos.dmg" \
  '\.dmg$' ''
# Linux x86_64 .AppImage (exclude .zsync sidecar and aarch64 build).
link_stable "Linux x86_64 .AppImage" "fjord-linux-x86_64.AppImage" \
  'x86_64.*\.appimage$' '(\.zsync$|aarch64)'

echo "Done. ${#urls[@]} assets in ${dest}; stable symlinks in ${dest} (via latest/)."
