#!/usr/bin/env bash
# Tests para cuda_toolkit_check
# Smoke: verifica que stdout contiene todas las keys requeridas y exit code 0.
set -uo pipefail
# Nota: set -e NO se usa para que los asserts fallen de forma acumulativa
# en lugar de abortar el script al primer fallo.

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../cuda_toolkit_check.sh"

PASS=0
FAIL=0

assert_eq() {
    local test_name="$1" expected="$2" got="$3"
    if [[ "$expected" == "$got" ]]; then
        echo "PASS: $test_name"
        ((PASS++)) || true
    else
        echo "FAIL: $test_name — expected '$expected', got '$got'"
        ((FAIL++)) || true
    fi
}

assert_contains() {
    local test_name="$1" needle="$2" haystack="$3"
    if echo "$haystack" | grep -qF "$needle"; then
        echo "PASS: $test_name"
        ((PASS++)) || true
    else
        echo "FAIL: $test_name — '$needle' not found in output"
        ((FAIL++)) || true
    fi
}

assert_matches_pattern() {
    local test_name="$1" pattern="$2" value="$3"
    if echo "$value" | grep -qE "$pattern"; then
        echo "PASS: $test_name"
        ((PASS++)) || true
    else
        echo "FAIL: $test_name — '$value' does not match pattern '$pattern'"
        ((FAIL++)) || true
    fi
}

assert_nonempty() {
    local test_name="$1" value="$2"
    if [[ -n "$value" ]]; then
        echo "PASS: $test_name"
        ((PASS++)) || true
    else
        echo "FAIL: $test_name — valor vacio"
        ((FAIL++)) || true
    fi
}

# --- Capturar salida ---
OUTPUT="$(cuda_toolkit_check)"
EXIT_CODE=$?

# --- Test: exit code 0 ---
assert_eq "exit code es 0" "0" "$EXIT_CODE"

# --- Test: stdout contiene clave nvcc= ---
assert_contains "stdout contiene clave nvcc=" "nvcc=" "$OUTPUT"

# --- Test: stdout contiene clave nvidia_smi= ---
assert_contains "stdout contiene clave nvidia_smi=" "nvidia_smi=" "$OUTPUT"

# --- Test: stdout contiene clave driver_version= ---
assert_contains "stdout contiene clave driver_version=" "driver_version=" "$OUTPUT"

# --- Test: stdout contiene clave cuda_libs= ---
assert_contains "stdout contiene clave cuda_libs=" "cuda_libs=" "$OUTPUT"

# --- Test: stdout contiene clave overall= ---
assert_contains "stdout contiene clave overall=" "overall=" "$OUTPUT"

# --- Test: overall tiene valor valido (ok|partial|missing) ---
OVERALL_VAL="$(echo "$OUTPUT" | grep '^overall=' | cut -d= -f2)"
assert_matches_pattern "overall tiene valor valido ok|partial|missing" "^(ok|partial|missing)$" "$OVERALL_VAL"

# --- Test: nvcc tiene valor no vacio ---
NVCC_VAL="$(echo "$OUTPUT" | grep '^nvcc=' | cut -d= -f2)"
assert_nonempty "nvcc tiene valor no vacio" "$NVCC_VAL"

# --- Test: nvidia_smi tiene valor valido (present|missing) ---
SMI_VAL="$(echo "$OUTPUT" | grep '^nvidia_smi=' | cut -d= -f2)"
assert_matches_pattern "nvidia_smi tiene valor valido present|missing" "^(present|missing)$" "$SMI_VAL"

# --- Test: driver_version tiene valor no vacio ---
DRV_VAL="$(echo "$OUTPUT" | grep '^driver_version=' | cut -d= -f2)"
assert_nonempty "driver_version tiene valor no vacio" "$DRV_VAL"

# --- Test: cuda_libs tiene valor no vacio ---
LIBS_VAL="$(echo "$OUTPUT" | grep '^cuda_libs=' | cut -d= -f2)"
assert_nonempty "cuda_libs tiene valor no vacio" "$LIBS_VAL"

# --- Test: exactamente 5 lineas en la salida ---
LINE_COUNT="$(echo "$OUTPUT" | wc -l | tr -d ' ')"
assert_eq "salida tiene exactamente 5 lineas" "5" "$LINE_COUNT"

# --- Test: segunda invocacion idempotente (mismo resultado) ---
OUTPUT2="$(cuda_toolkit_check)"
assert_eq "segunda invocacion produce mismo resultado (idempotente)" "$OUTPUT" "$OUTPUT2"

# --- Resumen ---
echo "---"
echo "Results: $PASS passed, $FAIL failed"
[[ $FAIL -eq 0 ]] || exit 1
