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

# Validate a clean pi-67 artifact copy/ref without touching the real Pi config.

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
REPO_URL=""
REF="WORKTREE"
KEEP_TMP=false
TMP_ROOT=""

usage() {
  cat <<'USAGE'
pi67-release-artifact-smoke validates a clean install/release-check artifact.

Usage:
  scripts/pi67-release-artifact-smoke.sh [options]

Options:
      --repo-root DIR  Local pi-67 repository root. Defaults to this script's parent.
      --repo-url URL   Clone source. Defaults to --repo-root for ref clones.
      --ref REF        Ref to verify. Defaults to WORKTREE.
                       Use WORKTREE for the current local candidate, HEAD for the
                       committed default branch state, or a tag such as v0.9.0.
      --keep-tmp       Keep temporary artifact directory for inspection.
  -h, --help           Show this help.

Examples:
  bash scripts/pi67-release-artifact-smoke.sh
  bash scripts/pi67-release-artifact-smoke.sh --ref HEAD
  bash scripts/pi67-release-artifact-smoke.sh --ref v0.9.0
USAGE
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --repo-root)
      REPO_ROOT="${2:?--repo-root requires a path}"
      shift 2
      ;;
    --repo-url)
      REPO_URL="${2:?--repo-url requires a URL or path}"
      shift 2
      ;;
    --ref)
      REF="${2:?--ref requires a ref}"
      shift 2
      ;;
    --keep-tmp)
      KEEP_TMP=true
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "Unknown option: $1" >&2
      usage >&2
      exit 2
      ;;
  esac
done

if [ -n "$REPO_URL" ] && [ "$REF" = "WORKTREE" ]; then
  REF="HEAD"
fi

pass() {
  echo -e "  ${GREEN}PASS${NC} $*"
}

warn() {
  echo -e "  ${YELLOW}WARN${NC} $*"
}

fail() {
  echo -e "  ${RED}FAIL${NC} $*" >&2
  exit 1
}

section() {
  echo ""
  echo -e "${CYAN}--- $* ---${NC}"
}

cleanup() {
  if [ "$KEEP_TMP" = true ]; then
    if [ -n "$TMP_ROOT" ]; then
      warn "kept temp directory: $TMP_ROOT"
    fi
    return
  fi
  if [ -n "$TMP_ROOT" ] && [ -d "$TMP_ROOT" ]; then
    rm -rf "$TMP_ROOT"
  fi
}
trap cleanup EXIT

command_exists() {
  command -v "$1" >/dev/null 2>&1
}

echo ""
echo -e "${CYAN}pi-67 release artifact smoke${NC}"
echo "Repository: $REPO_ROOT"
echo "Ref       : $REF"

command_exists git || fail "git is required"
command_exists node || fail "node is required"
command_exists npm || fail "npm is required"
if [ "$(git -C "$REPO_ROOT" rev-parse --is-inside-work-tree 2>/dev/null || true)" != "true" ]; then
  fail "repo root is not a Git checkout: $REPO_ROOT"
fi
pass "required tools found"

TMP_ROOT="$(mktemp -d "${TMPDIR:-/tmp}/pi67-release-artifact.XXXXXX")"
ARTIFACT_DIR="$TMP_ROOT/artifact"

copy_worktree_candidate() {
  if ! git clone --no-hardlinks --no-checkout "$REPO_ROOT" "$ARTIFACT_DIR" > "$TMP_ROOT/worktree-clone.log" 2>&1; then
    fail "could not clone local history for the worktree candidate"
  fi
  while IFS= read -r -d '' file; do
    if [ ! -e "$REPO_ROOT/$file" ] && [ ! -L "$REPO_ROOT/$file" ]; then
      continue
    fi
    mkdir -p "$ARTIFACT_DIR/$(dirname "$file")"
    cp -p "$REPO_ROOT/$file" "$ARTIFACT_DIR/$file"
  done < <(git -C "$REPO_ROOT" ls-files -z --cached --others --exclude-standard)

  git -C "$ARTIFACT_DIR" config user.email "pi67-release-artifact@example.invalid"
  git -C "$ARTIFACT_DIR" config user.name "pi67 release artifact smoke"
  git -C "$ARTIFACT_DIR" add .
  if ! git -C "$ARTIFACT_DIR" diff --cached --quiet; then
    git -C "$ARTIFACT_DIR" commit -q -m "pi67 release artifact smoke candidate"
  fi

  if ! git -C "$ARTIFACT_DIR" rev-parse --verify --quiet refs/tags/v0.11.7 >/dev/null; then
    fail "worktree artifact is missing the v0.11.7 settings-migration baseline tag"
  fi
}

section "Build artifact"
if [ "$REF" = "WORKTREE" ]; then
  copy_worktree_candidate
  pass "copied current worktree candidate with local history and tags"
else
  CLONE_SOURCE="${REPO_URL:-$REPO_ROOT}"
  git clone --no-hardlinks "$CLONE_SOURCE" "$ARTIFACT_DIR" > "$TMP_ROOT/clone.log" 2>&1
  if [ "$REF" != "HEAD" ]; then
    git -C "$ARTIFACT_DIR" checkout --detach "$REF" > "$TMP_ROOT/checkout.log" 2>&1
  fi
  pass "cloned artifact source"
fi

[ -f "$ARTIFACT_DIR/install.sh" ] || fail "artifact missing install.sh"
[ -f "$ARTIFACT_DIR/scripts/pi67-release-check.sh" ] || fail "artifact missing release check"
[ -f "$ARTIFACT_DIR/scripts/pi67-migrate-skills.sh" ] || fail "artifact missing skill migration helper"
[ -f "$ARTIFACT_DIR/tests/pi-rules-loader/routing.test.mjs" ] || fail "artifact missing rules-loader routing test"
[ -f "$ARTIFACT_DIR/tests/pi-vision-bridge/registration.test.mjs" ] || fail "artifact missing vision-bridge registration test"

section "Prepare repository dependencies"
mkdir -p "$ARTIFACT_DIR/npm"
cp "$ARTIFACT_DIR/package.json" "$ARTIFACT_DIR/npm/package.json"
cp "$ARTIFACT_DIR/package-lock.json" "$ARTIFACT_DIR/npm/package-lock.json"
(
  cd "$ARTIFACT_DIR"
  npm --prefix npm ci --ignore-scripts --omit=peer --no-audit --no-fund
)
pass "prepared repository dependency closure from the artifact lockfile"

FAKE_BIN="$TMP_ROOT/bin"
mkdir -p "$FAKE_BIN"
cat > "$FAKE_BIN/pi" <<'SH'
#!/usr/bin/env bash
case "${1:-}" in
  --help)
    echo "release artifact smoke pi help"
    ;;
  list)
    if [ "${2:-}" = "--no-approve" ]; then
      echo "User packages:"
    else
      echo "release artifact smoke pi list"
    fi
    ;;
  skill)
    if [ "${2:-}" = "list" ]; then
      echo "release artifact smoke skill list"
    else
      echo "release artifact smoke pi skill"
    fi
    ;;
  *)
    echo "release artifact smoke pi"
    ;;
esac
SH
chmod +x "$FAKE_BIN/pi"

section "Install dry-run"
HOME="$TMP_ROOT/home" PATH="$FAKE_BIN:$PATH" "$ARTIFACT_DIR/install.sh" \
  --dry-run \
  --json \
  --agent-dir "$TMP_ROOT/agent" \
  --skills-dir "$TMP_ROOT/shared-skills" \
  --no-npm \
  --yes > "$TMP_ROOT/install-dry-run.log"
if ! grep -q '"schema": "pi67.install.v1"' "$TMP_ROOT/install-dry-run.log"; then
  cat "$TMP_ROOT/install-dry-run.log" >&2
  fail "install.sh did not delegate to the immutable manager"
fi
pass "install.sh delegated its dry-run to the immutable manager"

section "Release metadata check"
bash "$ARTIFACT_DIR/scripts/pi67-release-check.sh" > "$TMP_ROOT/release-check.log"
pass "release check completed"

section "Skill migration schema check"
bash "$ARTIFACT_DIR/scripts/pi67-migrate-skills.sh" \
  --agent-dir "$TMP_ROOT/agent" \
  --skills-dir "$TMP_ROOT/shared-skills" \
  --backup-dir "$TMP_ROOT/backup/skill-migration" \
  --dry-run \
  --json > "$TMP_ROOT/migrate-skills.json"
node - "$TMP_ROOT/migrate-skills.json" <<'NODE'
const fs = require("fs");
const data = JSON.parse(fs.readFileSync(process.argv[2], "utf8"));
if (data.schemaId !== "pi67-skill-migration/v1") {
  throw new Error(`unexpected schemaId: ${data.schemaId}`);
}
if (!["NOOP", "READY_TO_APPLY"].includes(data.result)) {
  throw new Error(`unexpected migration result: ${data.result}`);
}
NODE
pass "skill migration JSON schema accepted"

section "Summary"
pass "release artifact smoke passed"
