#!/usr/bin/env bash
# amux-all — global view of amux sessions across every machine (local + configured boxes).
# Every box is shown compactly by default (like `amux ls -c`); each box in
# ~/.amux/remotes/<box>.env is queried via `amux-remote <box>`. Unreachable boxes
# are marked, not hung on (perl alarm bounds each call).
#
# Usage: amux-all            # every box, compact grid
#        amux-all -c         #   (same — compact is the default)
#        amux-all -v         # verbose rows from every box
set -uo pipefail

VERB=0
case "${1:-}" in
  -v|--verbose)          VERB=1 ;;
  -c|--compact|"")       VERB=0 ;;
  -h|--help)             sed -n '2,8p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
  *)                     VERB=0 ;;
esac

# Remote ls flags: --bare drops the per-command banner (amux-all prints its own box
# header below); -c makes each remote a compact grid to match the local view.
RFLAGS="--bare"; [ "$VERB" = 0 ] && RFLAGS="-c --bare"
# Keep captured (piped) remote grids fitting the real terminal width, and colored
# when we're on a real terminal (amux-remote otherwise strips color once captured).
export COLUMNS="${COLUMNS:-$(tput cols 2>/dev/null || echo 100)}"
[ -t 1 ] && export AMUX_FORCE_COLOR=1

TO=15   # per-box seconds
# Bound each box's call so ONE unreachable machine cannot hang the whole view.
# Three implementations because no single one is everywhere: `timeout` is GNU
# coreutils (Linux, Git Bash, and macOS only as `gtimeout` via coreutils), perl
# is on macOS and most Unix but not Git Bash, and the last resort is no timeout
# at all — better a slow list than a command that does not exist.
if command -v timeout >/dev/null 2>&1; then
  run_to(){ local s=$1; shift; timeout "$s" "$@"; }
elif command -v gtimeout >/dev/null 2>&1; then
  run_to(){ local s=$1; shift; gtimeout "$s" "$@"; }
elif command -v perl >/dev/null 2>&1; then
  run_to(){ local s=$1; shift; perl -e 'my $t=shift; alarm $t; exec @ARGV or exit 127' "$s" "$@"; }
else
  run_to(){ shift; "$@"; }
fi

hr(){ printf '%s\n' "────────────────────────────────────────────────────────"; }
here=$(hostname -s 2>/dev/null || hostname)

hr; printf '  ▸ %s  (local)\n' "$here"; hr
if [ "$VERB" = 1 ]; then amux ls 2>/dev/null || echo "  [local amux unavailable]"
else amux ls -c 2>/dev/null || echo "  [local amux unavailable]"; fi

show(){ # $1 label, then reads $out/$rc
  hr; printf '  ▸ %s  (remote)\n' "$1"; hr
  if [ "$rc" -eq 127 ] || [ -z "$out" ] \
     || echo "$out" | grep -qiE 'could not parse|refused|timed out|no route|could not connect|unauthor'; then
    echo "  [unreachable / offline — no response in ${TO}s]"
  else
    echo "$out" | sed 's/^/  /'
  fi
}

# Use the amux-remote from THIS checkout, not whatever is first on $PATH.
# Upstream amux ships its own amux-remote, and an older copy may also be
# installed; either would read config differently and render differently, so
# a command from this repo must drive the amux-remote from this repo.
_resolve_amux_remote() {
  local self dir real
  self="${BASH_SOURCE[0]}"
  dir=$(cd "$(dirname "$self")" && pwd)
  if [ -x "$dir/amux-remote" ]; then printf '%s\n' "$dir/amux-remote"; return; fi
  real=$(readlink "$self" 2>/dev/null || printf '%s' "$self")
  case "$real" in /*) ;; *) real="$dir/$real" ;; esac
  dir=$(cd "$(dirname "$real")" 2>/dev/null && pwd)
  if [ -n "$dir" ] && [ -x "$dir/amux-remote" ]; then printf '%s\n' "$dir/amux-remote"; return; fi
  printf 'amux-remote\n'   # last resort: whatever is on PATH
}
AMUX_REMOTE=$(_resolve_amux_remote)

remdir="${CC_HOME:-$HOME/.amux}/remotes"
if [ -d "$remdir" ] && ls "$remdir"/*.env >/dev/null 2>&1; then
  # one entry per configured box, queried via `amux-remote <box>` (box-required)
  for f in "$remdir"/*.env; do
    box=$(basename "$f" .env)
    out=$(run_to "$TO" "$AMUX_REMOTE" "$box" ls $RFLAGS 2>&1); rc=$?
    show "$box"
  done
else
  echo; echo "  (no boxes configured — add ~/.amux/remotes/<box>.env)"
fi

echo
echo "  (add more machines as ~/.amux/remotes/<name>.env to include them here)"
