#!/bin/bash

set -e

PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
EXAMPLE_DIR="$PROJECT_ROOT/example_project"
SERVER_PID=""

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

log() {
    echo -e "${GREEN}[TEST]${NC} $1"
}

error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

cleanup() {
    if [[ -n "$SERVER_PID" ]]; then
        log "Stopping server (PID: $SERVER_PID)..."
        kill $SERVER_PID 2>/dev/null || true
        wait $SERVER_PID 2>/dev/null || true
    fi
}

trap cleanup EXIT

main() {
    log "Starting django-rsgi example project test..."

    # Change to example directory
    cd "$EXAMPLE_DIR"

    # Test 1: Install dependencies
    log "Installing dependencies..."
    if ! uv pip install -e .. granian; then
        error "Failed to install dependencies"
        exit 1
    fi

    # Test 2: Start server in background
    log "Starting Granian server..."
    uv run granian --interface rsgi rsgi:application --host 127.0.0.1 --port 8001 &
    SERVER_PID=$!

    # Wait for server to start
    log "Waiting for server to start..."
    sleep 3

    # Check if server is still running
    if ! kill -0 $SERVER_PID 2>/dev/null; then
        error "Server failed to start"
        exit 1
    fi

    log "Server started successfully (PID: $SERVER_PID)"

    # Test 3: GET request
    log "Testing GET request..."
    GET_RESPONSE=$(curl -s -w "%{http_code}" http://127.0.0.1:8001/)
    HTTP_CODE="${GET_RESPONSE: -3}"
    RESPONSE_BODY="${GET_RESPONSE%???}"

    if [[ "$HTTP_CODE" != "200" ]]; then
        error "GET request failed with status $HTTP_CODE"
        error "Response: $RESPONSE_BODY"
        exit 1
    fi

    log "GET request successful (200)"
    log "Response: $RESPONSE_BODY"

    # Validate GET response structure
    if ! echo "$RESPONSE_BODY" | jq -e '.message' > /dev/null 2>&1; then
        error "GET response missing 'message' field"
        exit 1
    fi

    # Test 4: POST request
    log "Testing POST request..."
    POST_DATA='{"test": "hello world", "number": 42}'
    POST_RESPONSE=$(curl -s -w "%{http_code}" -X POST \
        -H "Content-Type: application/json" \
        -d "$POST_DATA" \
        http://127.0.0.1:8001/echo/)

    HTTP_CODE="${POST_RESPONSE: -3}"
    RESPONSE_BODY="${POST_RESPONSE%???}"

    if [[ "$HTTP_CODE" != "200" ]]; then
        error "POST request failed with status $HTTP_CODE"
        error "Response: $RESPONSE_BODY"
        exit 1
    fi

    log "POST request successful (200)"
    log "Response: $RESPONSE_BODY"

    # Validate POST response structure
    if ! echo "$RESPONSE_BODY" | jq -e '.echo' > /dev/null 2>&1; then
        error "POST response missing 'echo' field"
        exit 1
    fi

    # Validate echoed data - compare JSON semantically
    EXPECTED_NORMALIZED=$(echo "$POST_DATA" | jq -c '.')
    ECHOED_DATA=$(echo "$RESPONSE_BODY" | jq -c '.echo')
    if [[ "$ECHOED_DATA" != "$EXPECTED_NORMALIZED" ]]; then
        error "POST echo data doesn't match input"
        error "Expected: $EXPECTED_NORMALIZED"
        error "Got: $ECHOED_DATA"
        exit 1
    fi

    # Test 5: Invalid POST request
    log "Testing invalid POST request..."
    INVALID_RESPONSE=$(curl -s -w "%{http_code}" -X POST \
        -H "Content-Type: application/json" \
        -d "invalid json" \
        http://127.0.0.1:8001/echo/)

    HTTP_CODE="${INVALID_RESPONSE: -3}"

    if [[ "$HTTP_CODE" != "400" ]]; then
        error "Invalid POST request should return 400, got $HTTP_CODE"
        exit 1
    fi

    log "Invalid POST request correctly rejected (400)"

    # Test 6: Method not allowed
    log "Testing method not allowed..."
    GET_ECHO_RESPONSE=$(curl -s -w "%{http_code}" http://127.0.0.1:8001/echo/)
    HTTP_CODE="${GET_ECHO_RESPONSE: -3}"

    if [[ "$HTTP_CODE" != "405" ]]; then
        error "GET to echo endpoint should return 405, got $HTTP_CODE"
        exit 1
    fi

    log "Method not allowed correctly handled (405)"

    log "All tests passed! 🎉"
    log "Django RSGI adapter is working correctly with Granian"
}

# Check dependencies
command -v curl >/dev/null 2>&1 || { error "curl is required but not installed."; exit 1; }
command -v jq >/dev/null 2>&1 || { error "jq is required but not installed."; exit 1; }
command -v uv >/dev/null 2>&1 || { error "uv is required but not installed."; exit 1; }

main "$@"
