#!/usr/bin/env bash
# =============================================================================
# run-distro-matrix.sh — Test toutes les stacks sur toutes les distributions
#
# Usage :
#   ./run-distro-matrix.sh                              # toutes stacks × toutes distros
#   ./run-distro-matrix.sh --stacks=nginx,apache        # stacks choisies
#   ./run-distro-matrix.sh --distros=el9,el10           # distros choisies
#   ./run-distro-matrix.sh --no-down                    # garder les stacks actives
#   ./run-distro-matrix.sh --fail-fast                  # arrêter au premier échec
#
# Variables d'environnement :
#   MATRIX_STACKS   — liste des stacks séparées par virgules (défaut: toutes)
#   MATRIX_DISTROS  — liste des distros séparées par virgules (défaut: el8,el9,el10)
# =============================================================================
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

log()  { echo -e "${CYAN}[matrix]${NC} $(date +%H:%M:%S) $*"; }
pass() { echo -e "${GREEN}  ✓ $*${NC}"; }
fail() { echo -e "${RED}  ✗ $*${NC}"; }
warn() { echo -e "${YELLOW}  ⚠ $*${NC}"; }

# ── Correspondance distro → image Docker ──────────────────────────────────────
declare -A DISTRO_IMAGES=(
    [el8]="almalinux:8"
    [el9]="rockylinux:9"
    [el10]="almalinux:10"
)

# ── Disponibilité des packages par distro ─────────────────────────────────────
# hitch n'est pas disponible sur el8 (pas dans EPEL 8)
declare -A STACK_SKIP=(
    [el8_hitch-varnish]="hitch non disponible dans EPEL 8"
)

# ── Valeurs par défaut ────────────────────────────────────────────────────────
ALL_STACKS=(apache nginx nginx-varnish hitch-varnish)
ALL_DISTROS=(el8 el9 el10)

STACKS=()
DISTROS=()
KEEP_UP=false
FAIL_FAST=false

# ── Parse des arguments ───────────────────────────────────────────────────────
for arg in "$@"; do
    case "$arg" in
        --stacks=*)
            IFS=',' read -ra STACKS <<< "${arg#--stacks=}" ;;
        --distros=*)
            IFS=',' read -ra DISTROS <<< "${arg#--distros=}" ;;
        --no-down)
            KEEP_UP=true ;;
        --fail-fast)
            FAIL_FAST=true ;;
    esac
done

# Utiliser les valeurs env si définies
if [ -n "${MATRIX_STACKS:-}" ]; then
    IFS=',' read -ra STACKS <<< "$MATRIX_STACKS"
fi
if [ -n "${MATRIX_DISTROS:-}" ]; then
    IFS=',' read -ra DISTROS <<< "$MATRIX_DISTROS"
fi

# Défauts
[ "${#STACKS[@]}"  -eq 0 ] && STACKS=("${ALL_STACKS[@]}")
[ "${#DISTROS[@]}" -eq 0 ] && DISTROS=("${ALL_DISTROS[@]}")

# ── Résultats ─────────────────────────────────────────────────────────────────
declare -A RESULTS  # RESULTS[distro_stack] = PASS|FAIL|SKIP

# ── Lancement de la matrice ───────────────────────────────────────────────────
TOTAL_PASS=0
TOTAL_FAIL=0
TOTAL_SKIP=0

log "============================================================"
log "${BOLD}MATRICE DE TESTS : ${#DISTROS[@]} distros × ${#STACKS[@]} stacks${NC}"
log "Distros : ${DISTROS[*]}"
log "Stacks  : ${STACKS[*]}"
log "============================================================"
echo ""

for distro in "${DISTROS[@]}"; do
    base_image="${DISTRO_IMAGES[$distro]:-}"
    if [ -z "$base_image" ]; then
        warn "Distro inconnue '$distro' — ignorée. Valides: ${!DISTRO_IMAGES[*]}"
        continue
    fi

    log "┌──────────────────────────────────────────────────────────"
    log "│ DISTRO : $distro (image: $base_image)"
    log "└──────────────────────────────────────────────────────────"

    for stack in "${STACKS[@]}"; do
        key="${distro}_${stack}"

        # Vérifier si cette combinaison est à ignorer
        skip_reason="${STACK_SKIP[$key]:-}"
        if [ -n "$skip_reason" ]; then
            warn "SKIP [$distro/$stack] : $skip_reason"
            RESULTS[$key]="SKIP"
            TOTAL_SKIP=$((TOTAL_SKIP + 1))
            continue
        fi

        runner="$SCRIPT_DIR/$stack/run-tests.sh"
        if [ ! -f "$runner" ]; then
            warn "Runner introuvable : $runner"
            RESULTS[$key]="MISSING"
            TOTAL_FAIL=$((TOTAL_FAIL + 1))
            continue
        fi
        chmod +x "$runner"

        log "  → Stack '$stack' sur $distro..."

        # Passer BASE_IMAGE via l'env + flag --no-down si demandé
        extra_args=()
        $KEEP_UP && extra_args+=(--no-down)

        set +e
        PLATFORM_BASE_IMAGE="$base_image" bash "$runner" "${extra_args[@]}"
        rc=$?
        set -e

        if [ $rc -eq 0 ]; then
            pass "[$distro/$stack] RÉUSSI"
            RESULTS[$key]="PASS"
            TOTAL_PASS=$((TOTAL_PASS + 1))
        else
            fail "[$distro/$stack] ÉCHOUÉ (exit $rc)"
            RESULTS[$key]="FAIL"
            TOTAL_FAIL=$((TOTAL_FAIL + 1))
            if $FAIL_FAST; then
                log "FAIL-FAST activé — arrêt."
                break 2
            fi
        fi
        echo ""
    done
    echo ""
done

# ── Résumé en tableau ─────────────────────────────────────────────────────────
log "============================================================"
log "${BOLD}RÉSUMÉ DE LA MATRICE${NC}"
log "============================================================"

# En-tête
printf "%-16s" "DISTRO \\ STACK"
for stack in "${STACKS[@]}"; do
    printf "  %-18s" "$stack"
done
echo ""
printf "%-16s" "----------------"
for stack in "${STACKS[@]}"; do
    printf "  %-18s" "------------------"
done
echo ""

for distro in "${DISTROS[@]}"; do
    printf "%-16s" "$distro"
    for stack in "${STACKS[@]}"; do
        key="${distro}_${stack}"
        result="${RESULTS[$key]:-N/A}"
        case "$result" in
            PASS)    printf "  ${GREEN}%-18s${NC}" "PASS ✓" ;;
            FAIL)    printf "  ${RED}%-18s${NC}" "FAIL ✗" ;;
            SKIP)    printf "  ${YELLOW}%-18s${NC}" "SKIP ⚠" ;;
            MISSING) printf "  ${YELLOW}%-18s${NC}" "MISSING" ;;
            *)       printf "  %-18s" "$result" ;;
        esac
    done
    echo ""
done

echo ""
log "Résultat global : ${GREEN}${TOTAL_PASS} PASS${NC} | ${RED}${TOTAL_FAIL} FAIL${NC} | ${YELLOW}${TOTAL_SKIP} SKIP${NC}"

if [ $TOTAL_FAIL -gt 0 ]; then
    exit 1
fi
exit 0
