#!/usr/bin/env bash
# Regenerate symbols_mcp/skills/FRANKABILITY_CATALOG.md from frank-audit's
# `explain` output. Run before each release so the bundled catalog tracks
# whatever rules frank-audit currently ships.
#
# ⚠ THIS SCRIPT DELETES HAND-AUTHORED PROSE. The catalog calls itself
# auto-generated, but paragraphs no rule's `explain()` carries have been added
# to it by hand — FA304's sizes-token section (symbols-mcp a6eace5), FA701's
# polyglot block and the onDocumentXxx notes (1945ffd, 7e3dc05). A full resync
# on 2026-09-25 dropped 29 such lines. Until
# FW-MCP-CATALOG-SYNC-OVERWRITES-HAND-AUTHORED-SKILL-DOCS-1 decides which side
# owns the prose: to add ONE rule's wording, splice that rule's
# `frank-audit explain <ID>` output into the file instead of running this.
# Diff the result before committing, every time.
#
# Usage: ./bin/sync-frankability-catalog
set -e

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
OUT="$ROOT/symbols_mcp/skills/FRANKABILITY_CATALOG.md"

if ! command -v frank-audit >/dev/null 2>&1; then
  echo "✗ frank-audit not on PATH — install with: npm i -g @symbo.ls/frank-audit" >&2
  exit 1
fi

# Pull the rule-id list from `frank-audit explain` (no arg prints the catalog)
IDS=$(frank-audit explain 2>&1 \
  | grep -oE 'FA[0-9]+' \
  | sort -u)

if [ -z "$IDS" ]; then
  echo "✗ couldn't parse rule list from 'frank-audit explain'" >&2
  exit 1
fi

COUNT=$(echo "$IDS" | wc -l | tr -d ' ')
echo "syncing $COUNT rules → $OUT"

# Bucket titles. A plain function, NOT `declare -A`: associative arrays are
# bash 4+, and macOS ships bash 3.2 as /bin/bash, so `declare -A` aborted this
# script under `set -e` before it wrote a single rule — the catalog silently
# stayed at the previous release's wording
# (FW-FRANKAUDIT-FA107-FLAGS-FETCH-ON-TRIGGER-1).
category_title () {
  case "$1" in
    0) echo "FA0xx — Project structure & imports" ;;
    1) echo "FA1xx — Flat element API" ;;
    2) echo "FA2xx — DOMQL syntax & scope movers" ;;
    3) echo "FA3xx — Design-system tokens" ;;
    4) echo "FA4xx — Fix-time rules" ;;
    5) echo "FA5xx — Banned runtime APIs & frank-serialization" ;;
    6) echo "FA6xx — Lifecycle & events" ;;
    7) echo "FA7xx — State" ;;
    8) echo "FA8xx — Pages & routing" ;;
    9) echo "FA9xx — Reference resolution" ;;
    *) echo "FA${1}xx" ;;
  esac
}

{
  cat <<'EOF'
# Frankability Catalog — every `@symbo.ls/frank-audit` rule

**Auto-generated** by `bin/sync-frankability-catalog` from `frank-audit explain`.
Do not edit by hand — re-run the script after upgrading `@symbo.ls/frank-audit`.

For deeper conceptual context on the most-used rules, see `FRANKABILITY.md`.
This file is the exhaustive reference: brief explainer + bad/good examples per
rule, lifted verbatim from the CLI source-of-truth.

EOF

  CUR_BUCKET=""
  for ID in $IDS; do
    # Bucket by first digit after FA (e.g. FA503 → 5)
    BUCKET="${ID:2:1}"
    if [ "$BUCKET" != "$CUR_BUCKET" ]; then
      CUR_BUCKET="$BUCKET"
      TITLE="$(category_title "$BUCKET")"
      printf '\n---\n\n## %s\n\n' "$TITLE"
    fi
    frank-audit explain "$ID" 2>&1
    printf '\n'
  done
} > "$OUT"

LINES=$(wc -l < "$OUT" | tr -d ' ')
echo "✓ wrote $OUT ($LINES lines)"
