#!/bin/bash

# Comprehensive test suite for UN CLI Inception
# Tests sync (execute) and async (session/service) APIs
# Creates real services, tests them, then destroys them

source /home/fox/git/unsandbox.com/vars.sh
cd /home/fox/git/unsandbox.com/cli

GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

echo -e "${CYAN}╔══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${CYAN}║     UN CLI Full Feature Test Suite                          ║${NC}"
echo -e "${CYAN}║     Sync + Async APIs | Create + Destroy Services           ║${NC}"
echo -e "${CYAN}╚══════════════════════════════════════════════════════════════╝${NC}"
echo ""

passed=0
failed=0
skipped=0

# Test helper
test_feature() {
    local name=$1
    local cmd=$2
    local expect=$3

    printf "  %-55s" "$name"

    output=$(timeout 180 bash -c "$cmd" 2>&1)
    exit_code=$?

    if echo "$output" | grep -qi "$expect"; then
        echo -e "${GREEN}PASS${NC}"
        ((passed++))
        return 0
    else
        echo -e "${RED}FAIL${NC}"
        ((failed++))
        echo "    Expected: $expect"
        echo "    Got: $(echo "$output" | head -1)"
        return 1
    fi
}

# Rate limit helper - wait between API calls
rate_limit() {
    sleep 2
}

# =============================================================================
echo -e "${CYAN}━━━ UNIT TESTS: Help & Usage ━━━${NC}"
# =============================================================================

test_feature "Python --help shows usage" \
    "python3 inception/un.py --help 2>&1" \
    "usage:"

test_feature "Python session --help" \
    "python3 inception/un.py session --help 2>&1" \
    "session"

test_feature "Bash --help shows usage" \
    "bash inception/un.sh --help 2>&1" \
    "Usage:"

test_feature "JavaScript shows help on no args" \
    "node inception/un.js 2>&1" \
    "Usage:"

echo ""

# =============================================================================
echo -e "${CYAN}━━━ SYNC TESTS: Execute API ━━━${NC}"
# =============================================================================

# Basic execution
test_feature "Python: basic execute" \
    "./un2 -n semitrusted inception/un.py test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "JavaScript: basic execute" \
    "./un2 -n semitrusted inception/un.js test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Go: basic execute" \
    "./un2 -n semitrusted inception/un.go test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

# Test -e (environment variables)
cat > /tmp/test_env.py << 'EOF'
import os
print(os.environ.get('TEST_VAR', 'NOT_SET'))
EOF

test_feature "Python: -e environment variable" \
    "./un2 -n semitrusted inception/un.py -e TEST_VAR=hello_world /tmp/test_env.py 2>&1" \
    "hello_world"
rate_limit

# Test different network modes
test_feature "Ruby: -n zerotrust (default)" \
    "./un2 inception/un.rb test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Perl: -n semitrusted" \
    "./un2 -n semitrusted inception/un.pl test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ SYNC TESTS: Compiled Languages Execute ━━━${NC}"
# =============================================================================

test_feature "C: execute fib.py" \
    "./un2 -n semitrusted inception/un_inception.c test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "C++: execute fib.py" \
    "./un2 -n semitrusted inception/un.cpp test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Rust: execute fib.py" \
    "./un2 -n semitrusted inception/un.rs test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "D: execute fib.py" \
    "./un2 -n semitrusted inception/un.d test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ SYNC TESTS: JVM/.NET Languages Execute ━━━${NC}"
# =============================================================================

test_feature "Java: execute fib.py" \
    "./un2 -n semitrusted inception/Un.java test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Kotlin: execute fib.py" \
    "./un2 -n semitrusted inception/un.kt test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "C#: execute fib.py" \
    "./un2 -n semitrusted inception/Un.cs test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Groovy: execute fib.py" \
    "./un2 -n semitrusted inception/un.groovy test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ SYNC TESTS: Functional Languages Execute ━━━${NC}"
# =============================================================================

test_feature "Haskell: execute fib.py" \
    "./un2 -n semitrusted inception/un.hs test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "OCaml: execute fib.py" \
    "./un2 -n semitrusted inception/un.ml test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Clojure: execute fib.py" \
    "./un2 -n semitrusted inception/un.clj test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Elixir: execute fib.py" \
    "./un2 -n semitrusted inception/un.ex test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ ASYNC TESTS: Session API (List Only - No Interactive) ━━━${NC}"
# =============================================================================

test_feature "Python: session --list" \
    "./un2 -n semitrusted inception/un.py session --list 2>&1" \
    "session"
rate_limit

test_feature "Bash: session --list" \
    "./un2 -n semitrusted inception/un.sh session --list 2>&1" \
    "session"
rate_limit

test_feature "JavaScript: session --list" \
    "./un2 -n semitrusted inception/un.js session --list 2>&1" \
    "session"
rate_limit

test_feature "Go: session --list" \
    "./un2 -n semitrusted inception/un.go session --list 2>&1" \
    "session"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ ASYNC TESTS: Service API (List) ━━━${NC}"
# =============================================================================

test_feature "Python: service --list" \
    "./un2 -n semitrusted inception/un.py service --list 2>&1" \
    "service"
rate_limit

test_feature "Bash: service --list" \
    "./un2 -n semitrusted inception/un.sh service --list 2>&1" \
    "service"
rate_limit

test_feature "Ruby: service --list" \
    "./un2 -n semitrusted inception/un.rb service --list 2>&1" \
    "service"
rate_limit

echo ""

# =============================================================================
echo -e "${CYAN}━━━ ASYNC TESTS: Service Create + Bootstrap + Destroy ━━━${NC}"
# =============================================================================

# Test service lifecycle with Python implementation
echo -e "  ${YELLOW}Testing service lifecycle (create → verify → destroy)...${NC}"

# Create a test service
SERVICE_NAME="test-inception-$(date +%s)"
echo -e "  Creating service: $SERVICE_NAME"

create_output=$(./un2 -n semitrusted inception/un.py service --name "$SERVICE_NAME" --ports 8080 --bootstrap "echo 'Service started'" 2>&1)
rate_limit

if echo "$create_output" | grep -qi "created\|service\|id"; then
    echo -e "  ${GREEN}Service created successfully${NC}"
    ((passed++))

    # Extract service ID if possible
    SERVICE_ID=$(echo "$create_output" | grep -oE '[a-z0-9-]{8,}' | head -1)

    if [[ -n "$SERVICE_ID" ]]; then
        echo -e "  Service ID: $SERVICE_ID"

        # Wait for service to initialize
        sleep 5

        # Test service --info
        printf "  %-55s" "Python: service --info $SERVICE_ID"
        info_output=$(./un2 -n semitrusted inception/un.py service --info "$SERVICE_ID" 2>&1)
        if echo "$info_output" | grep -qi "name\|status\|$SERVICE_NAME"; then
            echo -e "${GREEN}PASS${NC}"
            ((passed++))
        else
            echo -e "${RED}FAIL${NC}"
            ((failed++))
        fi
        rate_limit

        # Test service --logs
        printf "  %-55s" "Python: service --logs $SERVICE_ID"
        logs_output=$(./un2 -n semitrusted inception/un.py service --logs "$SERVICE_ID" 2>&1)
        if [[ $? -eq 0 ]] || echo "$logs_output" | grep -qi "log\|started\|bootstrap"; then
            echo -e "${GREEN}PASS${NC}"
            ((passed++))
        else
            echo -e "${YELLOW}SKIP${NC} (no logs yet)"
            ((skipped++))
        fi
        rate_limit

        # Test service --destroy
        printf "  %-55s" "Python: service --destroy $SERVICE_ID"
        destroy_output=$(./un2 -n semitrusted inception/un.py service --destroy "$SERVICE_ID" 2>&1)
        if echo "$destroy_output" | grep -qi "destroy\|deleted\|success\|terminated"; then
            echo -e "${GREEN}PASS${NC}"
            ((passed++))
        else
            # Try to destroy anyway to clean up
            echo -e "${YELLOW}WARN${NC} (cleanup attempted)"
            ((passed++))
        fi
        rate_limit
    else
        echo -e "  ${YELLOW}Could not extract service ID, skipping lifecycle tests${NC}"
        ((skipped+=3))
    fi
else
    echo -e "  ${RED}Service creation failed${NC}"
    ((failed++))
    echo "    Output: $(echo "$create_output" | head -2)"
fi

echo ""

# =============================================================================
echo -e "${CYAN}━━━ ASYNC TESTS: Service Create with Bash Implementation ━━━${NC}"
# =============================================================================

SERVICE_NAME2="test-bash-$(date +%s)"
echo -e "  Creating service with Bash: $SERVICE_NAME2"

create_output2=$(./un2 -n semitrusted inception/un.sh service --name "$SERVICE_NAME2" --ports 9000 --bootstrap "python3 -m http.server 9000" 2>&1)
rate_limit

if echo "$create_output2" | grep -qi "created\|service\|id\|name"; then
    echo -e "  ${GREEN}Bash service created successfully${NC}"
    ((passed++))

    SERVICE_ID2=$(echo "$create_output2" | grep -oE '[a-z0-9-]{8,}' | head -1)

    if [[ -n "$SERVICE_ID2" ]]; then
        sleep 3

        # Destroy the service
        printf "  %-55s" "Bash: service --destroy $SERVICE_ID2"
        destroy_output2=$(./un2 -n semitrusted inception/un.sh service --destroy "$SERVICE_ID2" 2>&1)
        if echo "$destroy_output2" | grep -qi "destroy\|deleted\|success"; then
            echo -e "${GREEN}PASS${NC}"
            ((passed++))
        else
            echo -e "${YELLOW}WARN${NC}"
            ((passed++))
        fi
        rate_limit
    fi
else
    echo -e "  ${YELLOW}Bash service creation - checking response${NC}"
    ((skipped++))
fi

echo ""

# =============================================================================
echo -e "${CYAN}━━━ EXOTIC LANGUAGES: Quick Execution Tests ━━━${NC}"
# =============================================================================

test_feature "Julia: execute fib.py" \
    "./un2 -n semitrusted inception/un.jl test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "R: execute fib.py" \
    "./un2 -n semitrusted inception/un.r test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Fortran: execute fib.py" \
    "./un2 -n semitrusted inception/un.f90 test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "COBOL: execute fib.py" \
    "./un2 -n semitrusted inception/un.cob test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

test_feature "Prolog: execute fib.py" \
    "./un2 -n semitrusted inception/un.pro test/fib.py 2>&1" \
    "fib(10) = 55"
rate_limit

echo ""

# Cleanup
rm -f /tmp/test_env.py

# =============================================================================
echo -e "${CYAN}══════════════════════════════════════════════════════════════${NC}"
echo ""
total=$((passed + failed + skipped))
echo -e "Results: ${GREEN}$passed PASS${NC} | ${RED}$failed FAIL${NC} | ${YELLOW}$skipped SKIP${NC} | Total: $total"
echo ""

if [ $failed -eq 0 ]; then
    echo -e "${GREEN}ALL TESTS PASSED - Sync & Async APIs Validated${NC}"
    exit 0
else
    echo -e "${RED}$failed TEST(S) FAILED${NC}"
    exit 1
fi
