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

# Generates a flamegraph SVG for Manifest decode+profile validate.
#
# Prereqs:
# - `perf` installed and usable by current user
# - `cargo flamegraph` installed (`cargo install flamegraph`)
#
# Usage examples:
#   BENCH_SAMPLE=large-02 ./tests/benchmark/flamegraph_manifest_decode_profile.sh
#   BENCH_SAMPLE=large-02 BENCH_ITERS=5000 FLAMEGRAPH_PROFILE=dev ./tests/benchmark/flamegraph_manifest_decode_profile.sh
#   BENCH_SAMPLE=large-02 BENCH_ITERS=2000 FLAMEGRAPH_PROFILE=release ./tests/benchmark/flamegraph_manifest_decode_profile.sh

PROFILE="${FLAMEGRAPH_PROFILE:-dev}" # dev|release
SAMPLE="${BENCH_SAMPLE:-large-02}"

ITERS="${BENCH_ITERS:-2000}"
FREQ="${FLAMEGRAPH_FREQ:-99}"
WARMUP="${BENCH_WARMUP_ITERS:-1}"
ROUNDS="${BENCH_ROUNDS:-1}"
MIN_ROUND_MS="${BENCH_MIN_ROUND_MS:-1}"
MAX_ITERS="${BENCH_MAX_ITERS:-100000}"

if ! command -v perf >/dev/null 2>&1; then
  echo "ERROR: perf not found. Install linux-tools/perf first (may require sudo)." >&2
  exit 2
fi

if ! command -v cargo-flamegraph >/dev/null 2>&1 && ! command -v flamegraph >/dev/null 2>&1; then
  # cargo installs as `cargo flamegraph`, but the binary is `cargo-flamegraph`.
  if ! command -v cargo-flamegraph >/dev/null 2>&1; then
    echo "ERROR: cargo-flamegraph not found. Install with: cargo install flamegraph" >&2
    exit 2
  fi
fi

OUT="target/bench/flamegraph_mft_decode_profile_${SAMPLE}_${PROFILE}.svg"

echo "profile=${PROFILE} sample=${SAMPLE} iters=${ITERS} freq=${FREQ} out=${OUT}"

FLAGS=()
if [[ "${PROFILE}" == "release" ]]; then
  FLAGS+=(--release)
else
  FLAGS+=(--dev)
fi

# On WSL2, /usr/bin/perf is often a wrapper that exits 2 because there is no
# kernel-matched perf binary. In that case, prefer a real perf binary under
# /usr/lib/linux-tools/*/perf by putting a shim earlier in PATH.
PERF_WRAPPER_OK=1
PERF_VERSION_OUT="$(perf --version 2>&1 || true)"
if echo "${PERF_VERSION_OUT}" | grep -q "WARNING: perf not found for kernel"; then
  PERF_WRAPPER_OK=0
fi

if [[ "${PERF_WRAPPER_OK}" == "0" ]]; then
  PERF_REAL="$(ls -1 /usr/lib/linux-tools/*/perf 2>/dev/null | head -n 1 || true)"
  if [[ -z "${PERF_REAL}" ]]; then
    echo "ERROR: perf wrapper found, but no real perf binary under /usr/lib/linux-tools/*/perf" >&2
    exit 2
  fi

  SHIM_DIR="target/bench/tools"
  mkdir -p "${SHIM_DIR}"
  cat > "${SHIM_DIR}/perf" <<EOF
#!/usr/bin/env bash
exec "${PERF_REAL}" "\$@"
EOF
  chmod +x "${SHIM_DIR}/perf"
  export PATH="$(pwd)/${SHIM_DIR}:${PATH}"
  echo "Using perf shim -> ${PERF_REAL}"
fi

BENCH_SAMPLE="${SAMPLE}" \
BENCH_ITERS="${ITERS}" \
BENCH_WARMUP_ITERS="${WARMUP}" \
BENCH_ROUNDS="${ROUNDS}" \
BENCH_MIN_ROUND_MS="${MIN_ROUND_MS}" \
BENCH_MAX_ITERS="${MAX_ITERS}" \
cargo flamegraph "${FLAGS[@]}" \
  -F "${FREQ}" \
  --output "${OUT}" \
  --test bench_manifest_decode_profile -- --ignored --nocapture

echo "Wrote ${OUT}"
