# account-settings-pdf-conformance.sh — retrofit the quote-render PDF-conformance
# PostToolUse matcher onto existing accounts' .claude/settings.json. Task 1929.
#
# Task 1922 added a PostToolUse matcher on the browser-pdf-save tool running
# quote-render-pdf-conformance.sh to provision-account-dir.sh. That writer only
# runs at account-provision time; the upgrade path re-provisions the house
# account but NOT existing client sub-accounts, so any account provisioned before
# 1922 keeps a settings.json without the matcher and never runs the PDF gate
# (live glsmith is such an account). This lib is the standing backfill:
# setup-account.sh reconciles every account on every install so the gate reaches
# pre-1922 accounts. Mirrors account-settings-askgate.sh (Task 1683).
#
# Requires jq. Idempotent. Never echoes file contents. Fail-open (nudge, not
# brick): any unusable file logs a status and is left untouched.
#
# Sourced by setup-account.sh; also runnable standalone for a manual repair.

# The exact command string provision-account-dir.sh writes. $PLATFORM_ROOT is a
# literal in the settings file, resolved by Claude Code at hook-run time.
_PDF_CONFORMANCE_MATCHER='mcp__plugin_browser_browser__browser-pdf-save'
_PDF_CONFORMANCE_CMD='bash $PLATFORM_ROOT/plugins/admin/hooks/quote-render-pdf-conformance.sh'

# ensure_pdf_conformance_matcher <settings_file>
# Guarantees the PostToolUse browser-pdf-save matcher carries the conformance
# command: appends it if the matcher exists without it, or adds the whole matcher
# (single conformance command) if the matcher is absent. Logs exactly one
# `[backfill-1929] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
# to stdout. Always returns 0.
ensure_pdf_conformance_matcher() {
  local f="$1"
  if [ ! -f "$f" ]; then
    echo "[backfill-1929] file=$f status=absent"
    return 0
  fi
  # Patchable only when the file is valid JSON with a PostToolUse array.
  if ! jq -e '.hooks.PostToolUse | type == "array"' "$f" >/dev/null 2>&1; then
    if jq -e . "$f" >/dev/null 2>&1; then
      echo "[backfill-1929] file=$f status=no-hooks"
    else
      echo "[backfill-1929] file=$f status=rewrite-failed"
    fi
    return 0
  fi
  local tmp="$f.1929.tmp"
  if ! jq \
      --arg matcher "$_PDF_CONFORMANCE_MATCHER" \
      --arg cmd "$_PDF_CONFORMANCE_CMD" '
      .hooks.PostToolUse |= (
        if any(.[]; .matcher == $matcher)
        then map(
          if .matcher == $matcher
          then .hooks = (
                 if any(.hooks[]; .command == $cmd)
                 then .hooks
                 else .hooks + [{type: "command", command: $cmd}]
                 end)
          else . end)
        else . + [{matcher: $matcher, hooks: [{type: "command", command: $cmd}]}]
        end)
    ' "$f" > "$tmp" 2>/dev/null; then
    rm -f "$tmp"
    echo "[backfill-1929] file=$f status=rewrite-failed"
    return 0
  fi
  # Semantic no-op? Compare canonical forms; leave the file byte-identical if so.
  # `|| true` keeps a jq failure here (e.g. $f truncated by a concurrent writer
  # between the type-check above and this read) from tripping a caller's `set -e`
  # and aborting the whole install. This lib is fail-open by contract.
  local before after
  before="$(jq -S . "$f" 2>/dev/null || true)"
  after="$(jq -S . "$tmp" 2>/dev/null || true)"
  if [ "$before" = "$after" ]; then
    rm -f "$tmp"
    echo "[backfill-1929] file=$f status=already-set"
    return 0
  fi
  if mv "$tmp" "$f"; then
    echo "[backfill-1929] file=$f status=updated"
  else
    rm -f "$tmp"
    echo "[backfill-1929] file=$f status=rewrite-failed"
  fi
  return 0
}

# reconcile_all_accounts_pdf_conformance <accounts_dir>
# Standing check + backfill: every account dir with an account.json gets its
# PostToolUse browser-pdf-save matcher's conformance command ensured. Mirrors
# reconcile_all_accounts_askgate.
reconcile_all_accounts_pdf_conformance() {
  local accts="$1"
  [ -d "$accts" ] || return 0
  local acct
  for acct in "$accts"/*/; do
    [ -f "$acct/account.json" ] || continue
    ensure_pdf_conformance_matcher "$acct/.claude/settings.json"
  done
}
