#!/usr/bin/env bash
# verify-autonumber-canonicalizer.sh
#
# Fixpack F16 — Canonicalizer single-owner guard.
#
# Purpose:
#   The autonumber engine stores a SHA-256 hash of the canonical token-ref
#   serialization on _System_Field.AutoNumberCanonicalHash. V1→V2 cutover
#   (docs/design/autonumber-v2-implementation-plan.md §F16) mandated that
#   there be exactly ONE owner of that canonical serialization:
#   backend/internal/features/automation/autonumber.CanonicalizeTokenRefs.
#
#   Any code outside the autonumber package that calls json.Marshal on a
#   variable whose identifier contains "tokenRefs" / "TokenRefs" is almost
#   certainly producing a competing canonical form — which will silently
#   drift the stored hash and corrupt the V2 drift detector.
#
# What this script does:
#   greps backend/ for  json.Marshal*(<anything>tokenRefs-like<anything>)
#   outside the autonumber package. If a line matches, CI fails.
#
# Exemption:
#   Add a trailing  `// canonicalizer-exempt`  comment on the same line if
#   the bypass is intentional (e.g. the V2 drift detector itself, which
#   by design must use an independent serialization to catch drift).
#
# Exit codes:
#   0 — no non-canonicalized serialization found (PASS)
#   1 — violation(s) found (FAIL)

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

echo "🔍 Verifying autonumber canonicalizer single-owner invariant..."

# Pattern: json.Marshal / json.MarshalIndent whose argument region contains
# "tokenRefs" or "TokenRefs" (case-insensitive variants covered).
#
# Exclusions:
#   - autonumber package itself (the canonical owner lives there).
#   - vendor/ (third-party code).
#   - lines explicitly annotated with `canonicalizer-exempt`.
HITS=$(grep -rEn 'json\.(Marshal|MarshalIndent)\([^)]*([Tt]oken[Rr]efs|tokenRefs)' \
    --include='*.go' \
    --exclude-dir=autonumber \
    --exclude-dir=vendor \
    "$PROJECT_ROOT/backend/" 2>/dev/null | grep -v 'canonicalizer-exempt' || true)

if [ -n "$HITS" ]; then
    echo "❌ FAIL: direct json.Marshal of token refs outside autonumber pkg:" >&2
    echo "" >&2
    echo "$HITS" >&2
    echo "" >&2
    echo "Use autonumber.CanonicalizeTokenRefs instead — it is the single" >&2
    echo "source of truth for the canonical serialization used to compute" >&2
    echo "_System_Field.AutoNumberCanonicalHash." >&2
    echo "" >&2
    echo "If this usage is intentional (e.g. an independent drift detector)," >&2
    echo "append '// canonicalizer-exempt' to the offending line with a" >&2
    echo "comment explaining why the bypass is safe." >&2
    exit 1
fi

echo "✅ OK: no non-canonicalized token-refs serialization found."
exit 0
