#!/usr/bin/env bash
# gc-check.sh — Architectural invariants for the .pi/ kit
# Curated kit checks for the bundled extensions, skills, and required files.
#
# Returns exit 0 if all pass, 1 otherwise.
# Invoked from `/gc` workflow. Run manually: bash .pi/scripts/gc-check.sh

set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
ERRORS=0

fail() { echo "  FAIL: $1"; ERRORS=$((ERRORS + 1)); }
pass() { echo "  PASS: $1"; }

# --- 1. Extension isolation: no cross-extension imports ---
echo "[Check 1/5] Extension isolation..."
BEFORE=$ERRORS
EXT_DIR="$ROOT/.pi/extensions"
EXTS=()
for f in "$EXT_DIR"/*.ts; do
  [ -f "$f" ] && EXTS+=("$(basename "$f" .ts)")
done

for ext in "${EXTS[@]}"; do
  for other in "${EXTS[@]}"; do
    [ "$ext" = "$other" ] && continue
    # Allow subdir imports (./foo/bar) but flag direct cross-extension
    if grep -qE "from ['\"]\./$other['\"]" "$EXT_DIR/$ext.ts" 2>/dev/null; then
      fail "$ext.ts imports from $other.ts — extensions must be independent"
    fi
  done
done
if [ "$ERRORS" -eq "$BEFORE" ]; then
  pass "No cross-extension imports"
fi

# --- 2. File size limits ---
echo "[Check 2/5] File size limits..."
BEFORE=$ERRORS
MAX_EXT=800
for f in "$EXT_DIR"/*.ts; do
  [ ! -f "$f" ] && continue
  lines=$(wc -l <"$f")
  name=$(basename "$f")
  if [ "$lines" -gt "$MAX_EXT" ]; then
    fail "$name exceeds ${MAX_EXT} lines ($lines)"
  fi
done
if [ "$ERRORS" -eq "$BEFORE" ]; then
  pass "All extensions within size limits"
fi

# --- 3. No stale .opencode/ references in active skills ---
echo "[Check 3/5] No stale .opencode/ references in active skills..."
BEFORE=$ERRORS
ACTIVE_SKILLS=$(find "$ROOT/.pi/skills" -maxdepth 2 -name "SKILL.md" 2>/dev/null || true)
STALE=""
for f in $ACTIVE_SKILLS; do
  matches=$(grep -nF ".opencode/" "$f" 2>/dev/null || true)
  if [ -n "$matches" ]; then
    STALE+="$f: $matches\n"
  fi
done
if [ -n "$STALE" ]; then
  fail "Stale .opencode/ paths in active skills:"
  echo -e "$STALE" | head -10
fi
if [ "$ERRORS" -eq "$BEFORE" ]; then
  pass "No stale .opencode/ paths in active skills"
fi

# --- 4. Required files present ---
echo "[Check 4/5] Required files present..."
BEFORE=$ERRORS
REQUIRED=(
  "$ROOT/.pi/AGENTS.md"
  "$ROOT/.pi/README.md"
  "$ROOT/.pi/VERSION"
  "$ROOT/.pi/settings.json"
)
for f in "${REQUIRED[@]}"; do
  if [ ! -f "$f" ]; then
    fail "Required file missing: $f"
  fi
done
if [ "$ERRORS" -eq "$BEFORE" ]; then
  pass "All required files present"
fi

# --- 5. Workflow syntax compatible with runner parser (delegates to mdpi lint) ---
echo "[Check 5/5] Workflow syntax compatible with runner parser..."
BEFORE=$ERRORS
LINT_BIN=""
# Source repo: use the local CLI source. Installed kit: use the mdpi binary.
if [ -f "$ROOT/src/index.ts" ] && command -v pnpm >/dev/null 2>&1; then
  LINT_BIN="pnpm exec tsx src/index.ts"
elif command -v mdpi >/dev/null 2>&1; then
  LINT_BIN="mdpi"
fi
if [ -n "$LINT_BIN" ]; then
  # Delegates workflow-syntax parsing to the TS lint (the runner parser is TS regex;
  # reimplementing it in bash would drift). PRD-1 ships warnings-only, so exit 0
  # is expected; PRD-3 escalates to errors and this check will catch them.
  if ( cd "$ROOT" && $LINT_BIN lint workflows --json >/dev/null 2>&1 ); then
    pass "Workflow syntax compatible with runner parser (delegated to $LINT_BIN lint workflows)"
  else
    fail "Workflow lint reported errors — run: cd \"$ROOT\" && $LINT_BIN lint workflows"
  fi
else
  pass "Workflow lint skipped (no mdpi/tsx CLI available in this environment)"
fi

echo ""
echo "---"
if [ "$ERRORS" -eq 0 ]; then
  echo "[OK] All structural checks passed."
  exit 0
else
  echo "[FAIL] $ERRORS check(s) failed."
  exit 1
fi
