#!/bin/bash
set -e

echo "🚀 Opening Bell Load Test Runner"
echo "================================="

# Configuration
BASE_URL=${BASE_URL:-"http://localhost:8000"}
EVENT_ID=${EVENT_ID:-1}
LOAD_TEST_DIR="/Users/charlie/code/showprima/tests/load"
RESULTS_DIR="/Users/charlie/code/showprima/tests/load/results"

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

# Ensure k6 is installed
check_k6() {
    if ! command -v k6 >/dev/null 2>&1; then
        echo -e "${RED}❌ k6 is not installed${NC}"
        echo ""
        echo "Install k6:"
        echo "  macOS: brew install k6"
        echo "  Linux: sudo apt-get install k6"
        echo "  Other: https://k6.io/docs/getting-started/installation/"
        exit 1
    fi
    
    echo -e "${GREEN}✅ k6 found: $(k6 version --quiet)${NC}"
}

# Check server availability
check_server() {
    echo "🔍 Checking server availability at $BASE_URL..."
    
    if ! curl -s --connect-timeout 5 "$BASE_URL/api/seats/availability/$EVENT_ID" >/dev/null; then
        echo -e "${RED}❌ Server not accessible at $BASE_URL${NC}"
        echo ""
        echo "Start the server:"
        echo "  php artisan serve --host=0.0.0.0 --port=8000"
        echo ""
        echo "Or set BASE_URL environment variable:"
        echo "  export BASE_URL=http://your-server:port"
        exit 1
    fi
    
    echo -e "${GREEN}✅ Server is accessible${NC}"
}

# Setup test environment
setup_test_env() {
    echo "🛠️  Setting up test environment..."
    
    # Create results directory
    mkdir -p "$RESULTS_DIR"
    
    # Create test seats if needed
    echo "🎫 Creating test seats..."
    curl -s -X POST \
        -H "Content-Type: application/json" \
        -d "{\"event_id\": $EVENT_ID, \"seat_count\": 50}" \
        "$BASE_URL/__test/seats/create" >/dev/null || {
        echo -e "${YELLOW}⚠️  Could not create test seats (may already exist or test routes disabled)${NC}"
    }
    
    echo -e "${GREEN}✅ Test environment ready${NC}"
}

# Run baseline test
run_baseline() {
    echo ""
    echo "📊 Running baseline performance test..."
    
    k6 run \
        --env BASE_URL="$BASE_URL" \
        --env EVENT_ID="$EVENT_ID" \
        --vus 50 \
        --duration 30s \
        --out json="$RESULTS_DIR/baseline-$(date +%Y%m%d-%H%M%S).json" \
        "$LOAD_TEST_DIR/opening-bell.js" \
        2>&1 | tee "$RESULTS_DIR/baseline-output.log"
    
    echo -e "${GREEN}✅ Baseline test completed${NC}"
}

# Run opening bell scenarios
run_opening_bell() {
    echo ""
    echo "🔔 Running Opening Bell scenarios..."
    
    local timestamp=$(date +%Y%m%d-%H%M%S)
    
    # Run the full opening bell test
    k6 run \
        --env BASE_URL="$BASE_URL" \
        --env EVENT_ID="$EVENT_ID" \
        --out json="$RESULTS_DIR/opening-bell-$timestamp.json" \
        "$LOAD_TEST_DIR/opening-bell.js" \
        2>&1 | tee "$RESULTS_DIR/opening-bell-output-$timestamp.log"
    
    echo -e "${GREEN}✅ Opening Bell test completed${NC}"
}

# Analyze results
analyze_results() {
    echo ""
    echo "📈 Analyzing results..."
    
    local latest_result=$(ls -t "$RESULTS_DIR"/*.json 2>/dev/null | head -n 1)
    
    if [ -z "$latest_result" ]; then
        echo -e "${YELLOW}⚠️  No result files found${NC}"
        return
    fi
    
    echo "Latest result: $latest_result"
    
    # Extract key metrics using jq if available
    if command -v jq >/dev/null 2>&1; then
        echo ""
        echo "📊 Key Metrics:"
        echo "---------------"
        
        # HTTP request duration p95
        local http_p95=$(jq -r '.metrics.http_req_duration.values.p95 // "N/A"' "$latest_result")
        echo "HTTP P95: ${http_p95}ms"
        
        # Availability response time p95
        local avail_p95=$(jq -r '.metrics.availability_response_time.values.p95 // "N/A"' "$latest_result")
        echo "Availability P95: ${avail_p95}ms"
        
        # Hold response time p95
        local hold_p95=$(jq -r '.metrics.hold_response_time.values.p95 // "N/A"' "$latest_result")
        echo "Hold P95: ${hold_p95}ms"
        
        # Conflict rate
        local conflict_rate=$(jq -r '.metrics.seat_conflicts.values.rate // "N/A"' "$latest_result")
        echo "Conflict Rate: ${conflict_rate}"
        
        # Failure rate
        local failure_rate=$(jq -r '.metrics.http_req_failed.values.rate // "N/A"' "$latest_result")
        echo "HTTP Failure Rate: ${failure_rate}"
        
        # Performance gate check
        echo ""
        echo "🎯 Performance Gates:"
        echo "--------------------"
        
        # Check thresholds
        if [ "$avail_p95" != "N/A" ] && [ "$avail_p95" != "null" ]; then
            if (( $(echo "$avail_p95 < 300" | bc -l 2>/dev/null || echo 0) )); then
                echo -e "${GREEN}✅ Availability P95 ($avail_p95ms) < 300ms${NC}"
            else
                echo -e "${RED}❌ Availability P95 ($avail_p95ms) >= 300ms${NC}"
            fi
        fi
        
        if [ "$hold_p95" != "N/A" ] && [ "$hold_p95" != "null" ]; then
            if (( $(echo "$hold_p95 < 600" | bc -l 2>/dev/null || echo 0) )); then
                echo -e "${GREEN}✅ Hold P95 ($hold_p95ms) < 600ms${NC}"
            else
                echo -e "${RED}❌ Hold P95 ($hold_p95ms) >= 600ms${NC}"
            fi
        fi
        
        if [ "$conflict_rate" != "N/A" ] && [ "$conflict_rate" != "null" ]; then
            if (( $(echo "$conflict_rate < 0.1" | bc -l 2>/dev/null || echo 0) )); then
                echo -e "${GREEN}✅ Conflict Rate ($conflict_rate) < 10%${NC}"
            else
                echo -e "${RED}❌ Conflict Rate ($conflict_rate) >= 10%${NC}"
            fi
        fi
        
    else
        echo -e "${YELLOW}⚠️  Install jq for detailed metrics analysis${NC}"
        echo "Raw results available in: $latest_result"
    fi
}

# Check database state after test
check_db_state() {
    echo ""
    echo "🗄️  Checking database state..."
    
    # Check for stale holds
    local stale_check_response
    stale_check_response=$(curl -s "$BASE_URL/__test/state" 2>/dev/null || echo '{"error": "could not check"}')
    
    if echo "$stale_check_response" | grep -q '"stale_holds"'; then
        local stale_count=$(echo "$stale_check_response" | jq -r '.stale_holds // "unknown"' 2>/dev/null || echo "unknown")
        echo "Stale holds: $stale_count"
        
        if [ "$stale_count" = "0" ]; then
            echo -e "${GREEN}✅ No stale holds found${NC}"
        else
            echo -e "${YELLOW}⚠️  Found $stale_count stale holds${NC}"
        fi
    else
        echo -e "${YELLOW}⚠️  Could not check database state (test routes may be disabled)${NC}"
    fi
}

# Main execution
main() {
    local scenario=${1:-"all"}
    
    check_k6
    check_server
    setup_test_env
    
    case "$scenario" in
        "baseline")
            run_baseline
            ;;
        "opening-bell")
            run_opening_bell
            ;;
        "all"|*)
            run_baseline
            run_opening_bell
            ;;
    esac
    
    analyze_results
    check_db_state
    
    echo ""
    echo "🎉 Load testing completed!"
    echo ""
    echo "Results saved in: $RESULTS_DIR"
    echo "View detailed results:"
    echo "  HTML: open $RESULTS_DIR/load-test-summary.html"
    echo "  JSON: cat $RESULTS_DIR/*.json | jq ."
}

# Show help
show_help() {
    echo "Usage: $0 [scenario]"
    echo ""
    echo "Scenarios:"
    echo "  baseline     - Light load baseline test (50 VUs, 30s)"
    echo "  opening-bell - Full opening bell simulation"
    echo "  all          - Run both scenarios (default)"
    echo ""
    echo "Environment variables:"
    echo "  BASE_URL     - Server URL (default: http://localhost:8000)"
    echo "  EVENT_ID     - Event ID to test (default: 1)"
    echo ""
    echo "Examples:"
    echo "  $0                              # Run all scenarios"
    echo "  $0 baseline                     # Run baseline only"
    echo "  BASE_URL=http://staging.com $0  # Test against staging"
}

# Handle command line arguments
case "${1:-}" in
    "-h"|"--help")
        show_help
        exit 0
        ;;
    *)
        main "$@"
        ;;
esac
