#!/usr/bin/env bash
# Task 1362 — the reference-reachability guard.
# A SKILL.md's plugin-root-only bare `references/…` citation is reachable ONLY
# when the SKILL.md declares the `plugin-read` convention. Without it, a plain
# Read against the announced skill base dir misses, so the citation is a
# violation. Skill-local references, full `plugins/<name>/references/…` paths,
# and PLUGIN.md plugin-root references are unaffected.
set -u
GATE="$(cd "$(dirname "$0")/.." && pwd)/check-plugin-references.mjs"
[[ -f "$GATE" ]] || { echo "FAIL: gate script missing at $GATE" >&2; exit 1; }
PASS=0; FAIL=0

ROOT=$(mktemp -d)
PREMIUM="$ROOT/premium-empty"
mkdir -p "$PREMIUM"
trap 'rm -rf "$ROOT"' EXIT

reset_root() { rm -rf "$ROOT/platform"; }

# Write a SKILL.md for plugin "$1" (skill slug == plugin name) with body "$2".
make_skill() {
  local plugin="$1" body="$2"
  local dir="$ROOT/platform/plugins/$plugin/skills/$plugin"
  mkdir -p "$dir"
  { printf -- '---\nname: %s\ndescription: test skill\n---\n\n' "$plugin"; printf '%s\n' "$body"; } > "$dir/SKILL.md"
}

# Create a reference file at an arbitrary path under $ROOT.
make_ref() { local rel="$1"; mkdir -p "$ROOT/$(dirname "$rel")"; printf 'ref body\n' > "$ROOT/$rel"; }

check() {
  local desc="$1" expected="$2"
  node "$GATE" "$ROOT/platform" "$PREMIUM" >/dev/null 2>&1
  local got=$?
  if [[ "$got" -eq "$expected" ]]; then echo "PASS: $desc"; ((PASS++))
  else echo "FAIL: $desc (expected exit $expected, got $got)"; ((FAIL++)); fi
}

# CASE 1: plugin-root-only ref, NO plugin-read declared → violation.
reset_root
make_ref "platform/plugins/foo/references/api.md"
make_skill "foo" 'Read \`references/api.md\` before the API call.'
check "plugin-root-only ref without plugin-read fails" 1

# CASE 2: same ref, plugin-read declared → passes.
reset_root
make_ref "platform/plugins/foo/references/api.md"
make_skill "foo" 'Open \`references/api.md\` with the \`plugin-read\` tool before the API call.'
check "plugin-root-only ref with plugin-read passes" 0

# CASE 3: skill-local ref, NO plugin-read → passes (plain Read resolves it).
reset_root
make_ref "platform/plugins/foo/skills/foo/references/local.md"
make_skill "foo" 'Read \`references/local.md\` for the details.'
check "skill-local ref without plugin-read passes" 0

# CASE 4: full plugins/<name>/references/... path, NO plugin-read → passes.
reset_root
make_ref "platform/plugins/foo/references/api.md"
make_skill "foo" 'Read \`plugins/foo/references/api.md\` before the API call.'
check "full plugin-path ref without plugin-read passes" 0

# CASE 5: genuinely missing ref (neither skill-local nor plugin-root) → violation.
reset_root
make_skill "foo" 'Open \`references/ghost.md\` with \`plugin-read\`.'
check "missing ref fails even with plugin-read" 1

# CASE 6: a MISSING full plugins/<name>/references/... path from a SKILL.md without
# plugin-read → violation, and the plugin-root "declare plugin-read" hint must NOT
# fire (the hint is scoped to the bare references/ shape only; a full path is not
# reachability-limited by the missing convention). Guards the Task 1362 hint-scope fix.
reset_root
make_skill "foo" 'Read \`plugins/foo/references/ghost.md\` before the API call.'
OUT=$(node "$GATE" "$ROOT/platform" "$PREMIUM" 2>&1); GOT=$?
if [[ "$GOT" -eq 1 ]] && ! grep -q "exists at plugin root" <<<"$OUT"; then
  echo "PASS: missing full-path ref fails without a false plugin-read hint"; ((PASS++))
else
  echo "FAIL: missing full-path ref (exit=$GOT, hint present=$(grep -qc 'exists at plugin root' <<<"$OUT" && echo yes || echo no))"; ((FAIL++))
fi

echo ""
echo "Results: $PASS passed, $FAIL failed"
[[ "$FAIL" -eq 0 ]] && exit 0 || exit 1
