#!/usr/bin/env bash
# billo-audio.sh — ONE command to run the whole BILLO wireless-audio rig.
#
# Usage:
#   ./billo-audio.sh start ["dev1" "dev2" ...]   # start phone-mic + audio hub (manual mode)
#   ./billo-audio.sh status                        # health of both + the URLs to open
#   ./billo-audio.sh stop                          # stop the manual copies
#
#   If the always-on service is installed (./install-service.sh), it already runs
#   both; use `./install-service.sh uninstall` to switch back to manual mode.
#   start with no devices = "MacBook Pro Microphone".
#   Pass multiple devices to MIX them into one stream (e.g. "BlackHole 2ch").
set -euo pipefail

DIR="$(cd "$(dirname "$0")" && pwd)"
PIDDIR="$DIR/.run"
mkdir -p "$PIDDIR"
export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"

HUB_PORT="${HUB_PORT:-8123}"
PHONE_PORT="${PHONE_PORT:-8200}"
PY=/usr/bin/python3

service_on() { launchctl print "gui/$(id -u)/com.billysorrells.billo-audio-hub" >/dev/null 2>&1; }

ips() {
  LAN=$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null || true)
  TS=$( (tailscale ip -4 || "$HOME/.local/bin/tailscale" ip -4) 2>/dev/null | head -1 || true)
}

start() {
  if service_on; then
    echo "always-on service is already running the hub + phone-mic."
    echo "(run ./install-service.sh uninstall first to start manually with other devices)"
    status; return 0
  fi
  local devices=("$@")
  [ ${#devices[@]} -eq 0 ] && devices=("MacBook Pro Microphone")

  ( cd "$DIR/phone-mic" && exec $PY server.py "$PHONE_PORT" --https ) \
    > "$PIDDIR/phone-mic.log" 2>&1 &
  echo $! > "$PIDDIR/phone-mic.pid"

  $PY "$DIR/hub.py" stream "${devices[@]}" --port "$HUB_PORT" \
    > "$PIDDIR/hub.log" 2>&1 &
  echo $! > "$PIDDIR/hub.pid"

  sleep 2
  status
}

status() {
  ips
  echo "BILLO audio rig:"
  service_on && echo "  mode      : always-on service (launchd)" || echo "  mode      : manual"
  if curl -sk --max-time 2 "https://127.0.0.1:$PHONE_PORT/" >/dev/null 2>&1; then
    echo "  phone-mic : UP"
    [ -n "$LAN" ] && echo "     same Wi-Fi : https://$LAN:$PHONE_PORT/?id=phone1"
    [ -n "$TS" ]  && echo "     Tailscale  : https://$TS:$PHONE_PORT/?id=phone1"
  else
    echo "  phone-mic : DOWN"
  fi
  if curl -s --max-time 2 "http://127.0.0.1:$HUB_PORT/health" >/dev/null 2>&1; then
    echo "  hub stream: UP"
    [ -n "$LAN" ] && echo "     same Wi-Fi : http://$LAN:$HUB_PORT/"
    [ -n "$TS" ]  && echo "     Tailscale  : http://$TS:$HUB_PORT/"
  else
    echo "  hub stream: DOWN"
  fi
}

stop() {
  for f in "$PIDDIR"/*.pid; do
    [ -e "$f" ] && kill "$(cat "$f")" 2>/dev/null || true
  done
  rm -f "$PIDDIR"/*.pid
  if service_on; then
    echo "stopped manual copies (always-on service left running; ./install-service.sh uninstall to stop it)"
  else
    pkill -f "hub.py stream" 2>/dev/null || true
    pkill -f "phone-mic/server.py" 2>/dev/null || true
    echo "stopped"
  fi
}

doctor() {
  # checks the parked pieces and says plainly what each one is waiting on
  status
  echo "parked hardware:"
  if ! command -v rtl_fm >/dev/null 2>&1; then echo "  RTL-SDR   : software missing (brew install rtl-sdr)"
  elif rtl_test -t 2>&1 | grep -q "Found [1-9]"; then echo "  RTL-SDR   : dongle detected — ./sdr-mic.sh <MHz> ready"
  else echo "  RTL-SDR   : PARKED — software ready, plug in the RTL-SDR dongle"; fi
  if /opt/homebrew/bin/ffmpeg -hide_banner -f avfoundation -list_devices true -i "" 2>&1 | grep -qi "apollo"; then
    echo "  Apollo    : detected — use: ./billo-audio.sh start \"Apollo\""
  else echo "  Apollo    : PARKED — Apollo Twin X not detected (needs the 22uF cap repair, or plug in any USB interface)"; fi
  TSBIN=$(command -v tailscale || echo "$HOME/.local/bin/tailscale")
  if "$TSBIN" status 2>/dev/null | grep -i mothership | grep -vq offline; then echo "  MOTHERSHIP: online"
  else echo "  MOTHERSHIP: PARKED — not on the Tailscale network (power it on + sign in to Tailscale)"; fi
}

case "${1:-}" in
  doctor) doctor ;;
  start) shift; start "$@" ;;
  status) status ;;
  stop) stop ;;
  *) echo "usage: $0 {start [dev...]|status|stop|doctor}"; exit 1 ;;
esac
