#!/bin/sh
# Launcher script for the `agenshield` npm wrapper package.
# Resolves the correct platform-specific binary from optionalDependencies
# and executes it with all arguments forwarded.
#
# Installed as `bin/agenshield` in the wrapper package.

set -e

# Detect platform
case "$(uname -s)" in
  Darwin) OS="darwin" ;;
  Linux)  OS="linux" ;;
  *)      echo "Unsupported platform: $(uname -s)" >&2; exit 1 ;;
esac

case "$(uname -m)" in
  x86_64|amd64)   ARCH="x64" ;;
  aarch64|arm64)   ARCH="arm64" ;;
  *)               echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
esac

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PLATFORM_DIR="${OS}-${ARCH}"
PKG="@agenshield/cli-${PLATFORM_DIR}"
BIN=""
PKG_ROOT=""

# Wrapper version. Forwarded to the platform binary via
# AGENSHIELD_NPX_PACKAGE_VERSION so getVersion() can report what the user
# actually invoked (`npx agenshield@<v>`), regardless of whether the
# resolved platform binary's embedded VERSION asset matches. Without this,
# `npx agenshield@<new> upgrade` could compare against a stale binary's
# baked-in version and silently no-op as "already at version <old>".
WRAPPER_PKG_JSON="$SCRIPT_DIR/../package.json"
WRAPPER_VERSION=""
if [ -f "$WRAPPER_PKG_JSON" ]; then
  # Prefer node — guaranteed present for npx and immune to minified JSON.
  # The earlier awk-only parser silently returned the wrong field when
  # the package.json was on a single line (npm/yarn sometimes reformat
  # before publish), which let `npx agenshield@<v>` boot with an empty
  # WRAPPER_VERSION and silently no-op `upgrade` as "already at <old>".
  if command -v node >/dev/null 2>&1; then
    WRAPPER_VERSION=$(node -e "try{process.stdout.write(String(JSON.parse(require('fs').readFileSync(process.argv[1],'utf8')).version||''))}catch(_){}" "$WRAPPER_PKG_JSON" 2>/dev/null || true)
  fi
  # awk fallback for non-node environments (direct shell invocation,
  # `agenshield` symlink dragged outside npx, etc.). Multi-line JSON only.
  if [ -z "$WRAPPER_VERSION" ]; then
    WRAPPER_VERSION=$(/usr/bin/awk -F'"' '/"version"/ { print $4; exit }' "$WRAPPER_PKG_JSON" 2>/dev/null || true)
  fi
fi

# 1. Local dist layout: dist/npm/agenshield/bin/ → ../../darwin-arm64/
DIST_DIR="$SCRIPT_DIR/../../${PLATFORM_DIR}"
if [ -x "$DIST_DIR/bin/agenshield" ]; then
  BIN="$DIST_DIR/bin/agenshield"
  PKG_ROOT="$DIST_DIR"
fi

# 2. Flat-hoisted npm install (npm 7+, npx default):
#    node_modules/agenshield/bin/agenshield  (this launcher)
#    node_modules/@agenshield/cli-<platform>/bin/agenshield  (sibling, hoisted)
if [ -z "$BIN" ]; then
  HOIST_DIR="$SCRIPT_DIR/../../$PKG"
  if [ -x "$HOIST_DIR/bin/agenshield" ]; then
    BIN="$HOIST_DIR/bin/agenshield"
    PKG_ROOT="$HOIST_DIR"
  fi
fi

# 3. Nested npm install (legacy / --legacy-peer-deps):
#    node_modules/agenshield/node_modules/@agenshield/cli-<platform>/...
if [ -z "$BIN" ]; then
  NPM_DIR="$SCRIPT_DIR/../node_modules/$PKG"
  if [ -x "$NPM_DIR/bin/agenshield" ]; then
    BIN="$NPM_DIR/bin/agenshield"
    PKG_ROOT="$NPM_DIR"
  fi
fi

# Surface the wrapper version to the binary. Read by getVersion() in
# libs/cli/src/utils/version.ts — preferred over the SEA asset so
# `npx agenshield@<v>` always reports <v>, even when the resolved binary
# was hoisted/cached/symlinked from a different version.
if [ -n "$WRAPPER_VERSION" ]; then
  export AGENSHIELD_NPX_PACKAGE_VERSION="$WRAPPER_VERSION"
fi

if [ -n "$BIN" ]; then
  exec "$BIN" "$@"
fi

# 4. PATH fallback. Reached when optionalDeps silently failed to install
#    (most common cause: root-owned files in ~/.npm cache from a prior
#    `sudo npx`, so npm can't write the unpack and skips it without
#    erroring). Without this fallback, npx exits 1, then npm-exec
#    silently runs whatever `agenshield` is on PATH — typically a stale
#    .pkg-installed binary that PRECEDES the env-var support, so
#    `npx agenshield@<new>` reports the OLD installed version and the
#    upgrade silently no-ops as "already at version <old>".
#
#    By searching PATH ourselves, we control the env that the resolved
#    binary inherits — AGENSHIELD_NPX_PACKAGE_VERSION is preserved
#    through `exec`, so any `getVersion()`-aware build (>=.428) reports
#    the wrapper version even when the cache is broken. Older builds
#    still see only their own embedded VERSION; nothing we can do for
#    those without reinstalling from the .pkg.
#
#    Self-loop guard: skip any PATH entry that points back to this
#    launcher's own directory (would cause infinite recursion).
ME_DIR="$SCRIPT_DIR"
ME_REAL=""
if command -v readlink >/dev/null 2>&1; then
  ME_REAL=$(readlink -f "$0" 2>/dev/null || echo "$0")
else
  ME_REAL="$0"
fi
ME_DIR_REAL=$(cd "$(dirname "$ME_REAL")" 2>/dev/null && pwd || echo "$ME_DIR")

OLDIFS="$IFS"
IFS=:
for p in $PATH; do
  [ -z "$p" ] && continue
  cand="$p/agenshield"
  [ ! -x "$cand" ] && continue
  # Resolve symlinks before comparing — the .pkg installs
  # /usr/local/bin/agenshield as a symlink to /Library/AgenShield/bin/agenshield;
  # we want to match that binary, not the symlink.
  cand_real=$(readlink -f "$cand" 2>/dev/null || echo "$cand")
  cand_dir=$(cd "$(dirname "$cand_real")" 2>/dev/null && pwd || echo "$p")
  # Skip if the candidate is this same launcher (or in our own dir)
  if [ "$cand_dir" = "$ME_DIR_REAL" ] || [ "$cand_dir" = "$ME_DIR" ]; then
    continue
  fi
  IFS="$OLDIFS"
  echo "agenshield: platform package missing from npm cache; falling back to $cand_real" >&2
  if [ -n "$WRAPPER_VERSION" ]; then
    echo "agenshield: forwarding requested version ${WRAPPER_VERSION} via AGENSHIELD_NPX_PACKAGE_VERSION" >&2
  fi
  exec "$cand" "$@"
done
IFS="$OLDIFS"

# Nothing on PATH either — give the operator an actionable diagnostic.
echo "Platform package $PKG not found in npm cache, and no fallback agenshield binary on PATH." >&2
echo "" >&2
if [ -n "$WRAPPER_VERSION" ]; then
  echo "  Wrapper:   agenshield@${WRAPPER_VERSION}" >&2
  echo "  Expected: $PKG@${WRAPPER_VERSION}" >&2
  echo "" >&2
fi
echo "npm typically silently skips optionalDependencies when its cache has" >&2
echo "files it can't write (most common cause: a prior 'sudo npx' left some" >&2
echo "files root-owned). Recovery:" >&2
echo "" >&2
echo "  sudo chown -R \"\$(id -u):\$(id -g)\" ~/.npm" >&2
echo "  npm cache clean --force" >&2
echo "  rm -rf ~/.npm/_npx" >&2
echo "  npx --yes agenshield@<version> upgrade" >&2
echo "" >&2
echo "Or install the platform binary directly from npm and bypass npx:" >&2
echo "" >&2
echo "  TARBALL=\$(npm view ${PKG}@<version> dist.tarball)" >&2
echo "  curl -fSL -o /tmp/agenshield.tgz \"\$TARBALL\"" >&2
echo "  tar -xzf /tmp/agenshield.tgz -C /tmp" >&2
echo "  sudo installer -pkg /tmp/package/AgenShield.pkg -target /" >&2
echo "" >&2
echo "Supported platforms:" >&2
echo "  - darwin/arm64  (Apple Silicon)" >&2
echo "  - darwin/x64    (Intel Mac)" >&2
echo "  - linux/x64     (Linux x86_64)" >&2
exit 1
