#!/usr/bin/env bash
# Profile each case with perf and emit a flame chart SVG + a shake-vs-VND summary.
# Requires the privileged one-time setup in SETUP_perf.md (perf installed +
# perf_event_paranoid lowered). FlameGraph is cloned automatically (no sudo).
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${HERE}/cases.sh"

FG="${HERE}/FlameGraph"

# ---- preflight ------------------------------------------------------------
[[ -x "${BIN}" ]] || { echo "Build first: ${HERE}/build_prof.sh"; exit 1; }
command -v perf >/dev/null 2>&1 || { echo "perf not found -- see SETUP_perf.md"; exit 1; }
para="$(cat /proc/sys/kernel/perf_event_paranoid 2>/dev/null || echo 99)"
if [[ "${para}" -gt 2 ]]; then
  echo "perf_event_paranoid=${para} (>2) blocks user profiling -- see SETUP_perf.md"; exit 1
fi
if [[ ! -d "${FG}" ]]; then
  echo "Cloning FlameGraph..."
  git clone --depth 1 https://github.com/brendangregg/FlameGraph "${FG}"
fi

mkdir -p "${OUT}"

# ---- per-case profiling ---------------------------------------------------
for entry in "${CASES[@]}"; do
  IFS='|' read -r name d k file kmax iters seed bk <<< "${entry}"
  data="${OUT}/${name}.data"
  folded="${OUT}/${name}.folded"
  svg="${OUT}/${name}.svg"
  summary="${OUT}/${name}.summary.txt"
  title="${name}: ${file##*/} d=${d} k=${k} seed=${seed}"

  echo "=========================================================="
  echo "Profiling ${title}"
  echo "=========================================================="
  # -F 997: ~1kHz sampling; --call-graph fp: cheap frame-pointer unwinding
  # (the solver is built with -fno-omit-frame-pointer for exactly this).
  perf record -F 997 --call-graph fp -o "${data}" -- \
      "${BIN}" $(args_for "${entry}") --csv

  perf script -i "${data}" | "${FG}/stackcollapse-perf.pl" > "${folded}"
  "${FG}/flamegraph.pl" --title "${title}" --width 1400 "${folded}" > "${svg}"

  # ---- shake-vs-VND breakdown -------------------------------------------
  # Weights are perf sample periods (proportional to on-CPU time), so the
  # percentages are time fractions. Matching works for mangled or demangled
  # symbols (both contain the token). shake3/vndX are separate TUs -> distinct
  # frames; the big non-method cost is Solution copy-assignment under main.
  awk '
    { c=$NF; total+=c
      if      ($0 ~ /shake3/)              sh+=c
      else if ($0 ~ /vnd1/)                v1+=c
      else if ($0 ~ /vnd2bi/)              v2+=c
      else if ($0 ~ /vnd3bi/)              v3+=c
      else if ($0 ~ /prim_original/)       pr+=c
      else if ($0 ~ /operator=|_Hashtable/) cp+=c
      else                                 ot+=c
    }
    function pct(x){ return total>0 ? 100.0*x/total : 0 }
    END{
      printf "case:          %s\n\n", TITLE
      printf "%-16s %8s\n", "region", "cpu %"
      printf "%-16s %8.2f%%\n", "shake3 (SHAKE)", pct(sh)
      printf "%-16s %8.2f%%\n", "vnd1",           pct(v1)
      printf "%-16s %8.2f%%\n", "vnd2bi",         pct(v2)
      printf "%-16s %8.2f%%\n", "vnd3bi",         pct(v3)
      printf "%-16s %8.2f%%\n", "sol-copy(main)", pct(cp)
      printf "%-16s %8.2f%%\n", "prim (init)",    pct(pr)
      printf "%-16s %8.2f%%\n", "other",          pct(ot)
      printf "%-16s %8.2f%%\n", "VND total", pct(v1+v2+v3)
      printf "%-16s %8.2f%%\n", "SHAKE total", pct(sh)
    }' TITLE="${title}" "${folded}" | tee "${summary}"
  echo
done

echo "Done. Artefacts in ${OUT}/  (*.svg flame charts, *.summary.txt breakdowns)"
