#!/usr/bin/env bash
# scripts/quality/multi-compiler.sh
#
# Build and test the fast (non-CGAL) suite against multiple C++
# compilers in sequence.  Catches compiler-specific issues:
#   * gcc-only extensions accidentally used
#   * clang's stricter template-error handling
#   * libstdc++ vs libc++ ABI assumptions
#
# Local-only.  Each compiler gets its own build-multi-<cc>/ directory.
#
# Usage:
#   bash scripts/quality/multi-compiler.sh              # auto-detect
#   bash scripts/quality/multi-compiler.sh g++ clang++  # specific list
#
# Exit codes:
#   0  every detected/selected compiler builds + tests cleanly
#   1  at least one compiler failed
#   2  fewer than 2 compilers available

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

# ── Pick compilers ──────────────────────────────────────────────────────────
if [ $# -gt 0 ]; then
    COMPILERS=("$@")
else
    COMPILERS=()
    for cand in g++ g++-13 g++-12 g++-11 clang++ clang++-17 clang++-16 clang++-15; do
        if command -v "$cand" >/dev/null 2>&1; then
            COMPILERS+=("$cand")
        fi
    done
fi

if [ "${#COMPILERS[@]}" -lt 1 ]; then
    echo "FAIL: no C++ compilers detected.  Install gcc and/or clang." >&2
    exit 2
fi

echo "========================================"
echo "  Multi-compiler build matrix"
echo "  compilers: ${COMPILERS[*]}"
echo "========================================"
echo

# De-duplicate by resolving each to its absolute path.
declare -a UNIQ_BINS=()
declare -a UNIQ_NAMES=()
seen=""
for cc in "${COMPILERS[@]}"; do
    if ! command -v "$cc" >/dev/null 2>&1; then
        echo "  skip   $cc  (not in PATH)"
        continue
    fi
    full="$(command -v "$cc")"
    if echo "$seen" | grep -qx "$full"; then
        continue
    fi
    seen="$seen
$full"
    UNIQ_BINS+=("$full")
    # Use a sanitised name for the build dir (replace + and / etc.).
    safe="$(echo "$cc" | sed 's|[/+]|_|g')"
    UNIQ_NAMES+=("$safe")
done

if [ "${#UNIQ_BINS[@]}" -lt 2 ]; then
    echo "WARNING: only ${#UNIQ_BINS[@]} unique compiler(s) — matrix is degenerate."
    echo "         (continuing anyway; install a second toolchain for full coverage)"
fi

# ── Run each ────────────────────────────────────────────────────────────────
overall=0
i=0
for cc in "${UNIQ_BINS[@]}"; do
    name="${UNIQ_NAMES[$i]}"
    i=$((i + 1))
    build="build-multi-$name"
    echo
    echo "── [$i/${#UNIQ_BINS[@]}] $name  ─────────────────────"
    echo "    bin:   $cc"
    echo "    build: $build"

    if ! cmake -S code -B "$build" \
        -DCMAKE_CXX_COMPILER="$cc" \
        -DCMAKE_BUILD_TYPE=Release \
        -Wno-dev >/dev/null 2>&1; then
        echo "    CONFIGURE FAILED"
        overall=1
        continue
    fi

    if ! nice -n 19 cmake --build "$build" --target conformallab_tests \
        -j"$(nproc 2>/dev/null || sysctl -n hw.logicalcpu 2>/dev/null || echo 2)" \
        >"$build/build.log" 2>&1; then
        echo "    BUILD FAILED — see $build/build.log"
        overall=1
        continue
    fi

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

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

echo
if [ $overall -eq 0 ]; then
    echo "OK: every selected compiler built + passed the fast test suite."
else
    echo "FAIL: at least one compiler did not produce a green test run."
fi
exit $overall
