# account-settings-askgate.sh — retrofit the AskUserQuestion carrier gate onto
# existing accounts' .claude/settings.json. Task 1683.
#
# Task 1552 added askuserquestion-channel-carrier-gate.sh as a second command on
# the AskUserQuestion PreToolUse matcher in 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
# 1552 keeps a stale matcher with no carrier gate and re-wedges on a channel
# AskUserQuestion (live SiteDesk incident: session d39a22b0, account 2078cb54,
# 2026-07-15). This lib is the standing backfill: setup-account.sh reconciles
# every account on every install so the gate reaches pre-1552 accounts.
#
# 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 strings provision-account-dir.sh writes. $PLATFORM_ROOT is a
# literal in the settings file, resolved by Claude Code at hook-run time.
_ASKGATE_CARRIER='bash $PLATFORM_ROOT/plugins/admin/hooks/askuserquestion-channel-carrier-gate.sh'
_ASKGATE_INVESTIGATE='bash $PLATFORM_ROOT/plugins/admin/hooks/askuserquestion-investigate-gate.sh'

# ensure_askgate_carrier <settings_file>
# Guarantees the AskUserQuestion PreToolUse matcher carries the carrier-gate
# command: appends it if the matcher exists without it, or adds the whole matcher
# (both gates, investigate first) if the matcher is absent. Logs exactly one
# `[backfill-1683] file=<f> status=<absent|no-hooks|already-set|updated|rewrite-failed>`
# to stdout. Always returns 0.
ensure_askgate_carrier() {
  local f="$1"
  if [ ! -f "$f" ]; then
    echo "[backfill-1683] file=$f status=absent"
    return 0
  fi
  # Patchable only when the file is valid JSON with a PreToolUse array.
  if ! jq -e '.hooks.PreToolUse | type == "array"' "$f" >/dev/null 2>&1; then
    if jq -e . "$f" >/dev/null 2>&1; then
      echo "[backfill-1683] file=$f status=no-hooks"
    else
      echo "[backfill-1683] file=$f status=rewrite-failed"
    fi
    return 0
  fi
  local tmp="$f.1683.tmp"
  if ! jq \
      --arg carrier "$_ASKGATE_CARRIER" \
      --arg invest "$_ASKGATE_INVESTIGATE" '
      .hooks.PreToolUse |= (
        if any(.[]; .matcher == "AskUserQuestion")
        then map(
          if .matcher == "AskUserQuestion"
          then .hooks = (
                 if any(.hooks[]; .command == $carrier)
                 then .hooks
                 else .hooks + [{type: "command", command: $carrier}]
                 end)
          else . end)
        else . + [{matcher: "AskUserQuestion", hooks: [{type: "command", command: $invest}, {type: "command", command: $carrier}]}]
        end)
    ' "$f" > "$tmp" 2>/dev/null; then
    rm -f "$tmp"
    echo "[backfill-1683] 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-1683] file=$f status=already-set"
    return 0
  fi
  if mv "$tmp" "$f"; then
    echo "[backfill-1683] file=$f status=updated"
  else
    rm -f "$tmp"
    echo "[backfill-1683] file=$f status=rewrite-failed"
  fi
  return 0
}

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