#!/bin/bash
# Test script for CLI options - Parallel execution
# Tests -u, -uN, -r, -b flags

set -u  # Exit on undefined variables

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

# Test results directory (for parallel safety)
TEST_RESULTS_DIR="/tmp/cli-test-results-$$"
mkdir -p "$TEST_RESULTS_DIR"

# Cleanup function
cleanup() {
    echo ""
    echo "=== Cleaning up test directories ==="
    rm -rf /tmp/cli-test-* 2>/dev/null || true
    rm -rf "$TEST_RESULTS_DIR" 2>/dev/null || true
    # Kill any hanging processes
    pkill -f "changedetection.py.*cli-test" 2>/dev/null || true
}
trap cleanup EXIT

# Helper to record test result
record_result() {
    local test_num=$1
    local status=$2  # pass or fail
    local message=$3

    echo "$status|$message" > "$TEST_RESULTS_DIR/test_${test_num}.result"
}

# Run a test in background
run_test() {
    local test_num=$1
    local test_name=$2
    local test_func=$3

    (
        echo -e "${YELLOW}[Test $test_num]${NC} $test_name"
        if $test_func "$test_num"; then
            record_result "$test_num" "pass" "$test_name"
            echo -e "${GREEN}✓ PASS${NC}: $test_name"
        else
            record_result "$test_num" "fail" "$test_name"
            echo -e "${RED}✗ FAIL${NC}: $test_name"
        fi
    ) &
}

# =============================================================================
# Test Functions (each runs independently)
# =============================================================================

test_help_flag() {
    local test_id=$1
    timeout 3 python3 changedetection.py --help 2>&1 | grep -q "Add URLs on startup"
}

test_version_flag() {
    local test_id=$1
    timeout 3 python3 changedetection.py --version 2>&1 | grep -qE "changedetection.io [0-9]+\.[0-9]+"
}

test_single_url() {
    local test_id=$1
    local dir="/tmp/cli-test-single-${test_id}-$$"
    timeout 10 python3 changedetection.py -d "$dir" -C -u https://example.com -b &>/dev/null
    # Count watch directories (UUID directories containing watch.json)
    [ "$(find "$dir" -mindepth 2 -maxdepth 2 -name 'watch.json' | wc -l)" -eq 1 ]
}

test_multiple_urls() {
    local test_id=$1
    local dir="/tmp/cli-test-multi-${test_id}-$$"
    timeout 12 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u https://github.com \
        -u https://httpbin.org \
        -b &>/dev/null
    # Count watch directories (UUID directories containing watch.json)
    [ "$(find "$dir" -mindepth 2 -maxdepth 2 -name 'watch.json' | wc -l)" -eq 3 ]
}

test_url_with_options() {
    local test_id=$1
    local dir="/tmp/cli-test-opts-${test_id}-$$"
    timeout 10 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u0 '{"title":"Test Site","processor":"text_json_diff"}' \
        -b &>/dev/null
    # Check that at least one watch.json contains the title "Test Site"
    python3 -c "
import json, glob, sys
watch_files = glob.glob('$dir/*/watch.json')
for wf in watch_files:
    with open(wf) as f:
        data = json.load(f)
        if data.get('title') == 'Test Site':
            sys.exit(0)
sys.exit(1)
"
}

test_multiple_urls_with_options() {
    local test_id=$1
    local dir="/tmp/cli-test-multi-opts-${test_id}-$$"
    timeout 12 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u0 '{"title":"Site One"}' \
        -u https://github.com \
        -u1 '{"title":"Site Two"}' \
        -b &>/dev/null
    # Check that we have 2 watches and both titles are present
    python3 -c "
import json, glob, sys
watch_files = glob.glob('$dir/*/watch.json')
if len(watch_files) != 2:
    sys.exit(1)
titles = []
for wf in watch_files:
    with open(wf) as f:
        data = json.load(f)
        titles.append(data.get('title'))
sys.exit(0 if 'Site One' in titles and 'Site Two' in titles else 1)
"
}

test_batch_mode_exit() {
    local test_id=$1
    local dir="/tmp/cli-test-batch-${test_id}-$$"
    local start=$(date +%s)
    timeout 15 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -b &>/dev/null
    local end=$(date +%s)
    local elapsed=$((end - start))
    [ $elapsed -lt 14 ]
}

test_recheck_all() {
    local test_id=$1
    local dir="/tmp/cli-test-recheck-all-${test_id}-$$"
    # Create a watch using CLI, then recheck it
    timeout 10 python3 changedetection.py -d "$dir" -C -u https://example.com -b &>/dev/null
    # Now recheck all watches
    timeout 10 python3 changedetection.py -d "$dir" -r all -b 2>&1 | grep -q "Queuing"
}

test_recheck_specific() {
    local test_id=$1
    local dir="/tmp/cli-test-recheck-uuid-${test_id}-$$"
    # Create 2 watches using CLI
    timeout 12 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u https://github.com \
        -b &>/dev/null
    # Get the UUIDs that were created
    local uuids=$(find "$dir" -mindepth 2 -maxdepth 2 -name 'watch.json' -exec dirname {} \; | xargs -n1 basename | tr '\n' ',' | sed 's/,$//')
    # Now recheck specific UUIDs
    timeout 10 python3 changedetection.py -d "$dir" -r "$uuids" -b 2>&1 | grep -q "Queuing"
}

test_combined_operations() {
    local test_id=$1
    local dir="/tmp/cli-test-combined-${test_id}-$$"
    timeout 12 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u https://github.com \
        -r all \
        -b &>/dev/null
    # Count watch directories (UUID directories containing watch.json)
    [ "$(find "$dir" -mindepth 2 -maxdepth 2 -name 'watch.json' | wc -l)" -eq 2 ]
}

test_invalid_json() {
    local test_id=$1
    local dir="/tmp/cli-test-invalid-${test_id}-$$"
    timeout 5 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -u0 'invalid json here' \
        2>&1 | grep -qi "invalid json\|json decode error"
}

test_create_directory() {
    local test_id=$1
    local dir="/tmp/cli-test-create-${test_id}-$$/nested/path"
    timeout 10 python3 changedetection.py -d "$dir" -C \
        -u https://example.com \
        -b &>/dev/null
    [ -d "$dir" ]
}

# =============================================================================
# Main Test Execution
# =============================================================================

echo "=========================================="
echo "  CLI Options Test Suite (Parallel)"
echo "=========================================="
echo ""

# Launch all tests in parallel
run_test 1 "Help flag (--help) shows usage without initialization" test_help_flag
run_test 2 "Version flag (--version) displays version" test_version_flag
run_test 3 "Add single URL with -u flag" test_single_url
run_test 4 "Add multiple URLs with multiple -u flags" test_multiple_urls
run_test 5 "Add URL with JSON options using -u0" test_url_with_options
run_test 6 "Add multiple URLs with different options (-u0, -u1)" test_multiple_urls_with_options
run_test 7 "Batch mode (-b) exits automatically after processing" test_batch_mode_exit
run_test 8 "Recheck all watches with -r all" test_recheck_all
run_test 9 "Recheck specific watches with -r UUID" test_recheck_specific
run_test 10 "Combined: Add URLs and recheck all with -u and -r all" test_combined_operations
run_test 11 "Invalid JSON in -u0 option should show error" test_invalid_json
run_test 12 "Create datastore directory with -C flag" test_create_directory

# Wait for all tests to complete
echo ""
echo "Waiting for all tests to complete..."
wait

# Collect results
echo ""
echo "=========================================="
echo "  Test Summary"
echo "=========================================="

TESTS_RUN=0
TESTS_PASSED=0
TESTS_FAILED=0

for result_file in "$TEST_RESULTS_DIR"/test_*.result; do
    if [ -f "$result_file" ]; then
        TESTS_RUN=$((TESTS_RUN + 1))
        status=$(cut -d'|' -f1 < "$result_file")
        if [ "$status" = "pass" ]; then
            TESTS_PASSED=$((TESTS_PASSED + 1))
        else
            TESTS_FAILED=$((TESTS_FAILED + 1))
        fi
    fi
done

echo "Tests run:    $TESTS_RUN"
echo -e "${GREEN}Tests passed: $TESTS_PASSED${NC}"
if [ $TESTS_FAILED -gt 0 ]; then
    echo -e "${RED}Tests failed: $TESTS_FAILED${NC}"
else
    echo -e "${GREEN}Tests failed: $TESTS_FAILED${NC}"
fi
echo "=========================================="
echo ""

# Exit with appropriate code
if [ $TESTS_FAILED -gt 0 ]; then
    echo -e "${RED}Some tests failed!${NC}"
    exit 1
else
    echo -e "${GREEN}All tests passed!${NC}"
    exit 0
fi
