#!/usr/bin/env bash

# Test for parallel task execution reliability (GitHub issue #5451)
# This test verifies that tasks with ::: syntax run concurrently rather than sequentially

set -euo pipefail

# Create a temporary file to track task execution order and timing
temp_log=$(mktemp)
trap 'rm -f $temp_log' EXIT

cat <<EOF >mise.toml
[tools]
poetry = "latest"

[tasks.process1]
run = '''
echo "\$(date +%s%N) process1 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process1 end" >> $temp_log
echo "process1 complete"
'''

[tasks.process2]
run = '''
echo "\$(date +%s%N) process2 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process2 end" >> $temp_log
echo "process2 complete"
'''

[tasks.process3]
run = '''
echo "\$(date +%s%N) process3 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process3 end" >> $temp_log
echo "process3 complete"
'''

[tasks.process4]
run = '''
echo "\$(date +%s%N) process4 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process4 end" >> $temp_log
echo "process4 complete"
'''

[tasks.process5]
run = '''
echo "\$(date +%s%N) process5 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process5 end" >> $temp_log
echo "process5 complete"
'''

[tasks.process6]
run = '''
echo "\$(date +%s%N) process6 start" >> $temp_log
sleep 2
echo "\$(date +%s%N) process6 end" >> $temp_log
echo "process6 complete"
'''

[tasks.run-all]
run = "mise run process1 ::: process2 ::: process3 ::: process4 ::: process5 ::: process6"
EOF

assert "mise install"

echo "Testing parallel task execution (running 3 times for reliability)..."

# Run the test 3 times to ensure reliability
for test_run in {1..3}; do
	echo ""
	echo "=== Test Run $test_run/3 ==="

	# Clear the log file for each run
	rm -f "$temp_log"

	# Record start time for overall execution time measurement
	start_time=$(date +%s)

	# Run the tasks and capture output
	task_output=$(mise run run-all)

	# Record end time
	end_time=$(date +%s)
	total_time=$((end_time - start_time))

	echo "Total execution time: ${total_time}s"

	# Read the log file to analyze timing
	echo "Task execution log:"
	cat "$temp_log" | sort

	# Parse start times to check if tasks started concurrently
	mapfile -t start_times < <(grep "start" "$temp_log" | awk '{print $1}' | sort -n)
	mapfile -t end_times < <(grep "end" "$temp_log" | awk '{print $1}' | sort -n)

	echo "Analyzing task start times..."

	if [ ${#start_times[@]} -ne 6 ]; then
		echo "ERROR: Expected 6 task start times, got ${#start_times[@]}"
		exit 1
	fi

	if [ ${#end_times[@]} -ne 6 ]; then
		echo "ERROR: Expected 6 task end times, got ${#end_times[@]}"
		exit 1
	fi

	# Calculate time differences between task starts (in nanoseconds)
	# For parallel execution, all tasks should start within a small window (< 1 second)
	first_start=${start_times[0]}
	last_start=${start_times[5]}
	start_spread=$((last_start - first_start))

	# Convert nanoseconds to milliseconds for easier interpretation
	start_spread_ms=$((start_spread / 1000000))

	echo "Time between first and last task start: ${start_spread_ms}ms"

	# Check if tasks started in parallel (within 1 second = 1000ms)
	if [ $start_spread_ms -gt 1000 ]; then
		echo "WARNING: Tasks may not be running in parallel. Start spread: ${start_spread_ms}ms"
		echo "This could indicate the original issue is still present."
	else
		echo "✓ Tasks started concurrently (within ${start_spread_ms}ms)"
	fi

	# Critical check: Ensure all tasks start before any task completes
	# This is essential for true parallel execution
	echo "Checking that all tasks start before any complete..."
	last_start_time=${start_times[5]}
	first_end_time=${end_times[0]}

	if [ "$last_start_time" -gt "$first_end_time" ]; then
		echo "ERROR: Some tasks completed before all tasks started!"
		echo "Last task started at: $last_start_time"
		echo "First task completed at: $first_end_time"
		echo "This indicates sequential execution, not parallel execution."
		exit 1
	else
		echo "✓ All tasks started before any completed - confirming parallel execution"
	fi

	# Check total execution time
	# If running sequentially: 6 tasks * 2 seconds = ~12 seconds
	# If running in parallel: ~2-3 seconds (plus overhead)
	if [ $total_time -gt 8 ]; then
		echo "ERROR: Total execution time too long (${total_time}s). Tasks appear to be running sequentially."
		echo "Expected: ~2-4 seconds for parallel execution"
		echo "Got: ${total_time}s (suggests sequential execution)"
		exit 1
	else
		echo "✓ Total execution time acceptable (${total_time}s) - suggests parallel execution"
	fi

	# Verify all tasks completed successfully using the captured output
	for i in {1..6}; do
		if ! grep -q "process${i} complete" <<<"$task_output"; then
			echo "ERROR: process${i} did not complete successfully"
			exit 1
		fi
	done

	echo "✓ All tasks completed successfully in test run $test_run"
done

echo ""
echo "✓ All 3 test runs passed - Parallel task execution test passed"
