#!/bin/bash
# Benchmark: sx vs zig HTTP server
# Usage: bash bench/run.sh [requests] [concurrency]

set -e
cd "$(dirname "$0")/.."

# Build outputs go in the gitignored scratch dir, not the tree.
mkdir -p .sx-tmp

REQUESTS=${1:-10000}
CONCURRENCY=${2:-50}
WARMUP=500

SX_PORT=8080
ZIG_PORT=8081

RED='\033[0;31m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
BOLD='\033[1m'
RESET='\033[0m'

cleanup() {
    [[ -n "$SX_PID" ]]  && kill "$SX_PID"  2>/dev/null || true
    [[ -n "$ZIG_PID" ]] && kill "$ZIG_PID" 2>/dev/null || true
    wait 2>/dev/null || true
}
trap cleanup EXIT

echo -e "${BOLD}=== sx vs zig HTTP server benchmark ===${RESET}"
echo -e "requests: ${CYAN}$REQUESTS${RESET}  concurrency: ${CYAN}$CONCURRENCY${RESET}"
echo ""

# --- Build ---
echo -e "${BOLD}Building sx server...${RESET}"
time_sx_build=$( { time ./zig-out/bin/sx build examples/1602-platform-http-server.sx -o .sx-tmp/sx-server 2>&1; } 2>&1 | tail -1 )
echo "  $time_sx_build"

echo -e "${BOLD}Building zig server...${RESET}"
time_zig_build=$( { time zig build-exe bench/http-server.zig -O ReleaseFast -femit-bin=.sx-tmp/zig-server 2>&1; } 2>&1 | tail -1 )
echo "  $time_zig_build"
echo ""

wait_for_port() {
    local port=$1
    for i in $(seq 1 30); do
        if curl -s -o /dev/null "http://127.0.0.1:$port" 2>/dev/null; then
            return 0
        fi
        sleep 0.1
    done
    echo "FAIL: server on port $port did not start" >&2
    return 1
}

run_bench() {
    local name=$1
    local port=$2
    local color=$3

    echo -e "${BOLD}${color}--- $name (port $port) ---${RESET}"

    # Warmup
    ab -n $WARMUP -c 10 -q "http://127.0.0.1:$port/" > /dev/null 2>&1 || true

    # Benchmark
    ab -n "$REQUESTS" -c "$CONCURRENCY" -q "http://127.0.0.1:$port/" 2>/dev/null | \
        grep -E '(Requests per second|Time per request|Transfer rate|Total transferred|Failed requests|Time taken)'
    echo ""
}

# --- sx server ---
.sx-tmp/sx-server > /dev/null 2>&1 &
SX_PID=$!
wait_for_port $SX_PORT

run_bench "sx" $SX_PORT "$GREEN"

kill "$SX_PID" 2>/dev/null; wait "$SX_PID" 2>/dev/null || true
SX_PID=""
sleep 0.5

# --- zig server ---
.sx-tmp/zig-server > /dev/null 2>&1 &
ZIG_PID=$!
wait_for_port $ZIG_PORT

run_bench "zig" $ZIG_PORT "$CYAN"

kill "$ZIG_PID" 2>/dev/null; wait "$ZIG_PID" 2>/dev/null || true
ZIG_PID=""

echo -e "${BOLD}Done.${RESET}"
