#!/usr/bin/env bash
# Isolated behavior tests for the Codex sandbox dependency bootstrap.
set -uo pipefail

REPO_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)
BOOTSTRAP="$REPO_ROOT/modules/workstation/bin/codex-sandbox-bootstrap.sh"
PASS=0; FAIL=0
ok() { PASS=$((PASS + 1)); printf 'ok   %s\n' "$1"; }
no() { FAIL=$((FAIL + 1)); printf 'FAIL %s\n     %s\n' "$1" "$2"; }
TESTROOT=$(mktemp -d -t codex-sandbox-bootstrap.XXXXXX)
trap 'rm -rf "$TESTROOT"' EXIT

make_fixture() {
  FIXTURE="$TESTROOT/$1"; FAKE_BIN="$FIXTURE/fake-bin"
  mkdir -p "$FIXTURE/modules/workstation/claude/bin" "$FIXTURE/home/.bun/bin" "$FAKE_BIN"
  /usr/bin/git -C "$FIXTURE" init -q
  printf '{"packageManager":"pnpm@11.5.2"}\n' > "$FIXTURE/package.json"; : > "$FIXTURE/pnpm-lock.yaml"
  printf '#!/bin/sh\nexit 0\n' > "$FIXTURE/modules/workstation/claude/bin/local-gate"; chmod +x "$FIXTURE/modules/workstation/claude/bin/local-gate"
  cat > "$FAKE_BIN/node" <<'EOF'
#!/bin/sh
printf 'v22.0.0\n'
EOF
  cat > "$FAKE_BIN/pnpm" <<'EOF'
#!/bin/sh
if [ "$1" = install ]; then printf 'pnpm install %s\n' "$*" >> "$INSTALL_LOG"; mkdir -p "$FAKE_REPO_ROOT/node_modules"; : > "$FAKE_REPO_ROOT/node_modules/.modules.yaml"; exit 0; fi
printf '11.5.2\n'
EOF
  cat > "$FAKE_BIN/bun" <<'EOF'
#!/bin/sh
printf '1.2.0\n'
EOF
  printf '#!/bin/sh\nexit 0\n' > "$FAKE_BIN/corepack"
  chmod +x "$FAKE_BIN/node" "$FAKE_BIN/pnpm" "$FAKE_BIN/bun" "$FAKE_BIN/corepack"
  INSTALL_LOG="$FIXTURE/install.log"
  # /bin is a symlink to /usr/bin on Debian, so PATH=$FAKE_BIN:/bin would leak the
  # REAL corepack/pnpm into every case and make "tool is missing" untestable.
  # Curate a minimal system bin instead: only what the script itself shells out to.
  SYS_BIN="$FIXTURE/sys-bin"; mkdir -p "$SYS_BIN"
  for t in bash sh env sed head chmod rm mkdir cat wc grep dirname mktemp; do
    p=$(command -v "$t") && ln -sf "$p" "$SYS_BIN/$t"
  done
  # Real git, never the repo's PATH shim (the shim needs env this fixture lacks).
  ln -sf /usr/bin/git "$SYS_BIN/git"
}
run_bootstrap() { (cd "$1" && HOME="$FIXTURE/home" FAKE_REPO_ROOT="$FIXTURE" INSTALL_LOG="$INSTALL_LOG" PATH="$FAKE_BIN:$SYS_BIN" bash "$BOOTSTRAP") 2>&1; }

make_fixture outside; OUT=$(run_bootstrap "$TESTROOT"); RC=$?
if [ "$RC" -eq 1 ] && [[ "$OUT" == *'not inside a git repo'* ]]; then ok 'outside a git repo fails closed'; else no 'outside a git repo fails closed' "$OUT"; fi

make_fixture missing-corepack; rm "$FAKE_BIN/pnpm" "$FAKE_BIN/corepack"; OUT=$(run_bootstrap "$FIXTURE"); RC=$?
if [ "$RC" -eq 1 ] && [[ "$OUT" == *corepack* ]]; then ok 'missing pnpm and corepack names corepack'; else no 'missing pnpm and corepack names corepack' "$OUT"; fi

make_fixture install-absent; OUT=$(run_bootstrap "$FIXTURE"); RC=$?
if [ "$RC" -eq 0 ] && [ -f "$INSTALL_LOG" ] && grep -q -- '--frozen-lockfile --prefer-offline' "$INSTALL_LOG"; then ok 'missing node_modules invokes install'; else no 'missing node_modules invokes install' "$OUT"; fi

make_fixture install-skipped; mkdir -p "$FIXTURE/node_modules"; : > "$FIXTURE/node_modules/.modules.yaml"; sleep 1; touch "$FIXTURE/node_modules/.modules.yaml"; OUT=$(run_bootstrap "$FIXTURE"); RC=$?
if [ "$RC" -eq 0 ] && [ ! -e "$INSTALL_LOG" ]; then ok 'fresh node_modules skips install'; else no 'fresh node_modules skips install' "$OUT"; fi

make_fixture bun-fails; printf '#!/bin/sh\nexit 1\n' > "$FAKE_BIN/bun"; chmod +x "$FAKE_BIN/bun"; OUT=$(run_bootstrap "$FIXTURE"); RC=$?
if [ "$RC" -eq 1 ] && [[ "$OUT" == *'bun failed'* ]]; then ok 'bun verification failure names bun'; else no 'bun verification failure names bun' "$OUT"; fi

make_fixture healthy; OUT=$(run_bootstrap "$FIXTURE"); RC=$?
if [ "$RC" -eq 0 ] && [[ "$OUT" == 'codex-bootstrap: ok node=v22.0.0 pnpm=11.5.2 bun=1.2.0 local-gate=present' ]]; then ok 'healthy toolchain prints summary'; else no 'healthy toolchain prints summary' "$OUT"; fi

OUT1=$(run_bootstrap "$FIXTURE"); RC1=$?; OUT2=$(run_bootstrap "$FIXTURE"); RC2=$?; INSTALLS=$(wc -l < "$INSTALL_LOG" 2>/dev/null || printf 0)
if [ "$RC1" -eq 0 ] && [ "$RC2" -eq 0 ] && [ "$OUT1" = "$OUT2" ] && [ "$INSTALLS" -le 1 ]; then ok 'second run is idempotent'; else no 'second run is idempotent' "first=$RC1 second=$RC2 installs=$INSTALLS"; fi
printf '\n%d passed, %d failed\n' "$PASS" "$FAIL"
[ "$FAIL" -eq 0 ]
