#!/bin/sh
# VIA Quick setup — development candidate. Not a public installer.
set -eu
umask 077

NODE_VERSION="v24.21.0"
BASE_URL="https://nodejs.org/dist/${NODE_VERSION}"
VIA_PACKAGE="@thevia/via@latest"

usage() {
  printf '%s\n' "VIA Quick setup (development candidate)" \
    "Usage: sh quick-setup.sh [--verify-only|--help]" \
    "Default: prepare private Node.js and run the existing VIA setup." \
    "--verify-only: check runtime provisioning without running VIA setup."
}

case "${1:-}" in
  --help|-h) usage; exit 0 ;;
  --verify-only) VERIFY_ONLY=1 ;;
  "") VERIFY_ONLY=0 ;;
  *) usage >&2; exit 2 ;;
esac
if [ "$#" -gt 1 ]; then usage >&2; exit 2; fi
if [ "$(id -u)" -eq 0 ]; then
  echo "VIA must be installed as the intended ordinary user, not root." >&2
  exit 1
fi
for cmd in uname tar curl awk mktemp; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "Required tool not found: $cmd" >&2
    exit 1
  fi
done
machine="$(uname -m)"
case "$machine" in
  x86_64|amd64) arch=x64 ;;
  aarch64|arm64) arch=arm64 ;;
  *) echo "Unsupported processor: $machine" >&2; exit 1 ;;
esac
case "$(uname -s)" in
  Linux)
    platform=linux; extension=tar.xz
    case "$arch" in
      x64) expected="fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6" ;;
      arm64) expected="6ad1325edbdb5649c379b75a237147a666c95d4f9ae8d340fef2d1575d289ad2" ;;
    esac
    ;;
  Darwin)
    platform=darwin; extension=tar.gz
    case "$arch" in
      x64) expected="1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097" ;;
      arm64) expected="bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057" ;;
    esac
    ;;
  *) echo "This installer runs only on Linux and macOS." >&2; exit 1 ;;
esac
filename="node-${NODE_VERSION}-${platform}-${arch}.${extension}"
url="${BASE_URL}/${filename}"
if [ -n "${XDG_DATA_HOME:-}" ]; then
  case "$XDG_DATA_HOME" in
    /*) base="$XDG_DATA_HOME/via/quick-setup" ;;
    *) echo "XDG_DATA_HOME must be absolute" >&2; exit 1 ;;
  esac
elif [ "$platform" = darwin ]; then
  base="$HOME/Library/Application Support/VIA/QuickSetup"
else
  base="$HOME/.local/share/via/quick-setup"
fi
runtime="${base}/node-${NODE_VERSION}-${platform}-${arch}"
node="${runtime}/bin/node"
npx_js="${runtime}/lib/node_modules/npm/bin/npx-cli.js"
archive_cache="${base}/${filename}"
mkdir -p "$base"
chmod 700 "$base"

# Do not trust a previously extracted Node/npm directory via a writable marker.
# The per-user lock is held through the CLI invocation.
lock="${base}/.quick-setup.lock"
if ! mkdir "$lock" 2>/dev/null; then
  echo "Another VIA Quick setup is already running (or left a stale lock)." >&2
  exit 1
fi
stage=""
cleanup() {
  if [ -n "$stage" ]; then rm -rf "$stage"; fi
  rmdir "$lock" 2>/dev/null || :
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

hash_file() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum "$1" | awk '{print $1}'
  elif command -v shasum >/dev/null 2>&1; then
    shasum -a 256 "$1" | awk '{print $1}'
  else
    echo "SHA-256 tool missing." >&2
    return 1
  fi
}
if [ -L "$archive_cache" ]; then rm "$archive_cache"; fi
if [ ! -f "$archive_cache" ] || [ "$(hash_file "$archive_cache")" != "$expected" ]; then
  echo "[VIA] Downloading official Node.js ${NODE_VERSION} (${platform}/${arch})..."
  stage="$(mktemp -d "${base}/.incoming.XXXXXXXX")"
  curl --proto '=https' --tlsv1.2 --fail --location --silent --show-error --retry 2 \
    --output "${stage}/${filename}" "$url"
  if [ "$(hash_file "${stage}/${filename}")" != "$expected" ]; then
    echo "Node.js checksum verification failed; refusing to execute." >&2
    exit 1
  fi
  mv -f "${stage}/${filename}" "$archive_cache"
  rm -rf "$stage"
  stage=""
fi

# Rebuild the runtime from the pinned, verified archive on every invocation.
# This detects modification of the cached Node executable, npm or its modules.
stage="$(mktemp -d "${base}/.incoming.XXXXXXXX")"
mkdir -p "${stage}/payload"
case "$extension" in
  tar.xz) tar -xJf "$archive_cache" -C "${stage}/payload" --strip-components=1 ;;
  tar.gz) tar -xzf "$archive_cache" -C "${stage}/payload" --strip-components=1 ;;
esac
candidate="${stage}/payload"
[ -f "${candidate}/bin/node" ] && [ -f "${candidate}/lib/node_modules/npm/bin/npx-cli.js" ] || {
  echo "Verified Node.js bundle is missing required files." >&2
  exit 1
}
[ "$("${candidate}/bin/node" --version)" = "$NODE_VERSION" ] || {
  echo "Unexpected Node.js version in verified archive." >&2
  exit 1
}
printf '%s\n' "$expected" > "${candidate}/.via-archive-sha256"
previous="${stage}/previous"
if [ -e "$runtime" ] || [ -L "$runtime" ]; then mv "$runtime" "$previous"; fi
if ! mv "$candidate" "$runtime"; then
  if [ -e "$previous" ] || [ -L "$previous" ]; then mv "$previous" "$runtime"; fi
  echo "Could not activate verified Node.js runtime." >&2
  exit 1
fi
if [ -e "$previous" ] || [ -L "$previous" ]; then rm -rf "$previous"; fi
rm -rf "$stage"
stage=""
if [ "$VERIFY_ONLY" -eq 1 ]; then
  echo "[VIA] Verified runtime ready: ${NODE_VERSION} (${platform}/${arch}); VIA setup NOT invoked."
  exit 0
fi
echo "[VIA] Starting official VIA bootstrap..."
# Avoid accidentally executing a local project's shadowed `via` binary.
cd "$base"
PATH="${runtime}/bin:${PATH}"
unset NODE_OPTIONS NODE_PATH NODE_EXTRA_CA_CERTS LD_PRELOAD LD_LIBRARY_PATH DYLD_INSERT_LIBRARIES
NODE_TLS_REJECT_UNAUTHORIZED=1
npm_config_cache="${base}/npm-cache"
npm_config_userconfig=/dev/null
npm_config_registry="https://registry.npmjs.org/"
npm_config_strict_ssl=true
export PATH NODE_TLS_REJECT_UNAUTHORIZED npm_config_cache npm_config_userconfig npm_config_registry npm_config_strict_ssl
"$node" "$npx_js" --yes "$VIA_PACKAGE" setup
