#!/usr/bin/env bash
# Link-health probe — bash half (INFRA-REGISTER IR-1).
#
# The shared-runner quiet predicate is PROCESS-shaped: zero non-terminal CI runs,
# no local cargo/rustc/nextest by parent chain. Both axes passed on run
# 30771155390, whose only link was degrading — 321s for a 1s checkout,
# bidirectional 10s QUIC dial timeouts, PUMP_PEER_FAIL counts a 0->3->0 and
# b 8->22->8 across green/red/rerun. Nothing in the run recorded the link, so a
# network-shaped red was triaged as if it were a product one.
#
# kitsubito is wifi-only INDEFINITELY (operator-confirmed 2026-08-02), so the
# link cannot be hardened and the predicate has to SEE it instead.
#
# THIS IS AN INSTRUMENT, NOT A GATE. It never fails the job: a probe that reds a
# run turns "the link was slow" into "the suite failed", which is the confusion
# it exists to remove. Whether a bad number should refuse a rendezvous is a
# ruling, and it is not this script's to make.
#
# JITTER IS THE SIGNAL, so it takes 5 samples and records both the median and the
# max. A median alone would have read healthy through the very run that motivated
# this: the failure shape is a link that mostly works.
#
# Usage: bash .github/bench/link-probe.sh <peer-name>
set -uo pipefail

peer="${1:?usage: link-probe.sh <peer-name>}"
samples="${LINK_PROBE_SAMPLES:-5}"

ledger_dir="${BENCH_LEDGER_DIR:-bench-ledger}"
mkdir -p "$ledger_dir" 2>/dev/null || true
key="${GITHUB_SHA:-$(git rev-parse --short HEAD 2>/dev/null || echo no-key)}"
host="${RUNNER_NAME:-${HOSTNAME:-unknown-host}}"
ledger_file="$ledger_dir/ci-$(printf '%s' "$host" | tr -c 'a-zA-Z0-9' '-').jsonl"

now_ms() { python3 -c 'import time; print(int(time.time()*1000))' 2>/dev/null || date +%s000; }

# One row, the declared field order — the same shape wrap.sh emits, and pinned
# against it by crates/xtask/tests/bench_row_parity.rs. `duration_ms` carries the
# round trip in ms, which is what the step name says it is.
row() {
  printf '{"step":"%s","key":"%s","host":"%s","duration_ms":%s,"ts_ms":%s,"ok":%s}\n' \
    "$1" "$key" "$host" "$2" "$(now_ms)" "$3" \
    >> "$ledger_file" 2>/dev/null || true
}

ts=""
for cand in tailscale /usr/bin/tailscale /snap/bin/tailscale /usr/local/bin/tailscale; do
  if command -v "$cand" >/dev/null 2>&1; then ts="$cand"; break; fi
done
if [ -z "$ts" ]; then
  echo "LINK peer=$peer probe=UNAVAILABLE reason=no-tailscale-on-path"
  row "link-rtt-med-$peer" 0 false
  exit 0
fi

# --until-direct=false keeps sending after the first pong; without it the probe
# stops at one sample and the jitter this exists to see is never measured.
out=$("$ts" ping -c "$samples" --until-direct=false "$peer" 2>&1) || true
printf '%s\n' "$out"

# `pong from <name> (<ip>) via <path> in <N>ms`
rtts=$(printf '%s\n' "$out" | sed -n 's/.* in \([0-9][0-9]*\)ms.*/\1/p' | sort -n)
count=$(printf '%s' "$rtts" | grep -c . || true)
ip=$(printf '%s\n' "$out" | sed -n 's/.*(\([0-9][0-9.]*\)).*/\1/p' | head -n 1)
path=direct
printf '%s\n' "$out" | grep -q 'via DERP' && path=relay

if [ "${count:-0}" -eq 0 ]; then
  # A labelled hole, never silence: the run that needed this most is the one
  # where nothing answered.
  echo "LINK peer=$peer probe=NO-REPLY samples=0/$samples path=unknown"
  row "link-rtt-med-$peer" 0 false
  exit 0
fi

min=$(printf '%s\n' "$rtts" | head -n 1)
max=$(printf '%s\n' "$rtts" | tail -n 1)
med=$(printf '%s\n' "$rtts" | awk -v n="$count" 'NR == int((n + 1) / 2) { print; exit }')

# Membership beside the count: the samples themselves, not just how many.
echo "LINK peer=$peer ip=${ip:-unknown} path=$path samples=$count/$samples min=${min}ms med=${med}ms max=${max}ms rtts=$(printf '%s' "$rtts" | tr '\n' ',')"
row "link-rtt-med-$peer" "$med" true
row "link-rtt-max-$peer" "$max" true
exit 0
