#!/usr/bin/env bash
# scripts/quality/cgal-version-matrix.sh
#
# Build and test the CGAL test suite against multiple CGAL versions in
# sequence.  Catches:
#   * upstream API drift between minor CGAL releases (5.x vs 6.x)
#   * Surface_mesh / Polyhedron_3 trait-class changes
#   * deprecated CGAL macros we still rely on
#
# Local-only.  The script expects each CGAL version to live under
# `~/cgal/<version>/` (override with CGAL_ROOTS env var as a colon-list).
# If the directory tree is missing it prints the expected layout and
# exits 2 — it does not download anything (that would belong in a Docker
# image, see .gitea/docker/Dockerfile.ci-cpp).
#
# Usage:
#   bash scripts/quality/cgal-version-matrix.sh
#   CGAL_ROOTS=/opt/cgal-5.6:/opt/cgal-6.0  bash scripts/quality/cgal-version-matrix.sh
#
# Exit codes:
#   0  every requested CGAL version builds + tests cleanly
#   1  at least one version failed
#   2  no CGAL roots found

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

# ── Discover CGAL installs ──────────────────────────────────────────────────
DEFAULT_ROOTS="$HOME/cgal/5.6:$HOME/cgal/6.0:$HOME/cgal/6.1:/opt/cgal-5.6:/opt/cgal-6.0"
ROOTS="${CGAL_ROOTS:-$DEFAULT_ROOTS}"

# Collect existing paths.
AVAILABLE=""
OLD_IFS="$IFS"
IFS=":"
for r in $ROOTS; do
    if [ -f "$r/cmake/modules/UseCGAL.cmake" ] || [ -f "$r/include/CGAL/version.h" ] || [ -f "$r/CMakeLists.txt" ]; then
        AVAILABLE="${AVAILABLE}${r}
"
    fi
done
IFS="$OLD_IFS"

if [ -z "$AVAILABLE" ]; then
    cat >&2 <<EOF
FAIL: no CGAL installs found.

Searched: $ROOTS

Expected layout for each version (any one of these is enough):
    <root>/include/CGAL/version.h
    <root>/cmake/modules/UseCGAL.cmake
    <root>/CMakeLists.txt

Recovery (one-time, on the dev machine):
    cd ~/cgal && wget https://github.com/CGAL/cgal/archive/refs/tags/v5.6.tar.gz
    tar xf v5.6.tar.gz && mv cgal-5.6 5.6
    # repeat for v6.0, v6.1

Then re-run:
    bash scripts/quality/cgal-version-matrix.sh

Or override the lookup path:
    CGAL_ROOTS=/opt/cgal-5.6:/opt/cgal-6.0 bash scripts/quality/cgal-version-matrix.sh
EOF
    exit 2
fi

echo "========================================"
echo "  CGAL version matrix"
echo "  versions tested:"
echo "$AVAILABLE" | sed 's/^/    /'
echo "========================================"

# Failures are recorded in $ROOT/.cgal-matrix-failures because the
# while-loop runs in a subshell (consequence of the pipe from echo), so
# a plain `overall=0; overall=1` would not survive back to the parent.
rm -f "$ROOT/.cgal-matrix-failures"

echo "$AVAILABLE" | while IFS= read -r cgal_root; do
    [ -z "$cgal_root" ] && continue
    ver="$(basename "$cgal_root")"
    build="build-cgal-$ver"
    echo
    echo "── CGAL $ver  ─────────────────────────────"
    echo "    root:  $cgal_root"
    echo "    build: $build"

    if ! cmake -S code -B "$build" \
        -DCGAL_DIR="$cgal_root" \
        -DWITH_CGAL_TESTS=ON \
        -DCMAKE_BUILD_TYPE=Release \
        -Wno-dev >/dev/null 2>&1; then
        echo "    CONFIGURE FAILED"
        echo "$ver" >> "$ROOT/.cgal-matrix-failures"
        continue
    fi

    if ! nice -n 19 cmake --build "$build" --target conformallab_cgal_tests \
        -j1 >"$build/build.log" 2>&1; then
        echo "    BUILD FAILED — see $build/build.log"
        echo "$ver" >> "$ROOT/.cgal-matrix-failures"
        continue
    fi

    if ! ( cd "$build" && ctest -R "^cgal\." --output-on-failure >"test.log" 2>&1 ); then
        echo "    TESTS FAILED — see $build/test.log"
        echo "$ver" >> "$ROOT/.cgal-matrix-failures"
        continue
    fi

    pass=$(grep -oE "tests passed.*out of [0-9]+" "$build/test.log" | head -1)
    echo "    OK  ($pass)"
done

if [ -f "$ROOT/.cgal-matrix-failures" ]; then
    echo
    echo "FAIL: the following CGAL versions did not pass:"
    sed 's/^/    /' "$ROOT/.cgal-matrix-failures"
    rm -f "$ROOT/.cgal-matrix-failures"
    exit 1
fi

echo
echo "OK: every detected CGAL version built + passed the CGAL test suite."
exit 0
