#!/bin/bash
# Officer — host dependencies for the optional, sidecar-backed features.
#
# Usage:
#   bash scripts/setup/setup-sidecars.sh
#
# WHAT THIS IS
#   Everything here was part of setup.sh and is not any more. setup.sh installs what the app needs to
#   serve itself; this installs what a handful of *optional* features need on the host, and it is never
#   invoked by setup.sh — running it is a deliberate act.
#
#   The sections keep the numbering they had in setup.sh so the two files can be read against each
#   other:
#
#     1  (was 8)   Rust
#     2  (was 9)   PulseAudio + audio dev headers
#     3  (was 10)  cliamp
#     4  (was 13)  yt-dlp
#     5  (was 17)  Remote desktop (delegates to setup-desktop.sh)
#
#   There is no `light`/`full` profile here. In setup.sh these sections were the ones `light` skipped,
#   so gating them again would only mean "run this script and have it do nothing" — running it at all
#   IS the opt-in.
#
# ORDER MATTERS: section 3 needs Go, which setup.sh installs. Run setup.sh first.
# Section 5 rewrites GRUB and switches the display manager — it takes effect on the next reboot.

set -e

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'

ok()   { echo -e "  ${GREEN}✓${NC} $1"; }
warn() { echo -e "  ${YELLOW}!${NC} $1"; }
fail() { echo -e "  ${RED}✗${NC} $1"; }
skip() { echo -e "  - $1 (already installed)"; }

has() { command -v "$1" &>/dev/null; }

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# setup.sh installed Go and rustup into the user's home and exported them for its own run only. A
# fresh shell has neither on PATH, which would make `has go` false (silently skipping the cliamp
# build) and `has rustc` false (re-running rustup over an existing toolchain). Put them back.
export PATH="$HOME/.local/go/bin:$HOME/.cargo/bin:$PATH"

# ─── detect package manager ────────────────────────────────────────────────────
if has apt; then
  PM=apt
elif has pacman; then
  PM=pacman
elif has brew; then
  PM=brew
else
  fail "No supported package manager found (apt, pacman, brew)"
  exit 1
fi

install_pkg() {
  case $PM in
    apt)    sudo apt install -y "$@" ;;
    pacman) sudo pacman -S --noconfirm "$@" ;;
    brew)   brew install "$@" ;;
  esac
}

echo ""
echo "═══════════════════════════════════════════"
echo "  Officer — optional host dependencies ($PM)"
echo "═══════════════════════════════════════════"

# ─── 1. Rust (was setup.sh section 8) ─────────────────────────────────────────
echo ""
echo "── Rust ──"

if has rustc && has cargo; then
  skip "rust ($(rustc --version 2>/dev/null | awk '{print $2}'))"
else
  curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
  export PATH="$HOME/.cargo/bin:$PATH"
  if has rustc; then ok "rust installed"; else warn "rust install failed"; fi
fi

# ─── 2. PulseAudio (headless audio for cliamp) (was section 9) ────────────────
echo ""
echo "── PulseAudio (headless audio) ──"

PULSE_PKGS=()

if has pulseaudio; then skip "pulseaudio"; else
  case $PM in
    apt)    PULSE_PKGS+=(pulseaudio) ;;
    pacman) PULSE_PKGS+=(pulseaudio) ;;
    brew)   warn "PulseAudio: brew install pulseaudio (cliamp audio won't work without it)" ;;
  esac
fi

# pulseaudio-utils provides parec and pactl
if has parec && has pactl; then skip "pulseaudio-utils (parec, pactl)"; else
  case $PM in
    apt)    PULSE_PKGS+=(pulseaudio-utils) ;;
    pacman) ;; # included in pulseaudio package
    brew)   ;; # included in pulseaudio formula
  esac
fi

# ALSA dev headers (needed to compile cliamp's Go audio library)
case $PM in
  apt)
    if dpkg -s libasound2-dev &>/dev/null 2>&1; then skip "libasound2-dev"; else PULSE_PKGS+=(libasound2-dev); fi
    ;;
  pacman)
    if pacman -Qi alsa-lib &>/dev/null 2>&1; then skip "alsa-lib"; else PULSE_PKGS+=(alsa-lib); fi
    ;;
  brew) ;; # not needed on macOS
esac

# Vorbis/OGG/FLAC dev headers (needed by cliamp's Go dependencies)
case $PM in
  apt)
    for pkg in libvorbis-dev libogg-dev libflac-dev; do
      if dpkg -s "$pkg" &>/dev/null 2>&1; then skip "$pkg"; else PULSE_PKGS+=("$pkg"); fi
    done
    ;;
  pacman)
    for pkg in libvorbis libogg flac; do
      if pacman -Qi "$pkg" &>/dev/null 2>&1; then skip "$pkg"; else PULSE_PKGS+=("$pkg"); fi
    done
    ;;
  brew) ;; # not needed on macOS
esac

if [ ${#PULSE_PKGS[@]} -gt 0 ]; then
  install_pkg "${PULSE_PKGS[@]}"
  ok "Installed: ${PULSE_PKGS[*]}"
fi

# ─── 3. cliamp (music player) (was section 10) ────────────────────────────────
echo ""
echo "── cliamp ──"

# Export GOPATH (not just PATH) so `go install` lands in GOPATH_BIN — even when Go was already present
# this run and install_go (which sets GOPATH) never ran. Otherwise go uses its default ~/go/bin and the
# check below wrongly reports a build failure.
export GOPATH="${GOPATH:-$HOME/.local/go-path}"
GOPATH_BIN="$GOPATH/bin"
export PATH="$GOPATH_BIN:$PATH"

if has cliamp; then
  skip "cliamp ($(command -v cliamp))"
else
  if ! has go; then
    warn "Go not installed — skipping cliamp build (run setup.sh first)"
  else
    echo "  Building cliamp from source..."
    TMPDIR=$(mktemp -d)
    git clone --depth=1 https://github.com/bjarneo/cliamp.git "$TMPDIR/cliamp"
    (cd "$TMPDIR/cliamp" && go install .)
    rm -rf "$TMPDIR"
    if [ -f "$GOPATH_BIN/cliamp" ]; then
      ok "cliamp installed at $GOPATH_BIN/cliamp"
    else
      warn "cliamp build failed"
    fi
  fi
fi

# ─── 4. yt-dlp (video/audio download) (was section 13) ────────────────────────
echo ""
echo "── yt-dlp ──"

# Always install/upgrade via pip to get the latest version (apt repos are outdated).
# Remove apt version first if present, then install via pip to /usr/local/bin.
if has pip3; then
  # Remove outdated apt version if installed
  case $PM in
    apt)
      if dpkg -s yt-dlp &>/dev/null 2>&1; then
        echo "  Removing outdated apt version..."
        sudo apt remove -y yt-dlp > /dev/null 2>&1
      fi
      ;;
  esac
  echo "  Installing/upgrading yt-dlp via pip..."
  sudo pip3 install --break-system-packages --upgrade yt-dlp 2>/dev/null
  if has yt-dlp; then ok "yt-dlp $(yt-dlp --version) installed"; else warn "yt-dlp pip install failed"; fi
else
  case $PM in
    apt)    install_pkg yt-dlp 2>/dev/null && ok "yt-dlp installed (apt — may be outdated)" || warn "yt-dlp not available" ;;
    pacman) install_pkg yt-dlp && ok "yt-dlp installed" ;;
    brew)   install_pkg yt-dlp && ok "yt-dlp installed" ;;
  esac
fi

# ─── 5. remote desktop (Ubuntu Desktop + VNC) (was section 17) ────────────────
echo ""
echo "── Remote Desktop (Ubuntu Desktop + VNC) ──"

# No "already installed" guard here on purpose. This used to skip on `dpkg -s ubuntu-desktop`, which
# treats one package being present as proof the whole remote desktop is configured — and those are very
# different things. A host can have ubuntu-desktop and still be missing every part that makes the mirror
# work: GDM auto-login, the forced Xorg session, the captured EDID and its kernel command line, the
# login-time mode setter. That was not hypothetical; it was this machine on 2026-08-02, where the guard
# reported "skip" while five of setup-desktop.sh's steps had never run and /desktop could not survive a
# reboot. setup-desktop.sh is idempotent throughout — every step either no-ops or is individually
# guarded — so letting it run each time converges a partially configured host instead of trusting a
# proxy for state it never actually checked.
#
# This is by far the most expensive section — it pulls the whole ubuntu-desktop meta-package, rewrites
# /etc/default/grub and switches the display manager.
case $PM in
  apt)
    bash "$SCRIPT_DIR/setup-desktop.sh"
    ;;
  *)
    warn "Remote desktop setup is Ubuntu/Debian only — skipping"
    ;;
esac

# ─── verification ─────────────────────────────────────────────────────────────
echo ""
echo "═══════════════════════════════════════════"
echo "  Verification"
echo "═══════════════════════════════════════════"
echo ""

check() {
  if has "$1"; then ok "$1"; else fail "$1 — NOT FOUND"; fi
}

echo "Rust:"
check rustc
check cargo

echo ""
echo "Audio (cliamp):"
check pulseaudio
check parec
check pactl
check cliamp

echo ""
echo "Download:"
check yt-dlp

echo ""
echo "═══════════════════════════════════════════"
echo "  Done"
echo "═══════════════════════════════════════════"
echo ""
echo "Notes:"
echo "  • PulseAudio null sink starts automatically with the server"
echo "  • Make sure ~/.cargo/bin is in your PATH for Rust tools"
echo "  • Make sure ~/.local/go-path/bin is in your PATH for Go-installed tools (cliamp)"
echo "  • REBOOT to switch into the GNOME-on-Xorg session the remote desktop mirrors"
echo ""
