#!/bin/bash
# Bulk Event Retrieval Performance Test
# Tests retrieving hundreds of events to measure JSON reconstruction performance

# Load test keys
source tests/.test_keys.txt

RELAY_URL="${RELAY_URL:-ws://localhost:8888}"
NUM_EVENTS=500

# Use test secret keys for creating valid events
SECRET_KEYS=(
    "3fdd8227a920c2385559400b2b14e464f22e80df312a73cc7a86e1d7e91d608f"
    "a156011cd65b71f84b4a488ac81687f2aed57e490b31c28f58195d787030db60"
    "1618aaa21f5bd45c5ffede0d9a60556db67d4a046900e5f66b0bae5c01c801fb"
)

echo "=========================================="
echo "Bulk Event Retrieval Performance Test"
echo "=========================================="
echo "Relay: $RELAY_URL"
echo "Target: Retrieve $NUM_EVENTS events"
echo ""

# Check if relay is running
echo "Checking if relay is running..."
if ! nc -z localhost 8888 2>/dev/null; then
    echo "ERROR: Relay is not running on port 8888"
    exit 1
fi
echo "✓ Relay is running"
echo ""

# Check if nak is installed
if ! command -v nak &> /dev/null; then
    echo "ERROR: 'nak' command not found. Please install nak:"
    echo "  go install github.com/fiatjaf/nak@latest"
    exit 1
fi

# Check current event count in database
DB_FILE=$(ls build/*.db 2>/dev/null | head -1)
if [ -n "$DB_FILE" ]; then
    CURRENT_COUNT=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM events WHERE kind=1;" 2>/dev/null || echo "0")
    echo "Current kind 1 events in database: $CURRENT_COUNT"
    
    if [ "$CURRENT_COUNT" -ge "$NUM_EVENTS" ]; then
        echo "✓ Database already has $CURRENT_COUNT events (>= $NUM_EVENTS required)"
        echo "  Skipping event posting..."
        echo ""
    else
        EVENTS_TO_POST=$((NUM_EVENTS - CURRENT_COUNT))
        echo "Need to post $EVENTS_TO_POST more events..."
        echo ""
        
        # Post additional events
        echo "Posting $EVENTS_TO_POST test events using nak..."
        for i in $(seq 1 $EVENTS_TO_POST); do
            # Cycle through secret keys
            KEY_INDEX=$(( (i - 1) % ${#SECRET_KEYS[@]} ))
            CURRENT_KEY=${SECRET_KEYS[$KEY_INDEX]}
            
            # Create content
            CONTENT="Bulk test event $i/$EVENTS_TO_POST for performance testing"
            
            # Post event using nak (properly signed)
            nak event -c "$CONTENT" --sec "$CURRENT_KEY" "$RELAY_URL" >/dev/null 2>&1
            
            # Progress indicator
            if [ $((i % 50)) -eq 0 ]; then
                echo "  Posted $i/$EVENTS_TO_POST events..."
            fi
        done
        echo "✓ Posted $EVENTS_TO_POST test events"
        echo ""
    fi
else
    echo "WARNING: Could not find database file"
    echo "Posting $NUM_EVENTS events anyway..."
    echo ""
    
    # Post events
    echo "Posting $NUM_EVENTS test events using nak..."
    for i in $(seq 1 $NUM_EVENTS); do
        KEY_INDEX=$(( (i - 1) % ${#SECRET_KEYS[@]} ))
        CURRENT_KEY=${SECRET_KEYS[$KEY_INDEX]}
        CONTENT="Bulk test event $i/$NUM_EVENTS for performance testing"
        nak event -c "$CONTENT" --sec "$CURRENT_KEY" "$RELAY_URL" >/dev/null 2>&1
        
        if [ $((i % 50)) -eq 0 ]; then
            echo "  Posted $i/$NUM_EVENTS events..."
        fi
    done
    echo "✓ Posted $NUM_EVENTS test events"
    echo ""
fi

# Wait for events to be stored
echo "Waiting 2 seconds for events to be stored..."
sleep 2
echo ""

# Test 1: Retrieve 500 events using nak req
echo "=========================================="
echo "TEST 1: Retrieve $NUM_EVENTS events"
echo "=========================================="
echo "Sending REQ with limit=$NUM_EVENTS..."
echo ""

START_TIME=$(date +%s%N)

# Use nak req to retrieve events (properly handles subscription protocol)
RESPONSE=$(nak req -k 1 -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)

END_TIME=$(date +%s%N)
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))

# Count events received (each line is one event)
EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')

echo "Results:"
echo "  Time elapsed: ${ELAPSED_MS}ms"
echo "  Events received: $EVENT_COUNT"
echo ""

if [ $EVENT_COUNT -ge $((NUM_EVENTS - 10)) ]; then
    echo "✓ TEST 1 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
    if [ $ELAPSED_MS -lt 100 ]; then
        echo "  ⚡ EXCELLENT: <100ms for $EVENT_COUNT events!"
    elif [ $ELAPSED_MS -lt 500 ]; then
        echo "  ✓ GOOD: <500ms for $EVENT_COUNT events"
    elif [ $ELAPSED_MS -lt 2000 ]; then
        echo "  ⚠ ACCEPTABLE: <2s for $EVENT_COUNT events"
    else
        echo "  ⚠ SLOW: ${ELAPSED_MS}ms for $EVENT_COUNT events (expected <100ms)"
    fi
else
    echo "✗ TEST 1 FAILED: Only retrieved $EVENT_COUNT events (expected ~$NUM_EVENTS)"
fi
echo ""

# Test 2: Retrieve events by author (use first test key's pubkey)
echo "=========================================="
echo "TEST 2: Retrieve events by author"
echo "=========================================="
echo "Sending REQ with authors filter..."
echo ""

# Get pubkey from first secret key
TEST_PUBKEY=$(nak key public ${SECRET_KEYS[0]})

START_TIME=$(date +%s%N)

RESPONSE=$(nak req -k 1 -a "$TEST_PUBKEY" -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)

END_TIME=$(date +%s%N)
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))

EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')

echo "Results:"
echo "  Time elapsed: ${ELAPSED_MS}ms"
echo "  Events received: $EVENT_COUNT"
echo "  (Note: Only events from first test key, ~1/3 of total)"
echo ""

if [ $EVENT_COUNT -ge $((NUM_EVENTS / 3 - 20)) ]; then
    echo "✓ TEST 2 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
else
    echo "⚠ TEST 2 WARNING: Only retrieved $EVENT_COUNT events (expected ~$((NUM_EVENTS / 3)))"
fi
echo ""

# Test 3: Retrieve events with time filter
echo "=========================================="
echo "TEST 3: Retrieve events with time filter"
echo "=========================================="
echo "Sending REQ with since filter (last hour)..."
echo ""

SINCE_TIME=$(($(date +%s) - 3600))

START_TIME=$(date +%s%N)

RESPONSE=$(nak req -k 1 --since "$SINCE_TIME" -l $NUM_EVENTS "$RELAY_URL" 2>/dev/null)

END_TIME=$(date +%s%N)
ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))

EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')

echo "Results:"
echo "  Time elapsed: ${ELAPSED_MS}ms"
echo "  Events received: $EVENT_COUNT"
echo ""

if [ $EVENT_COUNT -ge $((NUM_EVENTS - 10)) ]; then
    echo "✓ TEST 3 PASSED: Retrieved $EVENT_COUNT events in ${ELAPSED_MS}ms"
else
    echo "⚠ TEST 3 WARNING: Only retrieved $EVENT_COUNT events (expected ~$NUM_EVENTS)"
fi
echo ""

# Test 4: Multiple small retrievals (simulating real-world usage)
echo "=========================================="
echo "TEST 4: Multiple small retrievals (50 events × 10 times)"
echo "=========================================="
echo "Simulating real-world client behavior..."
echo ""

TOTAL_TIME=0
TOTAL_EVENTS=0
for i in $(seq 1 10); do
    START_TIME=$(date +%s%N)
    
    RESPONSE=$(nak req -k 1 -l 50 "$RELAY_URL" 2>/dev/null)
    
    END_TIME=$(date +%s%N)
    ELAPSED_MS=$(( (END_TIME - START_TIME) / 1000000 ))
    TOTAL_TIME=$((TOTAL_TIME + ELAPSED_MS))
    
    EVENT_COUNT=$(echo "$RESPONSE" | grep -c '^{')
    TOTAL_EVENTS=$((TOTAL_EVENTS + EVENT_COUNT))
    echo "  Request $i: ${ELAPSED_MS}ms ($EVENT_COUNT events)"
done

AVG_TIME=$((TOTAL_TIME / 10))

echo ""
echo "Results:"
echo "  Total time: ${TOTAL_TIME}ms"
echo "  Total events: $TOTAL_EVENTS"
echo "  Average time per request: ${AVG_TIME}ms"
echo ""

if [ $AVG_TIME -lt 50 ]; then
    echo "✓ TEST 4 PASSED: Average retrieval time ${AVG_TIME}ms (excellent)"
elif [ $AVG_TIME -lt 200 ]; then
    echo "✓ TEST 4 PASSED: Average retrieval time ${AVG_TIME}ms (good)"
else
    echo "⚠ TEST 4 WARNING: Average retrieval time ${AVG_TIME}ms (slow)"
fi
echo ""

# Performance Summary
echo "=========================================="
echo "PERFORMANCE SUMMARY"
echo "=========================================="
echo ""
echo "Expected performance with event_json optimization:"
echo "  - 366 events: <10ms (previously 18 seconds)"
echo "  - 500 events: <15ms"
echo "  - Per-event overhead: ~0.02ms (vs 50ms before)"
echo ""

if [ -n "$DB_FILE" ]; then
    FINAL_COUNT=$(sqlite3 "$DB_FILE" "SELECT COUNT(*) FROM events WHERE kind=1;" 2>/dev/null || echo "0")
    echo "Final database stats:"
    echo "  Total kind 1 events: $FINAL_COUNT"
    echo "  Database file: $DB_FILE"
    echo ""
fi

echo "Check relay logs for [QUERY] entries to see actual query times:"
echo "  journalctl -u c-relay -n 100 | grep QUERY"
echo ""

echo "=========================================="
echo "Test Complete"
echo "=========================================="
