#!/usr/bin/env bash
# install_systemd.sh — Deploy and enable saltybot systemd services on Orin
#
# Run as root:  sudo ./systemd/install_systemd.sh
#
# What this does:
#   1. Deploy repo to /opt/saltybot/jetson
#   2. Build ROS2 workspace (colcon)
#   3. Install systemd unit files
#   4. Install udev rules (CAN, ESP32)
#   5. Enable and optionally start all services
#
# Services installed (start order):
#   can-bringup.service           CANable2 @ 1 Mbps DroneCAN (Here4 GPS)
#   saltybot-esp32-serial.service ESP32-S3 BALANCE UART bridge (bd-wim1)
#   saltybot-here4.service        Here4 GPS DroneCAN bridge (bd-p47c)
#   saltybot-ros2.service         Full ROS2 stack (perception + nav)
#   saltybot-dashboard.service    Web dashboard on port 8080
#   saltybot-social.service       Social-bot stack (speech + LLM + face)
#   tailscale-vpn.service         Tailscale VPN for remote access
#
# Prerequisites:
#   apt install ros-humble-desktop python3-colcon-common-extensions
#   pip install dronecan  (for Here4 GPS node)
#   usermod -aG dialout orin  (for serial port access)
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_DIR="$(dirname "${SCRIPT_DIR}")"
SYSTEMD_DIR="/etc/systemd/system"
DEPLOY_DIR="/opt/saltybot/jetson"
SCRIPTS_DIR="${DEPLOY_DIR}/scripts"
UDEV_DIR="/etc/udev/rules.d"
BRINGUP_SYSTEMD="${REPO_DIR}/ros2_ws/src/saltybot_bringup/systemd"
BRINGUP_UDEV="${REPO_DIR}/ros2_ws/src/saltybot_bringup/udev"
WS_SRC="${REPO_DIR}/ros2_ws/src"
WS_BUILD="${DEPLOY_DIR}/ros2_ws"

ROS_DISTRO="${ROS_DISTRO:-humble}"
ROS_SETUP="/opt/ros/${ROS_DISTRO}/setup.bash"
ORIN_USER="${SALTYBOT_USER:-orin}"

log()  { echo "[install_systemd] $*"; }
warn() { echo "[install_systemd] WARN: $*" >&2; }
die()  { echo "[install_systemd] ERROR: $*" >&2; exit 1; }

[[ "$(id -u)" == "0" ]] || die "Run as root (sudo $0)"
[[ -f "${ROS_SETUP}" ]] || die "ROS2 ${ROS_DISTRO} not found at ${ROS_SETUP}"

# ── 1. Deploy repo ─────────────────────────────────────────────────────────────
log "Deploying repo to ${DEPLOY_DIR}..."
mkdir -p "${DEPLOY_DIR}"
rsync -a \
    --exclude='.git' \
    --exclude='__pycache__' \
    --exclude='*.pyc' \
    --exclude='.pytest_cache' \
    --exclude='build/' \
    --exclude='install/' \
    --exclude='log/' \
    "${REPO_DIR}/" "${DEPLOY_DIR}/"

# Install launch wrapper script
log "Installing ros2-launch.sh..."
install -m 755 "${SCRIPT_DIR}/../scripts/ros2-launch.sh" "/opt/saltybot/scripts/ros2-launch.sh"

# ── 2. Build ROS2 workspace ────────────────────────────────────────────────────
if command -v colcon &>/dev/null; then
    log "Building ROS2 workspace (colcon)..."
    # shellcheck disable=SC1090
    source "${ROS_SETUP}"
    (
        cd "${WS_BUILD}"
        colcon build \
            --symlink-install \
            --cmake-args -DCMAKE_BUILD_TYPE=Release \
            2>&1 | tee /tmp/colcon-build.log
    )
    log "Workspace build complete."
else
    warn "colcon not found — skipping workspace build."
    warn "Run manually: cd ${WS_BUILD} && colcon build --symlink-install"
fi

# ── 3. Install systemd units ───────────────────────────────────────────────────
log "Installing systemd units..."

# Units from jetson/systemd/
for unit in \
    saltybot.target \
    saltybot-ros2.service \
    saltybot-esp32-serial.service \
    saltybot-here4.service \
    saltybot-dashboard.service \
    saltybot-social.service \
    tailscale-vpn.service
do
    if [[ -f "${SCRIPT_DIR}/${unit}" ]]; then
        cp "${SCRIPT_DIR}/${unit}" "${SYSTEMD_DIR}/"
        log "  Installed ${unit}"
    else
        warn "  ${unit} not found in ${SCRIPT_DIR}/ — skipping"
    fi
done

# Units from saltybot_bringup/systemd/
for unit in \
    can-bringup.service \
    chromium-kiosk.service \
    magedok-display.service \
    salty-face-server.service
do
    if [[ -f "${BRINGUP_SYSTEMD}/${unit}" ]]; then
        cp "${BRINGUP_SYSTEMD}/${unit}" "${SYSTEMD_DIR}/"
        log "  Installed ${unit} (from bringup)"
    else
        warn "  ${unit} not found in bringup systemd/ — skipping"
    fi
done

# ── 4. Install udev rules ──────────────────────────────────────────────────────
log "Installing udev rules..."
mkdir -p "${UDEV_DIR}"

for rule in \
    70-canable.rules \
    80-esp32.rules \
    90-magedok-touch.rules
do
    if [[ -f "${BRINGUP_UDEV}/${rule}" ]]; then
        cp "${BRINGUP_UDEV}/${rule}" "${UDEV_DIR}/"
        log "  Installed ${rule}"
    else
        warn "  ${rule} not found — skipping"
    fi
done

udevadm control --reload
udevadm trigger --subsystem-match=net   --action=add
udevadm trigger --subsystem-match=tty   --action=add
log "udev rules reloaded."

# ── 5. Set permissions ─────────────────────────────────────────────────────────
log "Ensuring '${ORIN_USER}' is in dialout group (serial port access)..."
if id "${ORIN_USER}" &>/dev/null; then
    usermod -aG dialout "${ORIN_USER}" || warn "usermod failed — add ${ORIN_USER} to dialout manually"
else
    warn "User '${ORIN_USER}' not found — skip usermod"
fi

# ── 6. Reload systemd and enable services ─────────────────────────────────────
log "Reloading systemd daemon..."
systemctl daemon-reload

log "Enabling services..."
systemctl enable \
    saltybot.target \
    can-bringup.service \
    saltybot-esp32-serial.service \
    saltybot-here4.service \
    saltybot-ros2.service \
    saltybot-dashboard.service \
    saltybot-social.service \
    tailscale-vpn.service

# Enable mosquitto (MQTT broker) if installed
if systemctl list-unit-files mosquitto.service &>/dev/null; then
    systemctl enable mosquitto.service
    log "  Enabled mosquitto.service"
fi

# ── 7. Summary ────────────────────────────────────────────────────────────────
log ""
log "Installation complete."
log ""
log "Services will start automatically on next reboot."
log "To start now without rebooting:"
log "  sudo systemctl start saltybot.target"
log ""
log "Check status:"
log "  systemctl status can-bringup saltybot-esp32-serial saltybot-here4 saltybot-ros2 saltybot-dashboard"
log ""
log "Live logs:"
log "  journalctl -fu can-bringup"
log "  journalctl -fu saltybot-esp32-serial"
log "  journalctl -fu saltybot-here4"
log "  journalctl -fu saltybot-ros2"
log "  journalctl -fu saltybot-dashboard"
log ""
log "Dashboard: http://<orin-ip>:8080"
log "rosbridge: ws://<orin-ip>:9090"
log ""
log "Note: saltybot-esp32-serial and saltybot-here4 require packages"
log "  from bd-wim1 (PR #727) and bd-p47c (PR #728) to be merged."
