#!/usr/bin/env bash
# Posly print agent installer for macOS and Linux.
#
# Called from the admin Connect-Agent wizard's "Install command" step,
# usually as:
#
#   POSLY_TENANT_ID=... POSLY_API_URL=... POSLY_AGENT_TOKEN=... \
#     curl -fsSL https://install.posly.xyz/agent.sh | bash
#
# Required env vars (the wizard injects all three):
#   POSLY_TENANT_ID  — the venue's tenant ID, shown in admin.
#   POSLY_AGENT_TOKEN — per-tenant bearer minted in admin once.
#   POSLY_API_URL    — usually https://api.posly.xyz, override for staging.
#
# Optional:
#   POSLY_AGENT_DIR  — install location, default ~/posly-print-agent.
#   POSLY_INSTALL_BASE — override the install host (for staging).
#   POSLY_AGENT_VERSION — pin a specific tarball, default "latest".

set -euo pipefail

# Pretty-print steps with the same prefix the wizard uses, so an owner
# watching the terminal sees a coherent narrative instead of bash noise.
say()  { printf "\033[1;36m[posly]\033[0m %s\n" "$*"; }
fail() { printf "\033[1;31m[posly]\033[0m %s\n" "$*" >&2; exit 1; }

# ---- 1. Required env vars ----
: "${POSLY_TENANT_ID:?missing POSLY_TENANT_ID. Re-run the install command from the admin Connect-Agent wizard.}"
: "${POSLY_AGENT_TOKEN:?missing POSLY_AGENT_TOKEN. Re-run the install command from the admin Connect-Agent wizard.}"
: "${POSLY_API_URL:?missing POSLY_API_URL. Re-run the install command from the admin Connect-Agent wizard.}"

INSTALL_BASE="${POSLY_INSTALL_BASE:-https://install.posly.xyz}"
AGENT_VERSION="${POSLY_AGENT_VERSION:-latest}"
AGENT_DIR="${POSLY_AGENT_DIR:-$HOME/posly-print-agent}"

# ---- 2. Verify host has the runtime ----
say "checking Node 20+ on PATH..."
if ! command -v node >/dev/null 2>&1; then
  fail "Node.js is not installed. Install Node 20 LTS first: https://nodejs.org/en/download/  Then re-run this command."
fi
NODE_MAJOR="$(node -e 'process.stdout.write(String(process.versions.node.split(\".\")[0]))')"
if [ "$NODE_MAJOR" -lt 20 ]; then
  fail "Node $NODE_MAJOR detected. Posly print agent requires Node 20+. Upgrade via nvm or nodejs.org and re-run."
fi
say "node $(node -v) ok"

if ! command -v npm >/dev/null 2>&1; then
  fail "npm not found on PATH. Reinstall Node from nodejs.org (npm ships with it)."
fi

if ! command -v curl >/dev/null 2>&1; then
  fail "curl not found on PATH. Install curl and re-run."
fi

# ---- 3. Stop any existing agent so we don't double-print during update ----
LABEL="com.posly.print-agent"
if launchctl print "gui/$(id -u)/$LABEL" >/dev/null 2>&1; then
  say "stopping existing agent before update"
  launchctl bootout "gui/$(id -u)/$LABEL" 2>/dev/null || true
fi

# ---- 4. Download + extract the agent tarball ----
say "downloading print-agent ($AGENT_VERSION)"
TARBALL_URL="$INSTALL_BASE/posly-print-agent.tar.gz"
if [ "$AGENT_VERSION" != "latest" ]; then
  TARBALL_URL="$INSTALL_BASE/posly-print-agent-$AGENT_VERSION.tar.gz"
fi

mkdir -p "$AGENT_DIR"
TMP_TAR="$(mktemp /tmp/posly-print-agent.XXXXXX.tar.gz)"
trap 'rm -f "$TMP_TAR"' EXIT
curl -fsSL --retry 3 --retry-delay 2 -o "$TMP_TAR" "$TARBALL_URL" \
  || fail "tarball download failed from $TARBALL_URL. Check your internet, then retry."

say "extracting to $AGENT_DIR"
tar -xzf "$TMP_TAR" -C "$AGENT_DIR" --strip-components=1

# ---- 5. Write .env from the injected POSLY_* values ----
# Keep the .env file mode tight so other macOS users can't read it.
say "writing .env"
cat > "$AGENT_DIR/.env" <<EOF
POSLY_API_URL=$POSLY_API_URL
POSLY_TENANT_ID=$POSLY_TENANT_ID
POSLY_AGENT_TOKEN=$POSLY_AGENT_TOKEN
POSLY_PRINTER_CONFIG_PATH=./printer-config.json
EOF
chmod 600 "$AGENT_DIR/.env"

# Seed a default printer-config.json so first launch doesn't crash on
# missing config. The owner adds real printers via the admin Printer
# Setup wizard, which writes back over this file.
if [ ! -f "$AGENT_DIR/printer-config.json" ]; then
  echo '{}' > "$AGENT_DIR/printer-config.json"
fi

# ---- 6. Install production dependencies on the target machine ----
# We ship dist/ (transpiled JS) but NOT node_modules, since sharp and
# node-thermal-printer have platform-specific native binaries that have
# to be fetched on the target. --omit=dev keeps the agent slim.
say "installing dependencies (this may take 1-2 minutes)"
cd "$AGENT_DIR"
npm install --omit=dev --no-audit --no-fund

# ---- 7. Register as a LaunchAgent (mac) or systemd unit (linux) ----
UNAME="$(uname -s)"
case "$UNAME" in
  Darwin)
    say "registering macOS LaunchAgent"
    bash "$AGENT_DIR/install/install-macos.sh"
    ;;
  Linux)
    if command -v systemctl >/dev/null 2>&1; then
      # No bundled systemd unit yet — write a minimal one inline so the
      # agent at least survives reboots on Linux hosts (NUC, Beelink, etc).
      UNIT="$HOME/.config/systemd/user/posly-print-agent.service"
      mkdir -p "$(dirname "$UNIT")"
      cat > "$UNIT" <<EOF
[Unit]
Description=Posly print agent
After=network.target

[Service]
Type=simple
WorkingDirectory=$AGENT_DIR
ExecStart=$(command -v node) --env-file=.env dist/index.js
Restart=always
RestartSec=5

[Install]
WantedBy=default.target
EOF
      systemctl --user daemon-reload
      systemctl --user enable --now posly-print-agent.service
      say "systemd user unit started: posly-print-agent.service"
    else
      say "systemd not detected. Starting agent in foreground; supervise it yourself (pm2, supervisord)."
      exec node --env-file=.env dist/index.js
    fi
    ;;
  *)
    fail "unsupported OS: $UNAME. This installer supports macOS and Linux. Windows users: install.posly.xyz/agent.ps1"
    ;;
esac

# ---- 8. Done ----
echo ""
say "install complete. The agent is running and will dial home within 30s."
echo "  Install dir:  $AGENT_DIR"
echo "  Tail logs:    tail -f \"$HOME/Library/Logs/posly-print-agent/agent.log\""
echo "  Uninstall:    bash \"$AGENT_DIR/install/uninstall-macos.sh\""
echo ""
say "next: return to admin > Settings > Printing to confirm the green 'connected' light."
