#!/usr/bin/env bash
set -euo pipefail

repo_dir="$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd -P)"
# shellcheck disable=SC1091
. "$repo_dir/config/node-runtime.env"

runtime_root="$repo_dir/.runtime"
mkdir -p "$runtime_root/downloads"

os_name="$(uname -s)"
cpu_name="$(uname -m)"
case "$os_name:$cpu_name" in
  Linux:x86_64|Linux:amd64) platform=linux; arch=x64; archive_ext=tar.xz; checksum="$NODE_LINUX_X64_SHA256" ;;
  Linux:aarch64|Linux:arm64) platform=linux; arch=arm64; archive_ext=tar.xz; checksum="$NODE_LINUX_ARM64_SHA256" ;;
  Darwin:x86_64|Darwin:amd64) platform=darwin; arch=x64; archive_ext=tar.gz; checksum="$NODE_DARWIN_X64_SHA256" ;;
  Darwin:arm64|Darwin:aarch64) platform=darwin; arch=arm64; archive_ext=tar.gz; checksum="$NODE_DARWIN_ARM64_SHA256" ;;
  *)
    echo "Unsupported project runtime platform: $os_name/$cpu_name (use Node $NODE_VERSION manually on this host)." >&2
    exit 2
    ;;
esac

archive_name="node-v${NODE_VERSION}-${platform}-${arch}.${archive_ext}"
archive_path="$runtime_root/downloads/$archive_name"
runtime_dir="$runtime_root/node-v${NODE_VERSION}-${platform}-${arch}"
resource_home="${WEB_FREECAD_RESOURCE_LIBRARY:-${HOME}/resource-library/web-freecad-bitbybit}"
resource_archive="$resource_home/toolchains/node/$archive_name"

if [ -x "$runtime_dir/bin/node" ] && [ "$($runtime_dir/bin/node --version)" = "v$NODE_VERSION" ]; then
  printf '%s\n' "$runtime_dir"
  exit 0
fi

if [ -e "$archive_path" ]; then
  if command -v sha256sum >/dev/null 2>&1; then
    actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')"
  else
    actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')"
  fi
  if [ "$actual_checksum" != "$checksum" ]; then
    rm -f "$archive_path"
  fi
fi

if [ ! -e "$archive_path" ] && [ -e "$resource_archive" ]; then
  cp "$resource_archive" "$archive_path"
fi

if [ ! -e "$archive_path" ] && { [ "${WEB_FREECAD_OFFLINE:-0}" = "1" ] || [ "${npm_config_offline:-false}" = "true" ]; }; then
  echo "Pinned Node archive is unavailable in the offline resource library: $resource_archive" >&2
  exit 2
fi

if [ ! -e "$archive_path" ]; then
  temp_archive="$archive_path.part"
  rm -f "$temp_archive"
  if ! command -v curl >/dev/null 2>&1; then
    echo "curl is required to bootstrap the project-local Node runtime." >&2
    exit 2
  fi
  curl --fail --location --retry 3 --output "$temp_archive" "$NODE_DIST_BASE/$archive_name"
  if command -v sha256sum >/dev/null 2>&1; then
    actual_checksum="$(sha256sum "$temp_archive" | awk '{print $1}')"
  else
    actual_checksum="$(shasum -a 256 "$temp_archive" | awk '{print $1}')"
  fi
  if [ "$actual_checksum" != "$checksum" ]; then
    rm -f "$temp_archive"
    echo "SHA-256 verification failed for $archive_name." >&2
    exit 3
  fi
  mv "$temp_archive" "$archive_path"
fi

if command -v sha256sum >/dev/null 2>&1; then
  actual_checksum="$(sha256sum "$archive_path" | awk '{print $1}')"
else
  actual_checksum="$(shasum -a 256 "$archive_path" | awk '{print $1}')"
fi
if [ "$actual_checksum" != "$checksum" ]; then
  echo "Cached Node archive checksum does not match the pinned value." >&2
  exit 3
fi

extract_dir="$(mktemp -d "$runtime_root/extract.XXXXXX")"
cleanup() { rm -rf "$extract_dir"; }
trap cleanup EXIT
tar -xf "$archive_path" -C "$extract_dir"
extracted_dir="$extract_dir/node-v${NODE_VERSION}-${platform}-${arch}"
if [ ! -x "$extracted_dir/bin/node" ]; then
  echo "Node archive did not contain the expected executable." >&2
  exit 4
fi
rm -rf "$runtime_dir"
mv "$extracted_dir" "$runtime_dir"
if [ "$($runtime_dir/bin/node --version)" != "v$NODE_VERSION" ]; then
  echo "Bootstrapped Node version is not v$NODE_VERSION." >&2
  exit 4
fi
printf '%s\n' "$runtime_dir"
