#!/usr/bin/env bash
# tests/run-godot: Run Godot client test suite via gdUnit4 (D-030)
# Exit: 0 = all pass, non-zero = failure
# Stdout: {"suite":"godot","total":N,"passed":N,"failed":N,"duration_ms":N}
#
# --filter: accepts a test filename stem (e.g. "test_protocol" → runs test_protocol.gd only)
set -euo pipefail

FILTER=""
while [[ $# -gt 0 ]]; do
    case "$1" in
        --filter) FILTER="${2:-}"; shift 2 ;;
        --filter=*) FILTER="${1#--filter=}"; shift ;;
        *) echo "Unknown argument: $1" >&2; exit 2 ;;
    esac
done

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

GODOT=$(command -v godot4 2>/dev/null || command -v godot 2>/dev/null || echo "")
if [[ -z "$GODOT" ]]; then
    printf '{"suite":"godot","total":0,"passed":0,"failed":0,"duration_ms":0,"error":"godot not found in PATH"}\n'
    exit 1
fi

# Resolve the test target: directory or specific file
if [[ -n "$FILTER" ]]; then
    # Support bare name (test_protocol) or full path (test_protocol.gd)
    if [[ "$FILTER" == res://* ]]; then
        TEST_TARGET="$FILTER"
    elif [[ "$FILTER" == *.gd ]]; then
        TEST_TARGET="res://tests/$FILTER"
    else
        TEST_TARGET="res://tests/${FILTER}.gd"
    fi
else
    TEST_TARGET="res://tests/"
fi

START_MS=$(date +%s%3N)
TMPOUT=$(mktemp)

set +e
"$GODOT" --headless --path "$REPO_ROOT/client" \
    -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd \
    --ignoreHeadlessMode \
    -c \
    -a "$TEST_TARGET" \
    2>&1 | tee "$TMPOUT" >&2
EXIT_CODE=${PIPESTATUS[0]}
set -e

END_MS=$(date +%s%3N)
DURATION_MS=$((END_MS - START_MS))

_extract_num() {
    local haystack="$1" pattern="$2"
    echo "$haystack" | grep -oiE "[0-9]+ $pattern" | grep -oE '^[0-9]+' || echo 0
}

# gdUnit4 outputs per-suite statistics: "N test cases | X errors | Y failures | ..."
# and a summary: "Executed test cases : (X/N)" or "Executed test cases : (X/N), Z skipped"
TOTAL=0; PASSED=0; FAILED=0

# Sum errors + failures across all suite statistics lines
STATS_LINES=$(grep -oE "[0-9]+ test cases \| [0-9]+ errors \| [0-9]+ failures" "$TMPOUT" || true)
if [[ -n "$STATS_LINES" ]]; then
    TOTAL=$(echo "$STATS_LINES" | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
    ERRORS=$(echo "$STATS_LINES" | grep -oE '[0-9]+ errors' | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
    FAILURES=$(echo "$STATS_LINES" | grep -oE '[0-9]+ failures' | grep -oE '^[0-9]+' | awk '{s+=$1} END {print s}')
    FAILED=$(( ${ERRORS:-0} + ${FAILURES:-0} ))
    PASSED=$(( TOTAL - FAILED ))
fi

# Fallback: parse "Executed test cases : (X/N)" for total if stats parse failed
if [[ "$TOTAL" -eq 0 ]]; then
    EXEC_LINE=$(grep -oE "Executed test cases : \([0-9]+/[0-9]+\)" "$TMPOUT" | tail -1 || true)
    if [[ -n "$EXEC_LINE" ]]; then
        TOTAL=$(echo "$EXEC_LINE" | grep -oE '/[0-9]+\)' | grep -oE '[0-9]+')
        PASSED=$(echo "$EXEC_LINE" | grep -oE '\([0-9]+/' | grep -oE '[0-9]+')
        FAILED=$(( TOTAL - PASSED ))
    fi
fi

rm -f "$TMPOUT"
printf '{"suite":"godot","total":%d,"passed":%d,"failed":%d,"duration_ms":%d}\n' \
    "${TOTAL:-0}" "${PASSED:-0}" "${FAILED:-0}" "$DURATION_MS"
exit $EXIT_CODE
