#!/bin/sh
# Foxora Desktop + Core installer/updater for macOS.
#
# Install or update with the same command:
#   curl -fsSL https://foxora.ai/install.sh | sh
#
# This replaces only Foxora.app. Account state, projects, sessions, Memory Den,
# and the downloaded Foxora Core under ~/.foxora are preserved. On launch the
# signed app installs, updates, or reconnects Foxora Core automatically.
set -eu

# Pinned per release. The checksums below are the asset digests GitHub reports
# for this exact tag, and the app inside the image must report VERSION as its
# CFBundleShortVersionString, so all three move together or the install aborts.
# Read the digests straight from the release rather than transcribing them:
#   gh api repos/foxora-ai/releases/releases/tags/desktop-v<version> \
#     --jq '.assets[] | "\(.name) \(.digest)"'
VERSION="5.0.4"
REPO="foxora-ai/releases"
TAG="desktop-v$VERSION"
APP_DIR="${FOXORA_APP_DIR:-/Applications}"
APP_PATH="$APP_DIR/Foxora.app"
LOCAL_DMG="${FOXORA_DMG_PATH:-}"
NO_LAUNCH="${FOXORA_NO_LAUNCH:-0}"

case "${1:-install}" in
  install|--install|update|--update) ;;
  *) echo "usage: install.sh [--install|--update]" >&2; exit 2 ;;
esac

[ "$(uname -s)" = "Darwin" ] || {
  echo "foxora: this Desktop installer currently supports macOS only" >&2
  exit 1
}

case "$(uname -m)" in
  arm64)
    # Apple Silicon gets its own image, roughly half the universal build's size.
    # Named AppleSilicon since 5.0.4; earlier releases called it aarch64.
    asset="Foxora_${VERSION}_AppleSilicon.dmg"
    expected_sha="ac2baa2f9e7c4f6fe56176d4fb83cf4ad1f9466a25aebcf89556210b859a5230"
    ;;
  x86_64)
    asset="Foxora_${VERSION}_universal.dmg"
    expected_sha="edd3fbe8530be9678ebdf0d8143b003d60d91bd05bba1eb86962e2ec7e9085af"
    ;;
  *) echo "foxora: unsupported Mac architecture $(uname -m)" >&2; exit 1 ;;
esac

for command in curl hdiutil ditto shasum spctl osascript open; do
  command -v "$command" >/dev/null 2>&1 || {
    echo "foxora: required macOS command is missing: $command" >&2
    exit 1
  }
done

tmp="$(mktemp -d "${TMPDIR:-/tmp}/foxora-install.XXXXXX")"
mount_dir="$tmp/mount"
dmg="$tmp/$asset"
mounted=0
cleanup() {
  if [ "$mounted" -eq 1 ]; then hdiutil detach "$mount_dir" -quiet >/dev/null 2>&1 || true; fi
  rm -rf "$tmp"
}
trap cleanup EXIT INT TERM

if [ -n "$LOCAL_DMG" ]; then
  [ -f "$LOCAL_DMG" ] || { echo "foxora: FOXORA_DMG_PATH does not exist" >&2; exit 1; }
  cp "$LOCAL_DMG" "$dmg"
else
  url="https://github.com/$REPO/releases/download/$TAG/$asset"
  echo "foxora: downloading Foxora $VERSION for $(uname -m)…"
  curl -fL --retry 3 --connect-timeout 15 --progress-bar "$url" -o "$dmg"
fi

actual_sha="$(shasum -a 256 "$dmg" | awk '{print $1}')"
[ "$actual_sha" = "$expected_sha" ] || {
  echo "foxora: installer checksum mismatch — refusing to install" >&2
  exit 1
}

spctl -a -t install "$dmg" >/dev/null 2>&1 || {
  echo "foxora: macOS rejected the installer signature" >&2
  exit 1
}

mkdir -p "$mount_dir"
hdiutil attach "$dmg" -mountpoint "$mount_dir" -nobrowse -readonly -quiet
mounted=1
[ -d "$mount_dir/Foxora.app" ] || { echo "foxora: Foxora.app is missing from the installer" >&2; exit 1; }

bundle_version="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleShortVersionString' "$mount_dir/Foxora.app/Contents/Info.plist")"
[ "$bundle_version" = "$VERSION" ] || {
  echo "foxora: expected app $VERSION, found $bundle_version" >&2
  exit 1
}
spctl -a "$mount_dir/Foxora.app" >/dev/null 2>&1 || {
  echo "foxora: macOS rejected the Foxora app signature" >&2
  exit 1
}

if [ -d "$APP_PATH" ]; then
  echo "foxora: replacing existing Foxora.app (your ~/.foxora data stays intact)…"
  osascript -e 'tell application "Foxora" to quit' >/dev/null 2>&1 || true
  sleep 2
else
  echo "foxora: installing Foxora.app…"
fi

stage="$APP_DIR/.Foxora.app.install.$$"
install_without_sudo() {
  mkdir -p "$APP_DIR" 2>/dev/null || return 1
  rm -rf "$stage"
  ditto "$mount_dir/Foxora.app" "$stage" || return 1
  rm -rf "$APP_PATH" || return 1
  mv "$stage" "$APP_PATH"
}

if ! install_without_sudo; then
  command -v sudo >/dev/null 2>&1 || {
    echo "foxora: $APP_DIR requires administrator access and sudo is unavailable" >&2
    exit 1
  }
  echo "foxora: administrator approval is required for $APP_DIR"
  sudo mkdir -p "$APP_DIR"
  sudo rm -rf "$stage"
  sudo ditto "$mount_dir/Foxora.app" "$stage"
  sudo rm -rf "$APP_PATH"
  sudo mv "$stage" "$APP_PATH"
fi

hdiutil detach "$mount_dir" -quiet
mounted=0

echo "foxora: Foxora Desktop $VERSION installed successfully."
echo "foxora: your account, projects, sessions, and Memory Den were preserved."
if [ "$NO_LAUNCH" != "1" ]; then
  open "$APP_PATH"
  echo "foxora: launching Foxora — Core will install/update and connect automatically."
fi
