#!/usr/bin/env bash

# Script to generate a CMake fragment listing all tests in the YAML test suite
# This allows registering tests even before the test data is downloaded

set -e

# Default values
TESTSUITEURL="${TESTSUITEURL:-https://github.com/yaml/yaml-test-suite}"
TESTSUITECHECKOUT="${TESTSUITECHECKOUT:-6e6c296ae9c9d2d5c4134b4b64d01b29ac19ff6f}"
OUTPUT_FILE="${1:-testsuite-tests.cmake}"

usage() {
    cat << EOF
Usage: $0 [OUTPUT_FILE]

Generate a CMake fragment listing all tests in the YAML test suite.

Arguments:
    OUTPUT_FILE     Output file path (default: testsuite-tests.cmake)

Environment variables:
    TESTSUITEURL        URL of the test suite repository
    TESTSUITECHECKOUT   Git commit/tag to use

Example:
    $0 cmake/testsuite-tests.cmake
EOF
    exit 1
}

if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
    usage
fi

echo "Generating testsuite list from ${TESTSUITEURL} @ ${TESTSUITECHECKOUT}"

# Create a temporary directory
TMPDIR=$(mktemp -d)
trap "rm -rf $TMPDIR" EXIT

# Check if we have a local test-suite-data directory to use
LOCAL_DATA=""
for dir in "build/test/test-suite-data" "test-suite-data" "../build/test/test-suite-data"; do
    if [ -d "$dir" ]; then
        LOCAL_DATA="$dir"
        echo "Using local test data from: $LOCAL_DATA"
        break
    fi
done

if [ -n "$LOCAL_DATA" ]; then
    # Use local data
    find "$LOCAL_DATA" -maxdepth 1 -type d -name '[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]' | \
        xargs -n1 basename | sort > "$TMPDIR/base_tests.txt"

    # For each base test, check for subtests
    > "$TMPDIR/all_tests.txt"
    while IFS= read -r base; do
        # Check for base test
        if [ -f "$LOCAL_DATA/$base/===" ]; then
            echo "$base" >> "$TMPDIR/all_tests.txt"
        fi

        # Check for 2-digit subtests
        for subtest in "$LOCAL_DATA/$base"/[0-9][0-9]; do
            if [ -d "$subtest" ] && [ -f "$subtest/===" ]; then
                echo "$base/$(basename $subtest)" >> "$TMPDIR/all_tests.txt"
            fi
        done

        # Check for 3-digit subtests
        for subtest in "$LOCAL_DATA/$base"/[0-9][0-9][0-9]; do
            if [ -d "$subtest" ] && [ -f "$subtest/===" ]; then
                echo "$base/$(basename $subtest)" >> "$TMPDIR/all_tests.txt"
            fi
        done
    done < "$TMPDIR/base_tests.txt"
else
    # Clone from git
    echo "No local data found, cloning from git repository..."
    cd "$TMPDIR"
    git clone --depth 1 --filter=blob:none --sparse "${TESTSUITEURL}" repo
    cd repo
    git checkout "${TESTSUITECHECKOUT}"
    git sparse-checkout disable

    # List all base test directories
    find . -maxdepth 1 -type d -name '[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]' | \
        sed 's|^\./||' | sort > "$TMPDIR/base_tests.txt"

    # For each base test, check for subtests
    > "$TMPDIR/all_tests.txt"
    while IFS= read -r base; do
        # Check for base test
        if [ -f "$base/===" ]; then
            echo "$base" >> "$TMPDIR/all_tests.txt"
        fi

        # Check for 2-digit subtests
        for subtest in "$base"/[0-9][0-9]; do
            if [ -d "$subtest" ] && [ -f "$subtest/===" ]; then
                echo "$base/$(basename $subtest)" >> "$TMPDIR/all_tests.txt"
            fi
        done

        # Check for 3-digit subtests
        for subtest in "$base"/[0-9][0-9][0-9]; do
            if [ -d "$subtest" ] && [ -f "$subtest/===" ]; then
                echo "$base/$(basename $subtest)" >> "$TMPDIR/all_tests.txt"
            fi
        done
    done < "$TMPDIR/base_tests.txt"
fi

# Read test counts
BASE_COUNT=$(wc -l < "$TMPDIR/base_tests.txt")
if [ -f "$TMPDIR/all_tests.txt" ]; then
    ALL_COUNT=$(wc -l < "$TMPDIR/all_tests.txt")
else
    ALL_COUNT=0
fi

echo "Found $BASE_COUNT base tests"
echo "Found $ALL_COUNT total tests (including subtests)"

# Generate CMake fragment
cat > "$OUTPUT_FILE" << 'EOF'
# Auto-generated file - do not edit manually
# Generated by cmake/generate-testsuite-list.sh
#
# This file contains lists of tests from the YAML test suite
# It allows registering individual tests without requiring the test data
# to be downloaded first.

EOF

echo "# Test suite checkout: ${TESTSUITECHECKOUT}" >> "$OUTPUT_FILE"
echo "# Generated on: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> "$OUTPUT_FILE"
echo "# Base tests: ${BASE_COUNT}" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"

# Write base test list
echo "# List of base test IDs" >> "$OUTPUT_FILE"
echo "set(TESTSUITE_BASE_TESTS" >> "$OUTPUT_FILE"
while IFS= read -r test; do
    echo "    $test" >> "$OUTPUT_FILE"
done < "$TMPDIR/base_tests.txt"
echo ")" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"

if [ -f "$TMPDIR/all_tests.txt" ]; then
    echo "# List of all tests (including subtests)" >> "$OUTPUT_FILE"
    echo "# Format: BASE or BASE/SUBTEST" >> "$OUTPUT_FILE"
    echo "set(TESTSUITE_ALL_TESTS" >> "$OUTPUT_FILE"
    while IFS= read -r test; do
        echo "    \"$test\"" >> "$OUTPUT_FILE"
    done < "$TMPDIR/all_tests.txt"
    echo ")" >> "$OUTPUT_FILE"
fi

echo "Generated $OUTPUT_FILE successfully!"
echo "Total base tests: $BASE_COUNT"
[ $ALL_COUNT -gt 0 ] && echo "Total tests (with subtests): $ALL_COUNT"
