#!/usr/bin/env bash
# The alternating-pairs protocol for measuring the description layer.
#
# WHAT THE TWO SIDES ARE, AND WHY THEY CHANGED
#
# This script used to serve one side through Askama and the other through the
# description layer, switching with `QUASI_SCREENS`. That switch was deleted in
# `64b33b26`: `quasi::mounts` is unconditional, the route tables register no
# Askama counterpart, and there is nothing left to revert to. Nothing reads the
# variable, so every run the old script made measured the same binary four times
# and reported a delta of zero -- which reads as "the conversion bought nothing"
# and means "the experiment did not run".
#
# So the two sides are two BUILDS, at two revisions. That is also the comparison
# there is now a question about: every described screen renders through quasi
# either way, and what differs is whether its markup is derived at build time
# and walked (the residual seam, quasicoherent `793d99dd`) or built as a `Node`
# and rendered per request.
#
# Both trees are built and run on astra, one after another, on the same box with
# the same database. fw13 is where the day's editing happens and a load
# measurement wants a quiet machine.
#
# READ THE CONTROLS FIRST. Not every described screen is on the seam --
# `ssh-keys` and `analytics` are not, for reasons filed against quasicoherent --
# so they report in both runs as themselves. A run where the seam screens move
# and the controls move with them measured the box, not the seam.
#
# Also read the report's `Rej` column before anything else. A rejected request is
# fast, so a route answering 403 or 404 wins a latency comparison it never ran.
#
# THE PROFILE IS RELEASE, and it is here rather than in shell history so a later
# reader knows which one produced the numbers. Render cost is the quantity being
# compared, and in debug it is dominated by unoptimized rendering.
#
# THE BOX IS aarch64. Absolute figures here are not comparable with the
# 2026-08-14 sweep's, whatever box that used; what is comparable is the
# before/after within one run of this script.
#
# Usage:
#   scripts/load-conversion-ab.sh                     # HEAD against the pre-seam tree
#   BEFORE_MNW=abc1234 BEFORE_QUASI=def5678 scripts/load-conversion-ab.sh
#   MT_LATENCY=500 scripts/load-conversion-ab.sh      # slow Multithreaded
#
# Sweep MT_LATENCY to find the upstream latency at which holding a blocking-pool
# thread across an outbound call starts to cost something: the two forum screens
# are the only described ones whose work is an HTTP call rather than a query.
# Sizing the pool is a config line either way, so the output worth having is the
# threshold, not a pass/fail.

set -euo pipefail
cd "$(dirname "$0")/.."

CODE="$(cd ../.. && pwd)"

# The tree before the seam took the screens this measures. `c554d7ed` is the
# last MNW commit with four screens on the seam rather than thirteen, and
# `b5a21fe` is the quasi it was written against.
: "${BEFORE_MNW:=c554d7ed}"
: "${BEFORE_QUASI:=b5a21fe}"
: "${HOST:=astra}"
: "${ROOT:=ab-seam}"
: "${MIX:=anon:25,buyer:15,creator:10,dash:50}"
: "${VUS:=60}"
: "${DURATION:=60}"
: "${RAMP:=10}"
: "${MT_LATENCY:=0}"
: "${OUT:=target/load-ab}"

AFTER_MNW="$(git -C "$CODE/MNW" rev-parse --short HEAD)"
AFTER_QUASI="$(git -C "$CODE/quasi" rev-parse --short HEAD)"
SHARED="$CODE/_private/infra/bootstrap/cargo-config.shared.toml"

echo "before: MNW $BEFORE_MNW quasi $BEFORE_QUASI"
echo "after:  MNW $AFTER_MNW quasi $AFTER_QUASI"

# Pristine trees from git rather than rsynced working copies. The two sides
# differ by a revision and nothing else, and an uncommitted edit in either would
# make the comparison say something other than what it claims.
REMOTE_HOME="$(ssh "$HOST" 'echo $HOME')"
ssh "$HOST" "rm -rf ~/$ROOT && mkdir -p ~/$ROOT/{before,after}/{MNW,quasi,Libraries,.cargo}"

send() { git -C "$CODE/$1" archive "$2" | ssh "$HOST" "tar -x -C ~/$ROOT/$3"; }
send MNW "$BEFORE_MNW" before/MNW
send quasi "$BEFORE_QUASI" before/quasi
send MNW "$AFTER_MNW" after/MNW
send quasi "$AFTER_QUASI" after/quasi

for side in before after; do
    # The siblings the `[patch]` block redirects that neither revision touches.
    for repo in synckit Libraries/docengine Libraries/quasi-type; do
        rsync -aq --delete --exclude 'target/' --exclude '.git/' --exclude 'mutants.out/' \
            "$CODE/$repo/" "$HOST:$ROOT/$side/$repo/"
    done
    # `[patch]` with absolute paths. The local pair resolves twice -- `include`
    # against the symlink's directory, then the included file's paths against
    # the parent of its own -- and neither survives being copied to another
    # layout. `[build]` and `[profile]` are fw13's numbers.
    awk -v root="$REMOTE_HOME/$ROOT/$side" '
        /^\[/ { keep = ($0 ~ /^\[patch/) }
        keep { gsub(/path = "\.\.\/\.\.\//, "path = \"" root "/"); print }
    ' "$SHARED" | ssh "$HOST" "cat > ~/$ROOT/$side/.cargo/config.toml"
done

# A patch that silently did not apply is the one failure a green run cannot tell
# you about: the side would be built against the published quasi rather than the
# revision this script just shipped.
for side in before after; do
    [ "$(ssh "$HOST" "grep -c 'path = \"/' ~/$ROOT/$side/.cargo/config.toml")" -gt 0 ] ||
        { echo "the $side cargo config carries no absolute patch paths" >&2; exit 1; }
done

ssh "$HOST" "cat > ~/$ROOT/run.sh" <<REMOTE
set -u
ROOT="\$HOME/$ROOT"
OUT="\$ROOT/out"
mkdir -p "\$OUT"
export PATH="\$HOME/.cargo/bin:\$PATH"
export TEST_DATABASE_URL="\${TEST_DATABASE_URL:-postgres:///postgres}"
export LOAD_VUS=$VUS
export LOAD_DURATION_SECS=$DURATION
export LOAD_RAMP_SECS=$RAMP
export LOAD_MIX="$MIX"
export LOAD_MT_LATENCY_MS=$MT_LATENCY

# Built outside the timed runs: a cold compile inside run 1 would show up as run
# 1 being slower than run 4, which is the shape the alternation cancels out.
for side in before after; do
    echo "=== building \$side ==="
    ( cd "\$ROOT/\$side/MNW/server" && cargo test --release --test load --no-run --quiet ) \
        > "\$OUT/build-\$side.log" 2>&1 || { echo "build \$side FAILED"; exit 1; }
done

run() {
    echo "=== run \$1 (\$2) ==="
    ( cd "\$ROOT/\$2/MNW/server" && cargo test --release --test load -- --ignored --nocapture ) \
        > "\$OUT/\$1-\$2.txt" 2>&1
    echo "run \$1 exit=\$?"
}

# before, after, after, before. The pairs are inner and the controls outer so a
# drift in the box over the run lands on both sides rather than on one.
run 1 before
run 2 after
run 3 after
run 4 before
echo DONE
REMOTE

echo "Running on $HOST. Four reports will land in ~/$ROOT/out/."
ssh "$HOST" "bash ~/$ROOT/run.sh"

mkdir -p "$OUT"
scp -q "$HOST:$ROOT/out/*.txt" "$OUT/" || true
echo
echo "Reports under $OUT/. Compare 2+3 against 1+4, per endpoint label."
echo "The described screens report under 'HTMX described:*' in both, so the rows"
echo "line up and only what serves them changed."
