#!/usr/bin/env bash

# Load Test Script
# This script runs load tests on RPC endpoints

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Configuration
RPC_URL="${RPC_URL:-http://localhost:8545}"
DURATION="${DURATION:-60}"  # seconds
RPS="${RPS:-100}"  # requests per second
CONCURRENT="${CONCURRENT:-10}"  # concurrent requests


log_success "Running Load Tests..."
log_warn "RPC URL: $RPC_URL"
log_warn "Duration: $DURATION seconds"
log_warn "Requests per second: $RPS"
log_warn "Concurrent requests: $CONCURRENT"

# Test RPC endpoint availability
log_warn "Testing RPC endpoint availability..."
if curl -s -X POST -H "Content-Type: application/json" \
    --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
    "$RPC_URL" | grep -q "result"; then
    log_success "✓ RPC endpoint is available"
else
    log_error "✗ RPC endpoint is not available"
    exit 1
fi

# Load test with k6 (if available)
if command -v k6 &> /dev/null; then
    log_success "✓ k6 is available"
    
    # Create k6 test script
    cat > /tmp/k6-load-test.js <<EOF
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
    stages: [
        { duration: '30s', target: ${RPS} },
        { duration: '${DURATION}s', target: ${RPS} },
        { duration: '30s', target: 0 },
    ],
    thresholds: {
        http_req_duration: ['p(95)<500', 'p(99)<1000'],
        http_req_failed: ['rate<0.01'],
    },
};

export default function () {
    const payload = JSON.stringify({
        jsonrpc: '2.0',
        method: 'eth_blockNumber',
        params: [],
        id: 1
    });
    
    const params = {
        headers: {
            'Content-Type': 'application/json',
        },
    };
    
    const res = http.post('${RPC_URL}', payload, params);
    
    check(res, {
        'status is 200': (r) => r.status === 200,
        'response has result': (r) => JSON.parse(r.body).result !== undefined,
    });
    
    sleep(1);
}
EOF
    
    log_warn "Running k6 load test..."
    if k6 run /tmp/k6-load-test.js 2>&1 | tee /tmp/k6-load-test.log; then
        log_success "✓ k6 load test completed"
    else
        log_warn "⚠ k6 load test completed with issues (check logs)"
    fi
else
    log_warn "⚠ k6 not available. Install it for load testing:"
    echo "  https://k6.io/docs/getting-started/installation/"
    
    # Fallback: Simple load test with curl
    log_warn "Running simple load test with curl..."
    
    SUCCESS=0
    FAILED=0
    TOTAL=0
    
    END_TIME=$((SECONDS + DURATION))
    
    while [ $SECONDS -lt $END_TIME ]; do
        for i in $(seq 1 $CONCURRENT); do
            (
                if curl -s -X POST -H "Content-Type: application/json" \
                    --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
                    --max-time 5 \
                    "$RPC_URL" | grep -q "result"; then
                    echo "SUCCESS" >> /tmp/load-test-results.txt
                else
                    echo "FAILED" >> /tmp/load-test-results.txt
                fi
            ) &
        done
        sleep 1
        TOTAL=$((TOTAL + CONCURRENT))
    done
    
    wait
    
    SUCCESS=$(grep -c "SUCCESS" /tmp/load-test-results.txt 2>/dev/null || echo "0")
    FAILED=$(grep -c "FAILED" /tmp/load-test-results.txt 2>/dev/null || echo "0")
    
    log_success "Load test results:"
    echo -e "  Total requests: $TOTAL"
    echo -e "  Successful: $SUCCESS"
    echo -e "  Failed: $FAILED"
    echo -e "  Success rate: $((SUCCESS * 100 / TOTAL))%"
fi

# Test autoscaling
log_warn "Testing autoscaling..."
NAMESPACE="${NAMESPACE:-besu-network}"

if kubectl get hpa besu-rpc-hpa -n "$NAMESPACE" &>/dev/null; then
    log_success "✓ HPA exists"
    
    # Get initial replica count
    INITIAL_REPLICAS=$(kubectl get statefulset besu-rpc -n "$NAMESPACE" -o jsonpath='{.spec.replicas}' 2>/dev/null || echo "0")
    log_warn "  Initial replicas: $INITIAL_REPLICAS"
    
    # Generate load
    log_warn "  Generating load for 60 seconds..."
    END_TIME=$((SECONDS + 60))
    
    while [ $SECONDS -lt $END_TIME ]; do
        for i in $(seq 1 50); do
            curl -s -X POST -H "Content-Type: application/json" \
                --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
                "$RPC_URL" > /dev/null 2>&1 &
        done
        sleep 1
    done
    
    wait
    
    # Wait for scaling
    log_warn "  Waiting for scaling (30 seconds)..."
    sleep 30
    
    # Check replica count
    CURRENT_REPLICAS=$(kubectl get statefulset besu-rpc -n "$NAMESPACE" -o jsonpath='{.spec.replicas}' 2>/dev/null || echo "0")
    log_warn "  Current replicas: $CURRENT_REPLICAS"
    
    if [ "$CURRENT_REPLICAS" -gt "$INITIAL_REPLICAS" ]; then
        log_success "✓ Autoscaling is working (scaled from $INITIAL_REPLICAS to $CURRENT_REPLICAS)"
    else
        log_warn "⚠ Autoscaling did not trigger (may need more load or time)"
    fi
else
    log_warn "⚠ HPA not found"
fi

# Performance metrics
log_warn "Collecting performance metrics..."

# Test various RPC methods
RPC_METHODS=(
    "eth_blockNumber"
    "eth_getBlockByNumber"
    "eth_getBalance"
    "eth_call"
)

for method in "${RPC_METHODS[@]}"; do
    log_warn "  Testing $method..."
    
    START_TIME=$(date +%s%N)
    curl -s -X POST -H "Content-Type: application/json" \
        --data "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":[],\"id\":1}" \
        "$RPC_URL" > /dev/null
    END_TIME=$(date +%s%N)
    
    DURATION_MS=$(( (END_TIME - START_TIME) / 1000000 ))
    log_success "    $method: ${DURATION_MS}ms"
done

log_success "Load testing completed"

