#!/usr/bin/env bash
# retune-mac.sh — flip a single byron-miner CLI knob on a running Mac rig and
# restart, without re-running the full join-pool-mac.sh onboarding flow.
#
# Reads the current byron-miner command line via `ps`, replaces the value of
# ONE specified --flag, kills the running miner+solver (NOT btxd), and
# relaunches with the new value (preferring tmux, falling back to nohup).
# BTX_MATMUL_* env vars are recovered from the running process when possible,
# defaulting to the conservative-apple-silicon profile values if not.
#
# Usage (pull-and-run, no manual download):
#   curl -fsS https://170-64-206-184.sslip.io/dl/retune-mac.sh | bash -s -- --gpu-inputs 1
#   curl -fsS https://170-64-206-184.sslip.io/dl/retune-mac.sh | bash -s -- --batch-size 32
#
# Tunable knobs (must ALREADY be present in the running command line — this
# script tunes existing values, it does NOT add new flags):
#   --gpu-inputs        0|1
#   --solver-threads    n   (raising above 6 risks a Metal hang)
#   --batch-size        n
#   --prepare-workers   n
#   --slice-seconds     n
#
# Exit codes: 0 success, 1 error.
#
# Safety:
#   * btxd (your wallet/node) is NEVER stopped — only byron-miner + byron-solve.
#   * If the new value triggers a regression or hang, the script prints the
#     exact one-liner to revert to the previous value.
#   * Single-variable change by design — to alter multiple knobs, re-run with
#     each one in turn (or re-run join-pool-mac.sh).

set -euo pipefail
RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m'; RESET=$'\033[0m'
err()  { printf '%serror:%s %s\n' "$RED" "$RESET" "$*" >&2; exit 1; }
ok()   { printf '%sok:%s    %s\n' "$GREEN" "$RESET" "$*" >&2; }
warn() { printf '%swarn:%s  %s\n' "$YELLOW" "$RESET" "$*" >&2; }
info() { printf '       %s\n' "$*" >&2; }

[ $# -ge 2 ] || err "usage: bash retune-mac.sh --<knob> <value>  (e.g. --gpu-inputs 1)"
FLAG="$1"; VAL="$2"
case "$FLAG" in
  --gpu-inputs|--solver-threads|--batch-size|--prepare-workers|--slice-seconds) ;;
  *) err "knob $FLAG not supported here — re-run join-pool-mac.sh for full re-onboard";;
esac
case "$VAL" in (''|*[!0-9]*) err "value must be a non-negative integer: got '$VAL'";; esac

ok "retune-mac.sh: $FLAG → $VAL"

# 1. Locate the running byron-miner via ps (same recipe as dashboard
#    troubleshooting). Filter out our own grep + this script itself.
# shellcheck disable=SC2009  # BSD pgrep has no -a; we need full cmdline for parsing
MINER_PROC="$(ps auxww | grep -iE '/byron-miner\b|\bbyron-miner --' | grep -v grep | grep -v retune-mac | head -1 || true)"
[ -n "$MINER_PROC" ] || err "no running byron-miner found — start it first with join-pool-mac.sh"

MINER_PID="$(echo "$MINER_PROC" | awk '{print $2}')"
FULL_CMD="$(ps -p "$MINER_PID" -o command= | head -1)"
[ -n "$FULL_CMD" ] || err "could not read command line for PID $MINER_PID"
info "current PID  $MINER_PID"
info "current cmd  $FULL_CMD"

# 2. Replace the flag value. Require the flag already exists; never silently
#    append (a missing flag means a profile mismatch the operator should
#    resolve via join-pool-mac.sh).
if ! echo "$FULL_CMD" | grep -qE -- "$FLAG +[0-9]+"; then
  err "$FLAG not found in current command line — can't tune what isn't set already"
fi
PREV_VAL="$(echo "$FULL_CMD" | grep -oE -- "$FLAG +[0-9]+" | head -1 | awk '{print $2}')"
if [ "$PREV_VAL" = "$VAL" ]; then
  warn "$FLAG is already $VAL — nothing to do"
  exit 0
fi
NEW_CMD="$(echo "$FULL_CMD" | sed -E "s|$FLAG +[0-9]+|$FLAG $VAL|")"
info "new cmd      $NEW_CMD"
info "(changing $FLAG from $PREV_VAL to $VAL)"

# 3. Recover env from the running process. macOS `ps -E -p PID -o command=`
#    appends envp to argv. We grep the two BTX_MATMUL_* keys join-pool-mac.sh
#    always exports; fall back to conservative-apple-silicon defaults if
#    parsing comes up empty.
PS_E="$(ps -E -p "$MINER_PID" -o command= 2>/dev/null || true)"
POOL_SLOTS="$(echo "$PS_E"  | grep -oE 'BTX_MATMUL_METAL_POOL_SLOTS=[0-9]+' | tail -1 | cut -d= -f2 || true)"
CPU_CONFIRM="$(echo "$PS_E" | grep -oE 'BTX_MATMUL_CPU_CONFIRM=[0-9]+'      | tail -1 | cut -d= -f2 || true)"
[ -n "${POOL_SLOTS:-}" ]  || { POOL_SLOTS=4;  warn "POOL_SLOTS not readable from env; defaulting to 4 (conservative)"; }
[ -n "${CPU_CONFIRM:-}" ] || { CPU_CONFIRM=1; warn "CPU_CONFIRM not readable from env; defaulting to 1 (conservative)"; }
NEW_ENV="BTX_MATMUL_METAL_POOL_SLOTS=$POOL_SLOTS BTX_MATMUL_CPU_CONFIRM=$CPU_CONFIRM"
info "env          $NEW_ENV"

# 4. Stop the current miner + its solver. btxd is untouched.
ok "stopping current byron-miner + byron-solve"
pkill -f byron-miner 2>/dev/null || true
pkill -f byron-solve 2>/dev/null || true
if command -v tmux >/dev/null 2>&1; then
  tmux has-session -t byron 2>/dev/null && tmux kill-session -t byron || true
fi
sleep 1

# 5. Restart with the new command, preferring tmux for live attach.
LOG="${HOME}/byron-miner.log"
ok "starting byron-miner with new args"
if command -v tmux >/dev/null 2>&1; then
  tmux new -d -s byron "env $NEW_ENV $NEW_CMD 2>&1 | tee -a $LOG"
  ok "byron tmux session restarted; attach: tmux attach -t byron"
else
  # shellcheck disable=SC2086  # NEW_ENV/NEW_CMD intentionally word-split
  nohup env $NEW_ENV $NEW_CMD >>"$LOG" 2>&1 &
  ok "byron-miner restarted (pid $!); logs: tail -f $LOG"
fi

# 6. Smoke check: wait up to 20s for the solver-ready handshake in the log.
ok "waiting up to 20s for solver-ready handshake…"
READY=0
for _ in 1 2 3 4 5 6 7 8 9 10; do
  sleep 2
  if grep -q "solver daemon ready" "$LOG" 2>/dev/null; then READY=1; break; fi
done
if [ $READY -eq 1 ]; then
  ok "solver daemon ready — retune complete"
  printf '\n  Watch your rate on the dashboard for ~5 min. If %s=%s makes things\n' "$FLAG" "$VAL" >&2
  printf '  worse, revert with one command:\n' >&2
  printf '    curl -fsS https://170-64-206-184.sslip.io/dl/retune-mac.sh | bash -s -- %s %s\n\n' "$FLAG" "$PREV_VAL" >&2
else
  warn "solver did not signal ready in 20s — check  tail -f $LOG"
  printf '\n  Revert with one command:\n' >&2
  printf '    curl -fsS https://170-64-206-184.sslip.io/dl/retune-mac.sh | bash -s -- %s %s\n\n' "$FLAG" "$PREV_VAL" >&2
  exit 1
fi
