#!/bin/bash
# Comprehensive test suite for mlgym_user_create
# Tests functional requirements, edge cases, and security

set -e

PASSED=0
FAILED=0

echo "=== mlgym_user_create Comprehensive Test Suite ==="
echo ""

# Helper to run test
run_test() {
    local test_name="$1"
    local email="$2"
    local name="$3"
    local password="$4"
    local accept_terms="$5"
    local expected_result="$6"  # "success" or "error"
    
    # Build JSON request
    local terms_field=""
    if [ -n "$accept_terms" ]; then
        terms_field=",\"accept_terms\":$accept_terms"
    fi
    
    local req="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"mlgym_user_create\",\"arguments\":{\"email\":\"$email\",\"name\":\"$name\",\"password\":\"$password\"$terms_field}},\"id\":99}"
    local resp=$(echo "$req" | node index.js 2>/dev/null | tail -1)
    
    # Check for user_id (success) or error message
    local content=$(echo "$resp" | jq -r '.result.content[0].text' 2>/dev/null)
    local user_id=$(echo "$content" | jq -r '.user_id' 2>/dev/null)
    local error_msg=$(echo "$content" | jq -r '.message' 2>/dev/null)
    local has_status=$(echo "$content" | jq -r '.status' 2>/dev/null)
    
    if [ "$expected_result" = "success" ]; then
        if [ -n "$user_id" ] && [ "$user_id" != "null" ]; then
            echo "✅ $test_name (user_id: $user_id)"
            PASSED=$((PASSED + 1))
        else
            echo "❌ $test_name (expected user creation, got: $error_msg)"
            FAILED=$((FAILED + 1))
        fi
    else
        # Expected error
        if echo "$content" | grep -qE "error|missing|required|invalid|must"; then
            echo "✅ $test_name"
            PASSED=$((PASSED + 1))
        else
            echo "❌ $test_name (expected error, got success or no error)"
            FAILED=$((FAILED + 1))
        fi
    fi
}

# Test 1: Valid user creation with all fields
echo "Test 1: Valid user creation with all required fields"
TEST_EMAIL="createtest-$(date +%s)@example.com"
TEST_PASS="MyV3ryC0mpl3x!P@ssw0rd#2024"
run_test "Valid user creation" "$TEST_EMAIL" "Test User Full Name" "$TEST_PASS" "true" "success"

# Test 2: Missing email
run_test "Missing email" "" "Test User" "Pass123!Strong" "true" "error"

# Test 3: Missing name
run_test "Missing name" "test@example.com" "" "Pass123!Strong" "true" "error"

# Test 4: Missing password
run_test "Missing password" "test@example.com" "Test User" "" "true" "error"

# Test 5: accept_terms = false
run_test "Terms not accepted (false)" "test@example.com" "Test User" "Pass123!Strong" "false" "error"

# Test 6: accept_terms missing
echo "Test 6: Missing accept_terms parameter"
REQ='{"jsonrpc":"2.0","method":"tools/call","params":{"name":"mlgym_user_create","arguments":{"email":"test@example.com","name":"Test User","password":"Pass123!Strong"}},"id":100}'
RESP=$(echo "$REQ" | node index.js 2>/dev/null | tail -1)
CONTENT=$(echo "$RESP" | jq -r '.result.content[0].text')
if echo "$CONTENT" | grep -qE "error|missing|required|must"; then
    echo "✅ Test 6: Missing accept_terms"
    PASSED=$((PASSED + 1))
else
    echo "❌ Test 6: Should reject missing accept_terms"
    FAILED=$((FAILED + 1))
fi

# Test 7: Invalid email format
run_test "Invalid email format" "not-an-email" "Test User" "Pass123!Strong" "true" "error"

# Test 8: Short password (< 8 chars)
run_test "Short password" "test@example.com" "Test User" "Pass12!" "true" "error"

# Test 9: Short name (< 2 chars)
run_test "Short name" "test@example.com" "T" "Pass123!Strong" "true" "error"

# Test 10: SQL injection in email
run_test "SQL injection (email)" "admin@test.com' OR '1'='1" "Test User" "Pass123!Strong" "true" "error"

# Test 11: SQL injection in name
run_test "SQL injection (name)" "test@example.com" "'; DROP TABLE users;--" "Pass123!Strong" "true" "error"

# Test 12: SQL injection in password
run_test "SQL injection (password)" "test@example.com" "Test User" "' OR '1'='1" "true" "error"

# Test 13: XSS attempt in email
run_test "XSS attempt (email)" "<script>alert(1)</script>@test.com" "Test User" "Pass123!Strong" "true" "error"

# Test 14: XSS attempt in name
run_test "XSS attempt (name)" "test@example.com" "<script>alert('XSS')</script>" "Pass123!Strong" "true" "error"

# Test 15: Buffer overflow in email
echo "Test 15: Buffer overflow (very long email)"
LONG_EMAIL=$(python3 -c "print('a' * 10000 + '@test.com')")
run_test "Buffer overflow (email)" "$LONG_EMAIL" "Test User" "Pass123!Strong" "true" "error"

# Test 16: Buffer overflow in name
echo "Test 16: Buffer overflow (very long name)"
LONG_NAME=$(python3 -c "print('A' * 10000)")
run_test "Buffer overflow (name)" "test@example.com" "$LONG_NAME" "Pass123!Strong" "true" "error"

# Test 17: Duplicate user creation
echo "Test 17: Duplicate user creation"
DUP_EMAIL="duplicate-$(date +%s)@example.com"
# Create first user
REQ="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"mlgym_user_create\",\"arguments\":{\"email\":\"$DUP_EMAIL\",\"name\":\"Duplicate User\",\"password\":\"Pass123!Strong\",\"accept_terms\":true}},\"id\":101}"
RESP=$(echo "$REQ" | node index.js 2>/dev/null | tail -1)
USER_ID=$(echo "$RESP" | jq -r '.result.content[0].text' | jq -r '.user_id')
if [ -n "$USER_ID" ] && [ "$USER_ID" != "null" ]; then
    # Try to create duplicate
    RESP2=$(echo "$REQ" | node index.js 2>/dev/null | tail -1)
    CONTENT2=$(echo "$RESP2" | jq -r '.result.content[0].text')
    if echo "$CONTENT2" | grep -qiE "error|exists|duplicate|already"; then
        echo "✅ Test 17: Duplicate user rejected"
        PASSED=$((PASSED + 1))
    else
        echo "❌ Test 17: Should reject duplicate user"
        FAILED=$((FAILED + 1))
    fi
else
    echo "⚠️  Test 17: Couldn't create first user for duplicate test"
    FAILED=$((FAILED + 1))
fi

# Test 18: Response format validation
echo "Test 18: Response format validation"
RESP_EMAIL="resptest-$(date +%s)@example.com"
REQ="{\"jsonrpc\":\"2.0\",\"method\":\"tools/call\",\"params\":{\"name\":\"mlgym_user_create\",\"arguments\":{\"email\":\"$RESP_EMAIL\",\"name\":\"Response Test User\",\"password\":\"MyV3ryC0mpl3x!P@ssw0rd#2024\",\"accept_terms\":true}},\"id\":102}"
RESP=$(echo "$REQ" | node index.js 2>/dev/null | tail -1)
CONTENT=$(echo "$RESP" | jq -r '.result.content[0].text')
HAS_USER_ID=$(echo "$CONTENT" | jq -e '.user_id' > /dev/null 2>&1 && echo "yes" || echo "no")
HAS_EMAIL=$(echo "$CONTENT" | jq -e '.email' > /dev/null 2>&1 && echo "yes" || echo "no")
HAS_NAME=$(echo "$CONTENT" | jq -e '.name' > /dev/null 2>&1 && echo "yes" || echo "no")
HAS_TOKEN=$(echo "$CONTENT" | jq -e '.token' > /dev/null 2>&1 && echo "yes" || echo "no")
HAS_SSH=$(echo "$CONTENT" | jq -e '.ssh_key_path' > /dev/null 2>&1 && echo "yes" || echo "no")
if [ "$HAS_USER_ID" = "yes" ] && [ "$HAS_EMAIL" = "yes" ] && [ "$HAS_NAME" = "yes" ] && [ "$HAS_TOKEN" = "yes" ] && [ "$HAS_SSH" = "yes" ]; then
    echo "✅ Test 18: Response format valid"
    PASSED=$((PASSED + 1))
else
    echo "❌ Test 18: Response format invalid (user_id:$HAS_USER_ID, email:$HAS_EMAIL, name:$HAS_NAME, token:$HAS_TOKEN, ssh:$HAS_SSH)"
    FAILED=$((FAILED + 1))
fi

# Test 19: SSH key generation verification
echo "Test 19: SSH key generation verification"
SSH_PATH=$(echo "$CONTENT" | jq -r '.ssh_key_path')
if [ -f "$SSH_PATH" ]; then
    echo "✅ Test 19: SSH key file created at $SSH_PATH"
    PASSED=$((PASSED + 1))
else
    echo "❌ Test 19: SSH key file not found at $SSH_PATH"
    FAILED=$((FAILED + 1))
fi

# Test 20: Token storage verification
echo "Test 20: Token storage verification"
if [ -f ~/.mlgym/mcp_config.json ]; then
    STORED_TOKEN=$(jq -r '.token' ~/.mlgym/mcp_config.json)
    STORED_EMAIL=$(jq -r '.email' ~/.mlgym/mcp_config.json)
    if [ -n "$STORED_TOKEN" ] && [ "$STORED_TOKEN" != "null" ]; then
        echo "✅ Test 20: Token stored correctly (email: $STORED_EMAIL)"
        PASSED=$((PASSED + 1))
    else
        echo "❌ Test 20: Token not stored properly"
        FAILED=$((FAILED + 1))
    fi
else
    echo "❌ Test 20: Config file not created"
    FAILED=$((FAILED + 1))
fi

echo ""
echo "==============================================="
echo "RESULTS: $PASSED passed, $FAILED failed (Total: $((PASSED + FAILED)))"
echo "==============================================="

if [ $FAILED -eq 0 ]; then
    echo "✅ ALL TESTS PASSED"
    exit 0
else
    echo "⚠️  SOME TESTS FAILED"
    exit 1
fi
