#!/usr/bin/env bash
# TASK-2: does a control write actually change what the pedals feel like?
# Every write comes back acknowledged; nobody has confirmed it does anything.
#
# Four connect/hold/disconnect cycles against one adapter, which is where this
# script's own hazard lives — see `settle` and the EXIT trap below. A run that
# leaves the trainer connected at the BlueZ level poisons the *next* run with
# `le-connection-abort-by-local`, and the failure looks like a trainer fault
# rather than the script's.
set -uo pipefail

P=./target/debug/probe
NAME=VANRYSEL
D="--name $NAME"
# Seconds to let BlueZ tear a link down before asking it to build another. A
# connect issued straight after a disconnect is the reliable way to provoke
# `le-connection-abort-by-local`.
SETTLE=4

if [[ ! -x $P ]]; then
  echo "Build the probe first:  cargo build -p bikecontrol-probe" >&2
  exit 1
fi

# The address of the trainer, if BlueZ currently knows one. Used only for
# cleanup — the probe finds its own device by name.
trainer_addr () {
  bluetoothctl devices 2>/dev/null | awk -v n="$NAME" '$3 ~ n {print $2; exit}'
}

# Drop any GATT link BlueZ still holds.
#
# This is the whole point of the trap: the probe disconnects cleanly on its own
# exit path, but it never gets there if the run is interrupted — Ctrl-C reaches
# every process in the foreground group, so bash can die while the probe is
# mid-hold and leave the link open with nothing owning it. The next run then
# fails at connect for reasons that have nothing to do with the trainer.
cleanup () {
  local addr
  addr=$(trainer_addr)
  [[ -z $addr ]] && return 0
  if bluetoothctl info "$addr" 2>/dev/null | grep -q "Connected: yes"; then
    echo
    echo "  (releasing GATT link to $addr)"
    bluetoothctl disconnect "$addr" >/dev/null 2>&1
    sleep 2
  fi
}
trap cleanup EXIT INT TERM

step () {
  local target=$1 title=$2
  echo
  echo "════════════════════════════════════════════"
  echo "  $title"
  echo "════════════════════════════════════════════"
  echo "  connecting (~8s), then holding for 20s — PEDAL THROUGHOUT"

  # Output is NOT piped. `| tail -3` swallowed the live telemetry this test
  # exists to produce, and hid connect errors until the run was over. It also
  # put the probe in a pipeline, so its exit status vanished behind tail's and
  # `set -e` never fired on a failed step.
  if ! $P set $D "$target" --secs 20; then
    echo
    echo "  !! step failed: $target" >&2
    cleanup
    return 1
  fi

  # Let the link fully drop before the next step reconnects.
  sleep "$SETTLE"
}

# Start from a clean slate: a link left over from a previous run is the most
# common cause of the first step failing.
cleanup

echo "Wake the trainer first: spin the cranks for a few seconds."
echo "Press Enter when it's awake and you're ready to ride."
read -r

step resistance=15 "TEST 1 of 4 — resistance 15 of 100 (should feel EASY)"  || exit 1
step resistance=75 "TEST 2 of 4 — resistance 75 of 100 (should feel MUCH HARDER)" || exit 1
step sim=0.0       "TEST 3 of 4 — simulated gradient 0% (flat)"             || exit 1
step sim=8.0       "TEST 4 of 4 — simulated gradient +8% (a climb)"         || exit 1

echo
echo "Done — trainer reset to zero load."
echo
echo "Report back:"
echo "  a) Did 2 feel harder than 1?   (resistance mode works)"
echo "  b) Did 4 feel harder than 3?   (SIM MODE works — this is the one that matters)"
echo "  c) Roughly how much harder, and did it change instantly or drift in?"
