#!/usr/bin/env bash
# scripts/quality/check-doc-freshness.sh
#
# Cheap, string-only documentation-freshness gate.  Catches the cross-file
# drift that a "documentation pass" (see doc/release-policy.md) is meant to
# prevent — without building anything, so it runs in well under a second.
#
# Invariants checked:
#   1. Release version agrees across CITATION.cff, CHANGELOG.md (newest
#      section) and CLAUDE.md ("Current release:" line).
#   2. Release date agrees across CITATION.cff and CHANGELOG.md.
#   3. The "N documents across ..." count in CLAUDE.md's Documentation map
#      equals the actual number of doc/**/*.md files.
#
# NOT checked here (they need a build — run them as part of the release
# documentation pass, see doc/release-policy.md):
#   * doc/api/tests.md counts        →  scripts/check-test-counts.sh  (needs BUILD_DIR)
#   * doc/api/headers.md regeneration →  scripts/gen-headers-md.py     (needs Doxygen XML)
#
# Usage:
#   bash scripts/quality/check-doc-freshness.sh
#
# Exit codes:
#   0  all string invariants hold
#   1  at least one drift found
#   2  prerequisite missing (a required file is absent)

set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$ROOT" || exit 2

for f in CITATION.cff CHANGELOG.md CLAUDE.md; do
    if [ ! -f "$f" ]; then
        echo "FAIL: required file not found: $f" >&2
        exit 2
    fi
done

fail=0
note() { printf '  %-4s %s\n' "$1" "$2"; }

# Strip an optional leading "v" so "v0.10.0" and "0.10.0" compare equal.
strip_v() { printf '%s' "${1#v}"; }

# ── Invariant 1 + 2: version & date triple ──────────────────────────────────
cit_ver=$(strip_v "$(grep -E '^version:' CITATION.cff | head -1 | awk '{print $2}')")
cit_date=$(grep -E '^date-released:' CITATION.cff | head -1 | awk '{print $2}')

chg_header=$(grep -m1 -E '^## \[' CHANGELOG.md)
chg_ver=$(strip_v "$(printf '%s' "$chg_header" | sed -E 's/^## \[([^]]+)\].*/\1/')")
chg_date=$(printf '%s' "$chg_header" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)

claude_ver=$(strip_v "$(grep -m1 'Current release:' CLAUDE.md | sed -E 's/.*\*\*(v?[0-9][0-9.]*)\*\*.*/\1/')")

echo "── version / date consistency ──"
note "CIT"  "CITATION.cff      version=$cit_ver  date=$cit_date"
note "CHG"  "CHANGELOG.md      version=$chg_ver  date=$chg_date"
note "CLD"  "CLAUDE.md         version=$claude_ver"

if [ "$cit_ver" = "$chg_ver" ] && [ "$cit_ver" = "$claude_ver" ]; then
    note "OK" "version agrees ($cit_ver)"
else
    note "DRIFT" "version mismatch: CITATION=$cit_ver CHANGELOG=$chg_ver CLAUDE=$claude_ver"
    fail=1
fi

if [ "$cit_date" = "$chg_date" ]; then
    note "OK" "date agrees ($cit_date)"
else
    note "DRIFT" "date mismatch: CITATION=$cit_date CHANGELOG=$chg_date"
    fail=1
fi

# ── Invariant 3: documentation-map count ────────────────────────────────────
stated=$(grep -m1 -E '^[0-9]+ documents across' CLAUDE.md | awk '{print $1}')
actual=$(find doc -name '*.md' -type f | wc -l | tr -d ' ')

echo
echo "── documentation-map count ──"
note "CLD"    "CLAUDE.md states: $stated documents"
note "DISK"   "doc/**/*.md on disk: $actual"
if [ "$stated" = "$actual" ]; then
    note "OK" "doc count agrees ($actual)"
else
    note "DRIFT" "CLAUDE.md says $stated, disk has $actual — update the 'N documents across' line"
    fail=1
fi

echo
if [ "$fail" -ne 0 ]; then
    echo "FAIL: documentation drift detected."
    echo "Recovery: run a documentation pass (see doc/release-policy.md →"
    echo "          'Documentation passes'); fix the lines above, then re-run."
    exit 1
fi

echo "OK: documentation strings are consistent."
echo "Reminder: at release also run scripts/check-test-counts.sh and"
echo "          scripts/gen-headers-md.py (both need a build)."
exit 0
