#!/bin/bash
set -e

echo "🎯 Performance Gate CI Check"
echo "============================"

# Configuration
RESULTS_DIR="/Users/charlie/code/showprima/tests/load/results"
BASELINE_FILE="$RESULTS_DIR/performance-baseline.json"
CURRENT_RESULT=""
THRESHOLD_DEGRADATION=0.20  # 20% degradation threshold

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

# Function to find latest test result
find_latest_result() {
    CURRENT_RESULT=$(ls -t "$RESULTS_DIR"/*.json 2>/dev/null | grep -v baseline | head -n 1)
    
    if [ -z "$CURRENT_RESULT" ]; then
        echo -e "${RED}❌ No recent test results found${NC}"
        echo "Run load tests first: ./scripts/run-load-tests.sh"
        exit 1
    fi
    
    echo "📊 Analyzing: $(basename "$CURRENT_RESULT")"
}

# Function to extract metric from JSON
extract_metric() {
    local file=$1
    local metric_path=$2
    
    if command -v jq >/dev/null 2>&1; then
        jq -r "$metric_path // 0" "$file" 2>/dev/null || echo "0"
    else
        echo "0"  # Fallback if jq not available
    fi
}

# Function to compare metrics with baseline
compare_with_baseline() {
    if [ ! -f "$BASELINE_FILE" ]; then
        echo -e "${YELLOW}⚠️  No baseline found, creating baseline from current results${NC}"
        cp "$CURRENT_RESULT" "$BASELINE_FILE"
        echo -e "${GREEN}✅ Baseline created at $BASELINE_FILE${NC}"
        return 0
    fi
    
    echo ""
    echo "📈 Performance Comparison vs Baseline:"
    echo "======================================"
    
    local exit_code=0
    
    # Define metrics to check
    declare -a metrics=(
        ".metrics.availability_response_time.values.p95:Availability P95 (ms)"
        ".metrics.hold_response_time.values.p95:Hold P95 (ms)"
        ".metrics.http_req_duration.values.p95:HTTP P95 (ms)"
        ".metrics.seat_conflicts.values.rate:Conflict Rate"
        ".metrics.http_req_failed.values.rate:HTTP Failure Rate"
    )
    
    for metric_def in "${metrics[@]}"; do
        IFS=':' read -r metric_path metric_name <<< "$metric_def"
        
        local baseline_value=$(extract_metric "$BASELINE_FILE" "$metric_path")
        local current_value=$(extract_metric "$CURRENT_RESULT" "$metric_path")
        
        if [ "$baseline_value" = "0" ] && [ "$current_value" = "0" ]; then
            echo -e "${YELLOW}⚠️  $metric_name: No data available${NC}"
            continue
        fi
        
        # Calculate percentage change
        local pct_change=0
        if [ "$baseline_value" != "0" ]; then
            pct_change=$(echo "scale=4; (($current_value - $baseline_value) / $baseline_value) * 100" | bc -l 2>/dev/null || echo "0")
        fi
        
        # Determine if degradation is significant
        local is_degraded=0
        if (( $(echo "$pct_change > ($THRESHOLD_DEGRADATION * 100)" | bc -l 2>/dev/null || echo "0") )); then
            is_degraded=1
        fi
        
        # Format output
        printf "%-20s: " "$metric_name"
        printf "baseline=%.2f, current=%.2f" "$baseline_value" "$current_value"
        
        if [ "$pct_change" != "0" ]; then
            if (( $(echo "$pct_change > 0" | bc -l 2>/dev/null || echo "0") )); then
                if [ "$is_degraded" = "1" ]; then
                    printf " ${RED}(+%.1f%% - DEGRADED)${NC}" "$pct_change"
                    exit_code=1
                else
                    printf " ${YELLOW}(+%.1f%%)${NC}" "$pct_change"
                fi
            else
                printf " ${GREEN}(%.1f%% - IMPROVED)${NC}" "$pct_change"
            fi
        fi
        echo ""
    done
    
    return $exit_code
}

# Function to check absolute thresholds
check_absolute_thresholds() {
    echo ""
    echo "🚦 Absolute Threshold Checks:"
    echo "============================="
    
    local exit_code=0
    
    # Define absolute thresholds from config
    local avail_p95=$(extract_metric "$CURRENT_RESULT" ".metrics.availability_response_time.values.p95")
    local hold_p95=$(extract_metric "$CURRENT_RESULT" ".metrics.hold_response_time.values.p95")
    local conflict_rate=$(extract_metric "$CURRENT_RESULT" ".metrics.seat_conflicts.values.rate")
    local failure_rate=$(extract_metric "$CURRENT_RESULT" ".metrics.http_req_failed.values.rate")
    
    # Availability P95 < 300ms
    if (( $(echo "$avail_p95 > 0" | bc -l 2>/dev/null || echo "0") )); then
        if (( $(echo "$avail_p95 < 300" | bc -l 2>/dev/null || echo "0") )); then
            echo -e "${GREEN}✅ Availability P95: ${avail_p95}ms < 300ms${NC}"
        else
            echo -e "${RED}❌ Availability P95: ${avail_p95}ms >= 300ms${NC}"
            exit_code=1
        fi
    fi
    
    # Hold P95 < 600ms
    if (( $(echo "$hold_p95 > 0" | bc -l 2>/dev/null || echo "0") )); then
        if (( $(echo "$hold_p95 < 600" | bc -l 2>/dev/null || echo "0") )); then
            echo -e "${GREEN}✅ Hold P95: ${hold_p95}ms < 600ms${NC}"
        else
            echo -e "${RED}❌ Hold P95: ${hold_p95}ms >= 600ms${NC}"
            exit_code=1
        fi
    fi
    
    # Conflict rate < 10%
    if (( $(echo "$conflict_rate > 0" | bc -l 2>/dev/null || echo "0") )); then
        if (( $(echo "$conflict_rate < 0.1" | bc -l 2>/dev/null || echo "0") )); then
            echo -e "${GREEN}✅ Conflict Rate: $(printf "%.1f%%" $(echo "$conflict_rate * 100" | bc -l)) < 10%${NC}"
        else
            echo -e "${RED}❌ Conflict Rate: $(printf "%.1f%%" $(echo "$conflict_rate * 100" | bc -l)) >= 10%${NC}"
            exit_code=1
        fi
    fi
    
    # HTTP failure rate < 5%
    if (( $(echo "$failure_rate > 0" | bc -l 2>/dev/null || echo "0") )); then
        if (( $(echo "$failure_rate < 0.05" | bc -l 2>/dev/null || echo "0") )); then
            echo -e "${GREEN}✅ HTTP Failure Rate: $(printf "%.1f%%" $(echo "$failure_rate * 100" | bc -l)) < 5%${NC}"
        else
            echo -e "${RED}❌ HTTP Failure Rate: $(printf "%.1f%%" $(echo "$failure_rate * 100" | bc -l)) >= 5%${NC}"
            exit_code=1
        fi
    fi
    
    return $exit_code
}

# Function to update baseline if explicitly requested
update_baseline() {
    echo -e "${YELLOW}📊 Updating performance baseline...${NC}"
    cp "$CURRENT_RESULT" "$BASELINE_FILE"
    echo -e "${GREEN}✅ Baseline updated: $BASELINE_FILE${NC}"
}

# Main execution
main() {
    local command=${1:-"check"}
    
    # Check dependencies
    if ! command -v jq >/dev/null 2>&1; then
        echo -e "${YELLOW}⚠️  jq not found. Install jq for detailed analysis.${NC}"
        echo "  macOS: brew install jq"
        echo "  Linux: sudo apt-get install jq"
        echo ""
    fi
    
    if ! command -v bc >/dev/null 2>&1; then
        echo -e "${RED}❌ bc (calculator) not found. Please install bc.${NC}"
        exit 1
    fi
    
    case "$command" in
        "update-baseline")
            find_latest_result
            update_baseline
            exit 0
            ;;
        "check"|*)
            find_latest_result
            
            local baseline_exit=0
            local threshold_exit=0
            
            compare_with_baseline || baseline_exit=$?
            check_absolute_thresholds || threshold_exit=$?
            
            echo ""
            echo "🎯 Gate Decision:"
            echo "================"
            
            if [ $baseline_exit -eq 0 ] && [ $threshold_exit -eq 0 ]; then
                echo -e "${GREEN}✅ PASS: Performance gates met${NC}"
                echo "✅ All metrics within acceptable ranges"
                echo "✅ No significant performance degradation detected"
                exit 0
            else
                echo -e "${RED}❌ FAIL: Performance gates failed${NC}"
                
                if [ $baseline_exit -ne 0 ]; then
                    echo "❌ Performance degraded beyond threshold (${THRESHOLD_DEGRADATION}%)"
                fi
                
                if [ $threshold_exit -ne 0 ]; then
                    echo "❌ Absolute performance thresholds not met"
                fi
                
                echo ""
                echo "🛠️  To fix:"
                echo "- Optimize slow endpoints"
                echo "- Review database query performance"
                echo "- Check for resource constraints"
                echo "- Update baseline if performance targets changed:"
                echo "  $0 update-baseline"
                
                exit 1
            fi
            ;;
    esac
}

# Show help
show_help() {
    echo "Usage: $0 [command]"
    echo ""
    echo "Commands:"
    echo "  check            - Check performance against baseline (default)"
    echo "  update-baseline  - Update baseline with latest test results"
    echo ""
    echo "Environment:"
    echo "  THRESHOLD_DEGRADATION - Max allowed degradation (default: 0.20 = 20%)"
    echo ""
    echo "Files:"
    echo "  Results: $RESULTS_DIR/*.json"
    echo "  Baseline: $BASELINE_FILE"
}

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