#!/bin/bash

# Memory Constraint Integration Tests
# Created to verify the bounded channel fix (commit 0cf597f) that resolved memory growth
# 
# CONTEXT: Before fix, memory grew linearly with file size (60MB → 3.4GB for 100M events)
# due to unbounded channel buffering between RandomEmitter and WasotReconstructor threads.
# 
# PURPOSE: Ensures memory usage stays constant (~60MB) regardless of file size,
# validating the bounded channel solution maintains backpressure and prevents accumulation.

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
TEMP_DIR=$(mktemp -d)

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Test configuration based on memory benchmark analysis
# MAX_MEMORY_MB: Conservative limit well above expected ~60MB baseline
# Provides buffer for measurement variance while catching any memory leaks
MAX_MEMORY_MB=100

# Event counts chosen to stress-test the bounded channel fix:
# LARGE_FILE_EVENTS: Previously caused 343MB usage, now should stay ~60MB  
# HUGE_FILE_EVENTS: Previously caused 3.4GB usage, critical test for the fix
LARGE_FILE_EVENTS=10000000
HUGE_FILE_EVENTS=100000000

echo "🧪 Running Memory Constraint Integration Tests"
echo "=============================================="
echo "Project root: $PROJECT_ROOT"
echo "Temp directory: $TEMP_DIR"
echo "Max memory limit: ${MAX_MEMORY_MB}MB"
echo ""

# Function to run memory test and check constraint
run_memory_test() {
    local test_name="$1"
    local event_count="$2"
    local max_memory_mb="$3"
    local output_file="$4"
    
    echo -n "🔍 $test_name (${event_count} events, max ${max_memory_mb}MB): "
    
    # Convert MB to GB for the script (rounded up)
    local max_memory_gb=$(( (max_memory_mb + 1023) / 1024 ))
    if [ $max_memory_gb -eq 0 ]; then
        max_memory_gb=1
    fi
    
    # Run the memory measurement
    local result
    if [ -n "$output_file" ]; then
        # Test with file output
        result=$("$PROJECT_ROOT/scripts/measure_memory.sh" "$event_count" "$max_memory_gb" 2>/dev/null | tail -n1 | cut -d' ' -f1)
        # Clean up the output file
        [ -f "$output_file" ] && rm -f "$output_file"
    else
        # Test with stdout output
        result=$("$PROJECT_ROOT/scripts/measure_memory.sh" "$event_count" "$max_memory_gb" 2>/dev/null | tail -n1 | cut -d' ' -f1)
    fi
    
    # Check if result is a valid number
    if ! [[ "$result" =~ ^[0-9]+\.?[0-9]*$ ]]; then
        echo -e "${RED}ERROR - Invalid result: $result${NC}"
        return 1
    fi
    
    # Compare with limit (allowing for some measurement variance)
    local result_int=$(echo "$result" | cut -d'.' -f1)
    if [ "$result_int" -le "$max_memory_mb" ]; then
        echo -e "${GREEN}PASS${NC} (${result}MB)"
        return 0
    else
        echo -e "${RED}FAIL${NC} (${result}MB > ${max_memory_mb}MB)"
        return 1
    fi
}

# Test 1: Small file generation with memory constraint
echo "Test 1: Small file generation (stdout)"
if run_memory_test "Small file to stdout" 100000 "$MAX_MEMORY_MB" ""; then
    PASS_COUNT=$((PASS_COUNT + 1))
else
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# Test 2: Medium file generation with memory constraint  
echo "Test 2: Medium file generation (stdout)"
if run_memory_test "Medium file to stdout" 1000000 "$MAX_MEMORY_MB" ""; then
    PASS_COUNT=$((PASS_COUNT + 1))
else
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# Test 3: Large file generation with memory constraint
echo "Test 3: Large file generation (stdout)"
if run_memory_test "Large file to stdout" "$LARGE_FILE_EVENTS" "$MAX_MEMORY_MB" ""; then
    PASS_COUNT=$((PASS_COUNT + 1))
else
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# Test 4: File output generation with memory constraint
TEST_OUTPUT_FILE="$TEMP_DIR/test_output.wasot"
echo "Test 4: Large file generation (file output)"
if run_memory_test "Large file to file" "$LARGE_FILE_EVENTS" "$MAX_MEMORY_MB" "$TEST_OUTPUT_FILE"; then
    PASS_COUNT=$((PASS_COUNT + 1))
else
    FAIL_COUNT=$((FAIL_COUNT + 1))
fi

# Test 5: Huge file generation (stress test)
echo "Test 5: Huge file generation (stress test)"
if run_memory_test "Huge file to stdout" "$HUGE_FILE_EVENTS" "$MAX_MEMORY_MB" ""; then
    PASS_COUNT=$((PASS_COUNT + 1))
    echo -e "   ${GREEN}✓ Memory usage remains bounded even for very large files${NC}"
else
    FAIL_COUNT=$((FAIL_COUNT + 1))
    echo -e "   ${RED}✗ Memory constraint violated for huge files${NC}"
fi

# Initialize counters if not set
PASS_COUNT=${PASS_COUNT:-0}
FAIL_COUNT=${FAIL_COUNT:-0}
TOTAL_COUNT=$((PASS_COUNT + FAIL_COUNT))

# Summary
echo ""
echo "=============================================="
echo "📊 Memory Constraint Test Results"
echo "=============================================="
echo "Total tests: $TOTAL_COUNT"
echo -e "Passed: ${GREEN}$PASS_COUNT${NC}"
echo -e "Failed: ${RED}$FAIL_COUNT${NC}"

if [ $FAIL_COUNT -eq 0 ]; then
    echo -e "\n${GREEN}🎉 All memory constraint tests passed!${NC}"
    echo "✓ Random file generation maintains bounded memory usage"
    echo "✓ Memory usage stays under ${MAX_MEMORY_MB}MB regardless of file size"
else
    echo -e "\n${RED}❌ Some memory constraint tests failed${NC}"
    echo "⚠️  Memory usage may not be properly bounded"
fi

# Cleanup
rm -rf "$TEMP_DIR"

# Exit with error code if any tests failed
exit $FAIL_COUNT