#!/usr/bin/env bash
# scripts/quality/run-all.sh
#
# Run every local quality gate in sequence.  Each gate is independent;
# a failure does not stop the rest (we collect failures and report at
# the end).  Use this before tagging a release or before showing the
# repo to an external reviewer.
#
# Wall-time budget on a typical dev laptop (M-series Mac):
#   license-headers.sh       ~1 s
#   check-markdown-links.py  ~2 s
#   sanitizers.sh            ~3 min
#   coverage.sh              ~2 min
#   clang-tidy.sh            ~2 min  (depends on header count)
#   multi-compiler.sh        ~5 min  (per compiler)
#   reproducible-build.sh    ~6 min
#   cgal-version-matrix.sh   ~5 min per CGAL version
#   ─────────────────────────────
#   TOTAL                    ~25–40 min
#
# Usage:
#   bash scripts/quality/run-all.sh           # everything
#   bash scripts/quality/run-all.sh --fast    # skip the slow gates
#                                              (cgal-matrix, multi-compiler,
#                                               coverage, reproducible)
#
# Exit code: number of failed gates (so 0 = green).

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

FAST=0
[ "${1:-}" = "--fast" ] && FAST=1

GATES_FAST=(
    "License headers     | bash scripts/quality/license-headers.sh"
    "Doc freshness       | bash scripts/quality/check-doc-freshness.sh"
    "CGAL conventions    | python3 scripts/quality/cgal-conventions.py"
    "clang-format drift  | bash scripts/quality/clang-format.sh"
    "cmake-format/-lint  | bash scripts/quality/cmake-format.sh"
    "codespell           | bash scripts/quality/codespell.sh"
    "shellcheck          | bash scripts/quality/shellcheck.sh"
    "cppcheck            | bash scripts/quality/cppcheck.sh"
    "Markdown links      | python3 scripts/check-markdown-links.py"
    "Sanitizers          | bash scripts/quality/sanitizers.sh"
    "clang-tidy          | bash scripts/quality/clang-tidy.sh"
)
GATES_SLOW=(
    "Coverage            | bash scripts/quality/coverage.sh"
    "Multi-compiler      | bash scripts/quality/multi-compiler.sh"
    "Reproducible build  | bash scripts/quality/reproducible-build.sh"
    "CGAL version matrix | bash scripts/quality/cgal-version-matrix.sh"
)

if [ "$FAST" -eq 1 ]; then
    GATES=("${GATES_FAST[@]}")
else
    GATES=("${GATES_FAST[@]}" "${GATES_SLOW[@]}")
fi

LOG_DIR="build-quality-logs"
mkdir -p "$LOG_DIR"

echo "============================================================"
echo "  conformallab++ local quality gates"
echo "  mode:  $([ $FAST -eq 1 ] && echo 'FAST (4 gates)' || echo "FULL (${#GATES[@]} gates)")"
echo "  logs:  $LOG_DIR/"
echo "============================================================"

results=""
failed=0
skipped=0
i=0
for entry in "${GATES[@]}"; do
    i=$((i + 1))
    name="${entry%%|*}"
    name="${name%%[[:space:]]*([[:space:]])}"   # trim trailing space
    cmd="${entry##*|}"
    cmd="${cmd##[[:space:]]}"
    # Slug-safe filename
    slug=$(echo "$name" | tr ' /[:upper:]' '_-[:lower:]' | tr -cd 'a-z0-9_-')
    log="$LOG_DIR/$slug.log"
    echo
    echo "──── [$i/${#GATES[@]}] $name  ────"
    eval "$cmd" >"$log" 2>&1
    rc=$?
    # Exit code 2 from any of our gate scripts = "prerequisite missing"
    # (tool not in PATH, no CGAL tarball, no second compiler, etc.).
    # Treat as SKIP rather than FAIL so a partial dev environment can
    # still run the rest of the sweep.
    if [ "$rc" -eq 2 ] && head -3 "$log" | grep -qE "FAIL:.*(not (in PATH|installed|found)|no .* found)"; then
        echo "    SKIP   (tool not installed — see $log)"
        results="${results}  SKIP  $name  (missing tool)
"
        skipped=$((skipped + 1))
    elif [ "$rc" -eq 0 ]; then
        echo "    OK     ($log)"
        results="${results}  PASS  $name
"
    else
        echo "    FAIL (rc=$rc) — see $log"
        echo "    last 20 lines:"
        tail -20 "$log" | sed 's/^/      /'
        results="${results}  FAIL  $name  ($log)
"
        failed=$((failed + 1))
    fi
done

echo
echo "============================================================"
echo "  Summary"
echo "============================================================"
printf "%s" "$results"
echo
echo "  passed:  $((${#GATES[@]} - failed - skipped)) / ${#GATES[@]}"
echo "  skipped: $skipped     (tool not installed; gate is local-only)"
echo "  failed:  $failed"
exit $failed
