#!/bin/bash

# Error Handling Security Test Script
# Tests CWE-209 mitigation and error handling implementation

set -e

echo "🔐 Error Handling Security Tests"
echo "================================="
echo ""

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

# Test counter
TESTS_PASSED=0
TESTS_FAILED=0

# Function to test endpoint
test_endpoint() {
    local test_name="$1"
    local url="$2"
    local expected_pattern="$3"
    local should_not_contain="$4"
    
    echo -n "Testing: $test_name... "
    
    response=$(curl -s "$url" 2>&1 || echo "ERROR")
    
    # Check if response contains expected pattern
    if [[ "$response" == *"$expected_pattern"* ]]; then
        # Check if response does NOT contain sensitive info
        if [[ -n "$should_not_contain" ]] && [[ "$response" == *"$should_not_contain"* ]]; then
            echo -e "${RED}FAILED${NC} - Contains sensitive information: $should_not_contain"
            TESTS_FAILED=$((TESTS_FAILED + 1))
            return 1
        fi
        echo -e "${GREEN}PASSED${NC}"
        TESTS_PASSED=$((TESTS_PASSED + 1))
        return 0
    else
        echo -e "${RED}FAILED${NC} - Expected pattern not found"
        TESTS_FAILED=$((TESTS_FAILED + 1))
        return 1
    fi
}

# Function to check for information disclosure
check_no_disclosure() {
    local test_name="$1"
    local url="$2"
    
    echo -n "Checking: $test_name... "
    
    response=$(curl -s "$url" 2>&1 || echo "ERROR")
    
    # Patterns that should NOT be in error responses
    FORBIDDEN_PATTERNS=(
        "/home/"
        "/app/"
        "/usr/"
        "/var/"
        "node_modules"
        ".js:"
        "Error:"
        "at "
        "line "
        "SQLITE_"
        "ENOENT"
        "EACCES"
        "password"
        "secret"
        "token"
    )
    
    for pattern in "${FORBIDDEN_PATTERNS[@]}"; do
        if [[ "$response" == *"$pattern"* ]]; then
            echo -e "${RED}FAILED${NC} - Contains forbidden pattern: $pattern"
            TESTS_FAILED=$((TESTS_FAILED + 1))
            return 1
        fi
    done
    
    echo -e "${GREEN}PASSED${NC}"
    TESTS_PASSED=$((TESTS_PASSED + 1))
    return 0
}

echo "1️⃣  Backend Syntax Tests"
echo "------------------------"

# Test backend files compile without errors
if node -c backend/server.js 2>&1 | grep -q "error"; then
    echo -e "${RED}FAILED${NC} - server.js has syntax errors"
    TESTS_FAILED=$((TESTS_FAILED + 1))
else
    echo -e "${GREEN}PASSED${NC} - server.js syntax valid"
    TESTS_PASSED=$((TESTS_PASSED + 1))
fi

if node -c backend/utils/errorHandler.js 2>&1 | grep -q "error"; then
    echo -e "${RED}FAILED${NC} - errorHandler.js has syntax errors"
    TESTS_FAILED=$((TESTS_FAILED + 1))
else
    echo -e "${GREEN}PASSED${NC} - errorHandler.js syntax valid"
    TESTS_PASSED=$((TESTS_PASSED + 1))
fi

if node -c backend/utils/logger.js 2>&1 | grep -q "error"; then
    echo -e "${RED}FAILED${NC} - logger.js has syntax errors"
    TESTS_FAILED=$((TESTS_FAILED + 1))
else
    echo -e "${GREEN}PASSED${NC} - logger.js syntax valid"
    TESTS_PASSED=$((TESTS_PASSED + 1))
fi

echo ""
echo "2️⃣  Frontend Syntax Tests"
echo "-------------------------"

if node -c frontend/src/utils/errorHandler.js 2>&1 | grep -q "error"; then
    echo -e "${RED}FAILED${NC} - errorHandler.js has syntax errors"
    TESTS_FAILED=$((TESTS_FAILED + 1))
else
    echo -e "${GREEN}PASSED${NC} - errorHandler.js syntax valid"
    TESTS_PASSED=$((TESTS_PASSED + 1))
fi

if node -c frontend/src/utils/api.js 2>&1 | grep -q "error"; then
    echo -e "${RED}FAILED${NC} - api.js has syntax errors"
    TESTS_FAILED=$((TESTS_FAILED + 1))
else
    echo -e "${GREEN}PASSED${NC} - api.js syntax valid"
    TESTS_PASSED=$((TESTS_PASSED + 1))
fi

echo ""
echo "3️⃣  Translation Files"
echo "---------------------"

# Check if translation files are valid JSON
if jq empty frontend/src/locales/en.json 2>/dev/null; then
    echo -e "${GREEN}PASSED${NC} - en.json is valid JSON"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}FAILED${NC} - en.json is not valid JSON"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

if jq empty frontend/src/locales/ro.json 2>/dev/null; then
    echo -e "${GREEN}PASSED${NC} - ro.json is valid JSON"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}FAILED${NC} - ro.json is not valid JSON"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

# Check if error translations exist
if jq -e '.errors' frontend/src/locales/en.json >/dev/null 2>&1; then
    echo -e "${GREEN}PASSED${NC} - English error translations exist"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}FAILED${NC} - English error translations missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

if jq -e '.errors' frontend/src/locales/ro.json >/dev/null 2>&1; then
    echo -e "${GREEN}PASSED${NC} - Romanian error translations exist"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}FAILED${NC} - Romanian error translations missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

echo ""
echo "4️⃣  File Structure"
echo "------------------"

# Check if required files exist
FILES=(
    "backend/utils/errorHandler.js"
    "backend/utils/logger.js"
    "frontend/src/utils/errorHandler.js"
    "frontend/src/components/ErrorBoundary.jsx"
    "frontend/src/components/ErrorNotificationProvider.jsx"
    "docs/ERROR_HANDLING_SECURITY.md"
    "docs/ERROR_HANDLING_QUICK_REFERENCE.md"
)

for file in "${FILES[@]}"; do
    if [[ -f "$file" ]]; then
        echo -e "${GREEN}✓${NC} $file exists"
        TESTS_PASSED=$((TESTS_PASSED + 1))
    else
        echo -e "${RED}✗${NC} $file missing"
        TESTS_FAILED=$((TESTS_FAILED + 1))
    fi
done

echo ""
echo "5️⃣  Docker Integration"
echo "----------------------"

# Check if Dockerfile exists and contains necessary commands
if [[ -f "Dockerfile" ]]; then
    echo -e "${GREEN}✓${NC} Dockerfile exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Dockerfile missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

if [[ -f "docker-compose.yml" ]]; then
    echo -e "${GREEN}✓${NC} docker-compose.yml exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} docker-compose.yml missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

echo ""
echo "6️⃣  Process Error Handlers"
echo "-------------------------"

# Check if backend has process-level error handlers
if grep -q "process.on('uncaughtException'" backend/server.js; then
    echo -e "${GREEN}✓${NC} Uncaught exception handler exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Uncaught exception handler missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

if grep -q "process.on('unhandledRejection'" backend/server.js; then
    echo -e "${GREEN}✓${NC} Unhandled rejection handler exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Unhandled rejection handler missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

# Check if frontend has window-level error handlers
if grep -q "window.addEventListener('error'" frontend/src/main.jsx; then
    echo -e "${GREEN}✓${NC} Window error handler exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Window error handler missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

if grep -q "window.addEventListener('unhandledrejection'" frontend/src/main.jsx; then
    echo -e "${GREEN}✓${NC} Window unhandled rejection handler exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Window unhandled rejection handler missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

echo ""
echo "7️⃣  Service Worker Protection"
echo "-----------------------------"

if grep -q "self.addEventListener('error'" frontend/public/service-worker.js; then
    echo -e "${GREEN}✓${NC} Service worker error handler exists"
    TESTS_PASSED=$((TESTS_PASSED + 1))
else
    echo -e "${RED}✗${NC} Service worker error handler missing"
    TESTS_FAILED=$((TESTS_FAILED + 1))
fi

echo ""
echo "📊 Test Summary"
echo "==============="
echo -e "Total Tests: $((TESTS_PASSED + TESTS_FAILED))"
echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
echo -e "${RED}Failed: $TESTS_FAILED${NC}"
echo ""

if [[ $TESTS_FAILED -eq 0 ]]; then
    echo -e "${GREEN}✅ All tests passed!${NC}"
    echo ""
    echo "🔒 Security Features Implemented:"
    echo "  ✓ CWE-209 mitigation (no information leakage)"
    echo "  ✓ CWE-391 compliance (no unhandled exceptions)"
    echo "  ✓ Error sanitization (backend + frontend)"
    echo "  ✓ Secure logging (sensitive data redaction)"
    echo "  ✓ User-friendly error messages"
    echo "  ✓ Multi-language support (EN, RO)"
    echo "  ✓ Error boundary protection"
    echo "  ✓ Global notification system"
    echo "  ✓ Process-level error handlers"
    echo "  ✓ Window-level error handlers"
    echo "  ✓ Service worker protection"
    echo "  ✓ Docker integration"
    echo ""
    echo "📚 Documentation:"
    echo "  - docs/ERROR_HANDLING_SECURITY.md"
    echo "  - docs/ERROR_HANDLING_QUICK_REFERENCE.md"
    echo ""
    exit 0
else
    echo -e "${RED}❌ Some tests failed${NC}"
    echo "Please review the errors above and fix them."
    exit 1
fi
