#!/usr/bin/env bash
set -uo pipefail

# ---------------------------------------------------------------------------
# Compare current benchmark results against a baseline and alert on
# regressions. A regression is flagged when BOTH the percentage increase
# exceeds the threshold (default 10%) AND the absolute increase exceeds
# the minimum (default 50ms). Exits non-zero if any benchmark regressed.
#
# Usage: compare-benchmarks.sh <baseline.json> <current.json>
# ---------------------------------------------------------------------------

THRESHOLD="${BENCHMARK_REGRESSION_THRESHOLD:-10}"
# Minimum absolute increase (ms) required to flag a regression. Filters noise
# from fast benchmarks where small absolute swings produce large percentages.
MIN_ABS_MS="${BENCHMARK_MIN_ABSOLUTE_MS:-50}"

if [[ $# -lt 2 ]]; then
  echo "Usage: $0 <baseline.json> <current.json>"
  exit 1
fi

BASELINE="$1"
CURRENT="$2"

if [[ ! -f "${BASELINE}" ]]; then
  echo "No baseline found at ${BASELINE} — skipping regression check (first run)"
  exit 0
fi

if [[ ! -f "${CURRENT}" ]]; then
  echo "ERROR: Current results not found at ${CURRENT}"
  exit 1
fi

echo "Comparing benchmarks (regression threshold: ${THRESHOLD}%, min absolute: ${MIN_ABS_MS}ms)"
echo "Baseline commit: $(jq -r '.commit // "unknown"' "${BASELINE}")"
echo "Current commit:  $(jq -r '.commit // "unknown"' "${CURRENT}")"
echo ""

regressions=0
comparisons=0

# For each file in the current results, find its baseline and compare
while IFS= read -r file; do
  current_ms=$(jq -r --arg f "$file" '.results[] | select(.file == $f) | .duration_ms' "${CURRENT}")
  baseline_ms=$(jq -r --arg f "$file" '.results[] | select(.file == $f) | .duration_ms' "${BASELINE}")

  if [[ -z "${baseline_ms}" || "${baseline_ms}" == "null" ]]; then
    echo "  NEW  ${file}: ${current_ms}ms (no baseline)"
    continue
  fi

  comparisons=$((comparisons + 1))

  if [[ "${baseline_ms}" -eq 0 ]]; then
    echo "  SKIP ${file}: baseline was 0ms"
    continue
  fi

  # Calculate percentage change with awk to avoid integer truncation
  # Uses -v to pass shell variables safely (prevents awk code injection via crafted values)
  pct_change=$(awk -v c="$current_ms" -v b="$baseline_ms" 'BEGIN { printf "%.1f", (c - b) / b * 100 }')

  abs_change=$(( current_ms - baseline_ms ))

  if awk -v p="$pct_change" -v t="$THRESHOLD" 'BEGIN { exit !(p > t) }' && [[ ${abs_change} -ge ${MIN_ABS_MS} ]]; then
    echo "  REGR ${file}: ${baseline_ms}ms -> ${current_ms}ms (+${pct_change}%, +${abs_change}ms)"
    regressions=$((regressions + 1))
  elif awk -v p="$pct_change" -v t="$THRESHOLD" 'BEGIN { exit !(p < -t) }'; then
    echo "  IMPR ${file}: ${baseline_ms}ms -> ${current_ms}ms (${pct_change}%)"
  else
    echo "  OK   ${file}: ${baseline_ms}ms -> ${current_ms}ms (${pct_change}%)"
  fi
done < <(jq -r '.results[].file' "${CURRENT}")

echo ""
echo "Compared ${comparisons} benchmarks, found ${regressions} regression(s)"

if [[ ${regressions} -gt 0 ]]; then
  echo ""
  echo "WARNING: ${regressions} benchmark(s) regressed by more than ${THRESHOLD}%"
  # Write to GitHub step summary if available
  if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then
    {
      echo "### Benchmark Regression Detected"
      echo ""
      echo "${regressions} benchmark(s) regressed by more than ${THRESHOLD}%."
      echo "Check the workflow output for details."
    } >> "${GITHUB_STEP_SUMMARY}"
  fi
  exit 1
fi

echo "No regressions detected"
