#!/bin/bash
# Phase 2: Schema Validation & Error Handling Tests
# Tests response schemas and error formats across all endpoints
# Date: 2026-01-20

API_BASE="http://localhost:8100/api"
RESULTS_FILE="/tmp/phase2_schema_results.txt"
PASSED=0
FAILED=0

echo "=== Phase 2: Schema Validation & Error Handling Tests ===" > $RESULTS_FILE
echo "Date: $(date)" >> $RESULTS_FILE
echo "API Base: $API_BASE" >> $RESULTS_FILE
echo "" >> $RESULTS_FILE

# Test function for schema validation
test_schema() {
    local method=$1
    local endpoint=$2
    local expected_status=$3
    local description=$4
    local data=$5
    local required_fields=$6  # Comma-separated list

    echo -n "Testing schema: $method $endpoint ... "

    if [ "$method" == "GET" ]; then
        response=$(curl -s -w "\n%{http_code}" "$API_BASE$endpoint")
    elif [ "$method" == "POST" ]; then
        response=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "$data" "$API_BASE$endpoint")
    elif [ "$method" == "DELETE" ]; then
        response=$(curl -s -w "\n%{http_code}" -X DELETE -H "Content-Type: application/json" -d "$data" "$API_BASE$endpoint")
    fi

    status=$(echo "$response" | tail -n 1)
    body=$(echo "$response" | sed '$d')

    # Check status code
    if [ "$status" != "$expected_status" ]; then
        echo "❌ FAIL (Expected: $expected_status, Got: $status)"
        echo "❌ FAIL: $method $endpoint - $description" >> $RESULTS_FILE
        echo "   Expected status: $expected_status, Got: $status" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    # Validate JSON structure
    if ! echo "$body" | jq empty 2>/dev/null; then
        echo "❌ FAIL (Invalid JSON)"
        echo "❌ FAIL: $method $endpoint - Invalid JSON response" >> $RESULTS_FILE
        echo "   Response: $(echo "$body" | head -c 200)" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    # Check required fields (check existence, not truthiness)
    missing_fields=""
    IFS=',' read -ra FIELDS <<< "$required_fields"
    for field in "${FIELDS[@]}"; do
        # Use 'type' to check if field exists (works for null, false, etc.)
        if ! echo "$body" | jq "$field | type" > /dev/null 2>&1; then
            missing_fields="$missing_fields $field"
        fi
    done

    if [ -n "$missing_fields" ]; then
        echo "❌ FAIL (Missing fields:$missing_fields)"
        echo "❌ FAIL: $method $endpoint - Missing required fields:$missing_fields" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    echo "✅ PASS"
    echo "✅ PASS: $method $endpoint - $description" >> $RESULTS_FILE
    ((PASSED++))
}

# Test error response format
test_error_format() {
    local method=$1
    local endpoint=$2
    local expected_status=$3
    local description=$4
    local data=$5

    echo -n "Testing error format: $method $endpoint ... "

    if [ "$method" == "GET" ]; then
        response=$(curl -s -w "\n%{http_code}" "$API_BASE$endpoint")
    elif [ "$method" == "POST" ]; then
        response=$(curl -s -w "\n%{http_code}" -X POST -H "Content-Type: application/json" -d "$data" "$API_BASE$endpoint")
    fi

    status=$(echo "$response" | tail -n 1)
    body=$(echo "$response" | sed '$d')

    # Check status code
    if [ "$status" != "$expected_status" ]; then
        echo "❌ FAIL (Expected: $expected_status, Got: $status)"
        echo "❌ FAIL: $method $endpoint - $description" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    # Validate error has 'success' field set to false
    success=$(echo "$body" | jq -r '.success' 2>/dev/null)
    if [ "$success" != "false" ]; then
        echo "❌ FAIL (Error missing 'success: false')"
        echo "❌ FAIL: $method $endpoint - Error response missing 'success: false'" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    # Validate error has 'message' field
    if ! echo "$body" | jq -e '.message' > /dev/null 2>&1; then
        echo "❌ FAIL (Error missing 'message' field)"
        echo "❌ FAIL: $method $endpoint - Error response missing 'message'" >> $RESULTS_FILE
        ((FAILED++))
        return
    fi

    echo "✅ PASS"
    echo "✅ PASS: $method $endpoint - $description (Error format valid)" >> $RESULTS_FILE
    ((PASSED++))
}

echo "=== 1. Success Response Schemas (200) ==="

# Events list - pagination structure
test_schema "GET" "/events" "200" "Events list has pagination" "" ".success,.data,.meta,.meta.current_page,.meta.total"

# Event detail - complete event object
test_schema "GET" "/events/mohamed-abdo-new-years-celebration-2025" "200" "Event detail has required fields" "" ".success,.data,.data.id,.data.name,.data.slug"

# Event tiers - pricing data
test_schema "GET" "/events/mohamed-abdo-new-years-celebration-2025/tiers" "200" "Event tiers has pricing data" "" ".success,.data"

echo ""
echo "=== 2. Validation Error Responses (422) ==="

# Seat hold - validation error structure
test_error_format "POST" "/seats/hold" "422" "Seat hold validation error format" '{}'

# Login - validation error with 'errors' field
test_schema "POST" "/login" "422" "Login validation has errors field" '{"email":"invalid"}' ".success,.message,.errors"

# Registration - detailed validation errors
test_schema "POST" "/register" "422" "Registration validation has field-level errors" '{"email":"test"}' ".success,.message,.errors"

echo ""
echo "=== 3. Authentication Error Responses (401) ==="

# Unauthorized access
test_error_format "GET" "/me" "401" "Unauthorized access error format" ""

# Order detail without auth
test_error_format "GET" "/orders/1" "401" "Order detail unauthorized error format" ""

# Admin routes without auth
test_error_format "GET" "/admin/events" "401" "Admin unauthorized error format" ""

echo ""
echo "=== 4. Not Found Error Responses (404) ==="

# Nonexistent event
test_error_format "GET" "/events/nonexistent-slug-12345" "404" "Event not found error format" ""

# Nonexistent booking
test_error_format "GET" "/bookings/99999" "404" "Booking not found error format" ""

echo ""
echo "=== 5. Bad Request Error Responses (400) ==="

# Missing idempotency header
test_error_format "POST" "/seats/confirm" "400" "Missing idempotency header error format" '{"hold_id":"123"}'

# Missing required header on deposit
test_error_format "POST" "/orders/deposit" "400" "Missing idempotency header on deposit" '{"hold_id":"123"}'

echo ""
echo "=== 6. Server Error Responses (500) ==="

# Venue without assignment (expected 500)
test_error_format "GET" "/events/mohamed-abdo-new-years-celebration-2025/venue" "500" "Server error format (no venue assigned)" ""

echo ""
echo "=== 7. Pagination Structure Validation ==="

# Events list pagination metadata
test_schema "GET" "/events?per_page=5" "200" "Pagination metadata structure" "" ".meta.current_page,.meta.last_page,.meta.per_page,.meta.total,.meta.from,.meta.to"

# Past events pagination
test_schema "GET" "/events?filter=past&page=1" "200" "Past events pagination" "" ".success,.data,.meta"

echo ""
echo "=========================="
echo "Results: $PASSED passed, $FAILED failed"
echo "" >> $RESULTS_FILE
echo "=========================="  >> $RESULTS_FILE
echo "SUMMARY: $PASSED passed, $FAILED failed" >> $RESULTS_FILE

cat $RESULTS_FILE

if [ $FAILED -gt 0 ]; then
    echo ""
    echo "⚠️  Some schema validation tests failed. Review results above."
    exit 1
else
    echo ""
    echo "🎉 ALL SCHEMA VALIDATION TESTS PASSED!"
    exit 0
fi
