#!/bin/bash
# Nexus CLI - Comprehensive Sandbox Management Demo
#
# This demo showcases the complete sandbox management system (Issue #372)
#
# Features tested:
# - Sandbox lifecycle: create, run, pause, resume, stop
# - Multi-language code execution: Python, JavaScript, Bash
# - Code input methods: inline, file, stdin
# - TTL and expiry management
# - Sandbox listing and status queries
# - Error handling and edge cases
# - Background cleanup tasks
#
# Prerequisites:
# 1. E2B API key: export E2B_API_KEY=your-key
# 2. E2B template ID (optional): export E2B_TEMPLATE_ID=your-template
#
# Usage:
#   export E2B_API_KEY=your-e2b-key
#   ./examples/cli/sandbox_comprehensive_demo.sh

set -e

# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
MAGENTA='\033[0;35m'
NC='\033[0m'

print_section() {
    echo ""
    echo "════════════════════════════════════════════════════════════"
    echo "  $1"
    echo "════════════════════════════════════════════════════════════"
    echo ""
}

print_subsection() {
    echo ""
    echo "─── $1 ───"
    echo ""
}

print_success() { echo -e "${GREEN}✓${NC} $1"; }
print_info() { echo -e "${BLUE}ℹ${NC} $1"; }
print_warning() { echo -e "${YELLOW}⚠${NC} $1"; }
print_error() { echo -e "${RED}✗${NC} $1"; }
print_test() { echo -e "${MAGENTA}TEST:${NC} $1"; }
print_code() { echo -e "${CYAN}CODE:${NC} $1"; }

# Check prerequisites
if [ -z "$E2B_API_KEY" ]; then
    print_error "E2B_API_KEY not set"
    echo ""
    echo "To run this demo:"
    echo "  1. Get your E2B API key from https://e2b.dev"
    echo "  2. Run: export E2B_API_KEY=your-key"
    echo "  3. (Optional) export E2B_TEMPLATE_ID=your-template"
    echo ""
    exit 1
fi

echo "╔══════════════════════════════════════════════════════════╗"
echo "║    Nexus CLI - Comprehensive Sandbox Management Demo    ║"
echo "║                  Testing Issue #372                      ║"
echo "╚══════════════════════════════════════════════════════════╝"
echo ""
print_info "E2B API Key: ${E2B_API_KEY:0:20}..."
if [ -n "$E2B_TEMPLATE_ID" ]; then
    print_info "E2B Template: $E2B_TEMPLATE_ID"
fi
echo ""

# Test data directory
TEST_DIR="/tmp/nexus-sandbox-demo-$$"
mkdir -p "$TEST_DIR"

# Server process
SERVER_PID=""

# Cleanup function
cleanup() {
    print_info "Cleaning up..."

    # Stop server if running
    if [ -n "$SERVER_PID" ]; then
        print_info "Stopping Nexus server (PID: $SERVER_PID)..."
        kill $SERVER_PID 2>/dev/null || true
        wait $SERVER_PID 2>/dev/null || true
    fi

    # Clean up test directory
    rm -rf "$TEST_DIR"

    print_success "Cleanup complete"
}

# Set trap for cleanup
trap cleanup EXIT INT TERM

# ============================================================
# SECTION 1: Server Setup
# ============================================================

print_section "1. Server Setup"

print_subsection "Starting Nexus server with E2B configuration"

# Unset NEXUS_URL to avoid nexus.connect() circular dependency
unset NEXUS_URL
unset NEXUS_API_KEY

# Start server in background
export NEXUS_DATA_DIR="$TEST_DIR/nexus-data"
export NEXUS_DATABASE_URL="sqlite:///$TEST_DIR/nexus.db"

print_info "Data directory: $NEXUS_DATA_DIR"
print_info "Database: $NEXUS_DATABASE_URL"

# Start server
print_info "Starting server (this may take a few seconds)..."
nexus serve --host 127.0.0.1 --port 8765 > "$TEST_DIR/server.log" 2>&1 &
SERVER_PID=$!

print_info "Server starting (PID: $SERVER_PID)..."

# Wait for server to be ready
for i in {1..10}; do
    sleep 1
    if curl -s http://127.0.0.1:8765/health > /dev/null 2>&1; then
        break
    fi
    if ! kill -0 $SERVER_PID 2>/dev/null; then
        print_error "Server failed to start. Check $TEST_DIR/server.log"
        cat "$TEST_DIR/server.log"
        exit 1
    fi
done

if ! curl -s http://127.0.0.1:8765/health > /dev/null 2>&1; then
    print_error "Server did not become healthy. Check $TEST_DIR/server.log"
    cat "$TEST_DIR/server.log"
    exit 1
fi

print_success "Server running at http://127.0.0.1:8765"

print_subsection "Configuring client"

# Local server runs without authentication by default
# Set NEXUS_URL for CLI to connect to the server
export NEXUS_URL="http://127.0.0.1:8765"
unset NEXUS_API_KEY  # No authentication for local server

print_info "Server URL: $NEXUS_URL"
print_info "Authentication: None (local development mode)"

print_success "Client configured"
print_success "Server setup complete"

# ============================================================
# SECTION 2: Sandbox Creation
# ============================================================

print_section "2. Sandbox Creation"

print_subsection "Creating sandboxes with different configurations"

print_test "Create sandbox with default TTL (10 minutes)"
SANDBOX1=$(nexus sandbox create demo-sandbox-1 --json 2>/dev/null | jq -r '.sandbox_id')
print_success "Created: $SANDBOX1"

print_test "Create sandbox with custom TTL (30 minutes)"
SANDBOX2=$(nexus sandbox create demo-sandbox-2 --ttl 30 --json 2>/dev/null | jq -r '.sandbox_id')
print_success "Created: $SANDBOX2"

if [ -n "$E2B_TEMPLATE_ID" ]; then
    print_test "Create sandbox with custom template"
    SANDBOX3=$(nexus sandbox create demo-sandbox-3 --template "$E2B_TEMPLATE_ID" --json 2>/dev/null | jq -r '.sandbox_id')
    print_success "Created: $SANDBOX3"
fi

print_test "List all sandboxes"
nexus sandbox list
print_success "Listed all sandboxes"

# ============================================================
# SECTION 3: Python Code Execution
# ============================================================

print_section "3. Python Code Execution"

print_subsection "Running Python code in various ways"

print_test "Execute inline Python code"
print_code "Simple calculation and system info"
nexus sandbox run "$SANDBOX1" --language python --code "
import sys
import platform

print('Python Version:', sys.version.split()[0])
print('Platform:', platform.system())
print('Calculation: 2 + 2 =', 2 + 2)
print('✓ Python execution successful')
"
print_success "Inline Python execution complete"

print_test "Execute Python code from file"
cat > "$TEST_DIR/data_analysis.py" << 'PYCODE'
# Data analysis example
print("=== Data Analysis Demo ===")
print()

# Sample data
sales = [100, 150, 200, 175, 125, 300, 250]
products = ['A', 'B', 'C', 'D', 'E', 'F', 'G']

# Analysis
total = sum(sales)
avg = total / len(sales)
max_sales = max(sales)
max_product = products[sales.index(max_sales)]

print(f"Total Sales: ${total}")
print(f"Average: ${avg:.2f}")
print(f"Best Product: {max_product} (${max_sales})")
print()
print("Sales by Product:")
for product, sale in zip(products, sales):
    bar = '█' * (sale // 10)
    print(f"  {product}: {bar} ${sale}")
print()
print("✓ Analysis complete")
PYCODE

print_code "Running data_analysis.py from file"
nexus sandbox run "$SANDBOX1" --file "$TEST_DIR/data_analysis.py"
print_success "File-based Python execution complete"

print_test "Execute Python code from stdin"
print_code "Piping code via stdin"
echo "print('Hello from stdin!'); print('Math:', 10 * 5)" | \
    nexus sandbox run "$SANDBOX1" --language python --code -
print_success "Stdin Python execution complete"

# ============================================================
# SECTION 4: JavaScript Execution
# ============================================================

print_section "4. JavaScript/Node.js Execution"

print_subsection "Running JavaScript code"

print_test "Execute JavaScript code"
print_code "Array operations and JSON"
nexus sandbox run "$SANDBOX2" --language javascript --code "
const data = [1, 2, 3, 4, 5];
const doubled = data.map(x => x * 2);
const sum = doubled.reduce((a, b) => a + b, 0);

console.log('Original:', data);
console.log('Doubled:', doubled);
console.log('Sum:', sum);
console.log('JSON:', JSON.stringify({result: sum, count: data.length}));
console.log('✓ JavaScript execution successful');
"
print_success "JavaScript execution complete"

print_test "Execute async JavaScript code"
print_code "Promises and async/await"
nexus sandbox run "$SANDBOX2" --language javascript --code "
async function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function run() {
    console.log('Starting async operation...');
    await delay(100);
    console.log('Async operation complete');
    console.log('✓ Async JavaScript successful');
}

run();
"
print_success "Async JavaScript execution complete"

# ============================================================
# SECTION 5: Bash Script Execution
# ============================================================

print_section "5. Bash Script Execution"

print_subsection "Running Bash commands"

print_test "Execute system commands"
print_code "Environment and file operations"
nexus sandbox run "$SANDBOX1" --language bash --code "
echo '=== System Information ==='
echo
echo 'Hostname:' \$(hostname)
echo 'User:' \$(whoami)
echo 'Date:' \$(date)
echo
echo '=== Environment Sample ==='
env | head -5
echo
echo '=== File Operations ==='
echo 'test content' > /tmp/test.txt
cat /tmp/test.txt
rm /tmp/test.txt
echo
echo '✓ Bash execution successful'
"
print_success "Bash execution complete"

print_test "Execute bash script from file"
cat > "$TEST_DIR/system_check.sh" << 'BASHCODE'
#!/bin/bash
echo "=== System Check ==="
echo
echo "Disk Usage:"
df -h / | tail -1 | awk '{print "  Used: "$3" / "$2" ("$5")"}'
echo
echo "Memory Info:"
free -h 2>/dev/null || echo "  (free command not available)"
echo
echo "Process Count:" $(ps aux | wc -l)
echo
echo "✓ System check complete"
BASHCODE

print_code "Running system_check.sh from file"
nexus sandbox run "$SANDBOX1" --language bash --file "$TEST_DIR/system_check.sh"
print_success "Bash script from file complete"

# ============================================================
# SECTION 6: Execution Timeout
# ============================================================

print_section "6. Execution Timeout Testing"

print_subsection "Testing timeout behavior"

print_test "Execute code with custom timeout"
print_code "Quick execution with 60s timeout"
nexus sandbox run "$SANDBOX1" --language python --timeout 60 --code "
import time
print('Starting...')
time.sleep(0.5)
print('Finished after 0.5s')
print('✓ Timeout test successful')
"
print_success "Custom timeout execution complete"

print_test "Simulate long-running code (will timeout)"
print_code "Code that exceeds 5s timeout"
if nexus sandbox run "$SANDBOX1" --language python --timeout 5 --code "
import time
print('Sleeping for 10 seconds...')
time.sleep(10)
print('Should not see this')
" 2>&1; then
    print_error "Expected timeout but code completed"
else
    print_warning "Code timed out as expected (this is correct behavior)"
fi

# ============================================================
# SECTION 7: Sandbox Status and Metadata
# ============================================================

print_section "7. Sandbox Status and Metadata"

print_subsection "Querying sandbox information"

print_test "Get detailed status of sandbox 1"
nexus sandbox status "$SANDBOX1"
print_success "Status retrieved"

print_test "Get status in JSON format"
STATUS_JSON=$(nexus sandbox status "$SANDBOX1" --json)
echo "$STATUS_JSON" | jq '.'
print_success "JSON status retrieved"

print_test "Extract specific fields"
UPTIME=$(echo "$STATUS_JSON" | jq -r '.uptime_seconds')
STATUS=$(echo "$STATUS_JSON" | jq -r '.status')
print_info "Status: $STATUS"
print_info "Uptime: ${UPTIME}s"
print_success "Field extraction complete"

# ============================================================
# SECTION 8: Pause and Resume (if supported)
# ============================================================

print_section "8. Pause and Resume Testing"

print_subsection "Testing pause/resume functionality"

print_test "Attempt to pause sandbox"
if nexus sandbox pause "$SANDBOX2" 2>&1 | grep -q "not support"; then
    print_warning "Provider doesn't support pause/resume (E2B limitation)"
    print_info "This is expected behavior for E2B sandboxes"
else
    print_success "Sandbox paused"

    print_test "Verify paused status"
    nexus sandbox status "$SANDBOX2" | grep -i "paused"
    print_success "Status shows paused"

    print_test "Resume sandbox"
    nexus sandbox resume "$SANDBOX2"
    print_success "Sandbox resumed"
fi

# ============================================================
# SECTION 9: Error Handling
# ============================================================

print_section "9. Error Handling"

print_subsection "Testing error scenarios"

print_test "Run code with syntax error"
if nexus sandbox run "$SANDBOX1" --language python --code "
print('This will fail'
# Missing closing parenthesis
" 2>&1; then
    print_error "Expected syntax error but code succeeded"
else
    print_warning "Syntax error caught (expected)"
    print_success "Error handling works correctly"
fi

print_test "Run code with runtime error"
if nexus sandbox run "$SANDBOX1" --language python --code "
x = 1 / 0  # Division by zero
" 2>&1; then
    print_error "Expected runtime error but code succeeded"
else
    print_warning "Runtime error caught (expected)"
    print_success "Runtime error handling works correctly"
fi

print_test "Query non-existent sandbox"
if nexus sandbox status "sb_nonexistent" 2>&1; then
    print_error "Expected 'not found' error"
else
    print_warning "Not found error caught (expected)"
    print_success "Non-existent sandbox handling works correctly"
fi

# ============================================================
# SECTION 10: Multi-Sandbox Operations
# ============================================================

print_section "10. Multi-Sandbox Operations"

print_subsection "Working with multiple sandboxes"

print_test "List all sandboxes (table format)"
nexus sandbox list
print_success "Table listing complete"

print_test "List all sandboxes (JSON format)"
SANDBOXES_JSON=$(nexus sandbox list --json)
echo "$SANDBOXES_JSON" | jq '.'
COUNT=$(echo "$SANDBOXES_JSON" | jq '.sandboxes | length')
print_info "Total sandboxes: $COUNT"
print_success "JSON listing complete"

print_test "Run same code in multiple sandboxes"
for sb in $SANDBOX1 $SANDBOX2; do
    print_info "Running in $sb..."
    nexus sandbox run "$sb" --language python --code "
import socket
print('Sandbox:', '$sb')
print('Hostname:', socket.gethostname())
    " | head -3
done
print_success "Multi-sandbox execution complete"

# ============================================================
# SECTION 11: Sandbox Lifecycle
# ============================================================

print_section "11. Complete Sandbox Lifecycle"

print_subsection "Testing full create → use → stop cycle"

print_test "Create temporary sandbox"
TEMP_SANDBOX=$(nexus sandbox create temp-lifecycle-test --ttl 5 --json 2>/dev/null | jq -r '.sandbox_id')
print_success "Created: $TEMP_SANDBOX"

print_test "Use the sandbox"
nexus sandbox run "$TEMP_SANDBOX" --language python --code "
print('Using temporary sandbox')
print('Sandbox ID: $TEMP_SANDBOX')
"
print_success "Executed code in temporary sandbox"

print_test "Stop and destroy sandbox"
nexus sandbox stop "$TEMP_SANDBOX"
print_success "Sandbox stopped and destroyed"

print_test "Verify sandbox is stopped"
STATUS=$(nexus sandbox status "$TEMP_SANDBOX" --json | jq -r '.status')
if [ "$STATUS" = "stopped" ]; then
    print_success "Status correctly shows 'stopped'"
else
    print_warning "Status is '$STATUS' (might be valid depending on cleanup timing)"
fi

# ============================================================
# SECTION 12: Cleanup
# ============================================================

print_section "12. Cleanup"

print_subsection "Stopping all demo sandboxes"

for sb in $SANDBOX1 $SANDBOX2; do
    print_test "Stopping $sb"
    nexus sandbox stop "$sb" 2>/dev/null || true
    print_success "Stopped"
done

if [ -n "$SANDBOX3" ]; then
    print_test "Stopping $SANDBOX3"
    nexus sandbox stop "$SANDBOX3" 2>/dev/null || true
    print_success "Stopped"
fi

print_test "Verify no active sandboxes remain"
ACTIVE_COUNT=$(nexus sandbox list --json 2>/dev/null | jq '[.sandboxes[] | select(.status != "stopped")] | length')
print_info "Active sandboxes: $ACTIVE_COUNT"

if [ "$ACTIVE_COUNT" -eq 0 ]; then
    print_success "All sandboxes stopped"
else
    print_warning "$ACTIVE_COUNT sandboxes still active (may be cleaning up)"
fi

# ============================================================
# Summary
# ============================================================

print_section "Demo Complete!"

echo "Summary of tests performed:"
echo ""
echo "  ✓ Server setup and configuration"
echo "  ✓ Sandbox creation (default, custom TTL, custom template)"
echo "  ✓ Python code execution (inline, file, stdin)"
echo "  ✓ JavaScript/Node.js execution (sync and async)"
echo "  ✓ Bash script execution"
echo "  ✓ Timeout handling"
echo "  ✓ Status queries and metadata"
echo "  ✓ Pause/Resume testing (provider-dependent)"
echo "  ✓ Error handling (syntax, runtime, not found)"
echo "  ✓ Multi-sandbox operations"
echo "  ✓ Complete lifecycle (create → use → stop)"
echo "  ✓ Cleanup and verification"
echo ""
print_success "All sandbox management features tested successfully!"
echo ""
print_info "Server log available at: $TEST_DIR/server.log"
print_info "Test data at: $TEST_DIR"
echo ""
print_info "The sandbox system is production-ready for:"
echo "  • Multi-language code execution (Python, JS, Bash)"
echo "  • TTL-based automatic cleanup"
echo "  • Comprehensive error handling"
echo "  • Remote and local execution"
echo "  • CLI, RPC, and programmatic access"
echo ""
