#!/usr/bin/env bash
# scripts/quality/codespell.sh
#
# Run codespell across the repo to catch typos in:
#   * doc/**/*.md  (reviewer-facing material)
#   * code/include/**/*.{h,hpp}  (Doxygen comments are user-facing)
#   * code/src/, code/tests/  (test names, error messages)
#   * scripts/**/*.{sh,py}  (CI messages reach contributors)
#   * README.md, CHANGELOG.md, CLAUDE.md
#
# Skips vendored deps, build dirs, generated Doxygen output (see
# `.codespellrc`).
#
# Local-only.  CI promotion once the existing tree is 0-typo.
#
# Usage:
#   bash scripts/quality/codespell.sh          # dry-run, exit 1 on any hit
#   bash scripts/quality/codespell.sh --fix    # interactively apply suggestions
#
# Exit codes:
#   0  no typos
#   1  at least one typo found (no --fix), or --fix completed
#   2  prerequisite missing

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

command -v codespell >/dev/null 2>&1 || {
    echo "FAIL: codespell not in PATH." >&2
    echo "        macOS: brew install codespell" >&2
    echo "        Linux: sudo apt install codespell  OR  pip3 install codespell" >&2
    exit 2
}

FIX=0
for arg in "$@"; do
    case "$arg" in
        --fix) FIX=1 ;;
        *)     echo "Unknown arg: $arg" >&2; exit 2 ;;
    esac
done

# Targets: everything except deps + build + generated.
TARGETS=(
    "doc"
    "code/include"
    "code/src"
    "code/tests"
    "scripts"
    "README.md"
    "CHANGELOG.md"
    "CLAUDE.md"
    "CITATION.cff"
    "CONTRIBUTING.md"
)

# Filter to existing entries (CONTRIBUTING.md / CHANGELOG.md may not exist
# on every branch).
EXISTING=()
for t in "${TARGETS[@]}"; do
    [ -e "$t" ] && EXISTING+=("$t")
done

echo "codespell ($(codespell --version 2>&1 | head -1))"
echo "Targets: ${EXISTING[*]}"
echo

if [ "$FIX" -eq 1 ]; then
    codespell --write-changes "${EXISTING[@]}"
    rc=$?
else
    codespell "${EXISTING[@]}"
    rc=$?
fi

if [ "$rc" -ne 0 ]; then
    echo
    echo "Recovery:"
    echo "  bash scripts/quality/codespell.sh --fix   # apply"
    echo "  # or add false-positives to .codespellrc → ignore-words-list"
    exit 1
fi

echo
echo "OK: no typos found."
exit 0
