#!/usr/bin/env bash
# Idempotent starter for the X2 dashboard agent.
#
# Run this every minute from cron. If the agent is already up it does nothing;
# if it is not, it starts it. That covers three cases with one mechanism:
#   * boot                - the robot came back and nobody logged in
#   * crash               - the process died
#   * manual kill         - someone stopped it by hand
#
# Why not systemd? The agi account cannot enable linger (`loginctl
# enable-linger` is denied, and sudo forbids running as root here), so a
# `systemd --user` unit only runs while a login session exists - which is
# exactly not the case after a power cycle. A cron watchdog needs no root and
# does not depend on @reboot firing correctly.

set -e

DIR="$(dirname "$(readlink -f "$0")")"
PORT="${X2_AGENT_PORT:-8781}"
LOG="$DIR/agent.log"

# Already listening? Nothing to do. Checking the port rather than the process
# also catches a process that is alive but wedged before binding.
if ss -ltn 2>/dev/null | grep -q ":${PORT} "; then
    exit 0
fi

# Avoid stacking instances if a previous start is still coming up.
if pgrep -f "x2_agent.py" >/dev/null 2>&1; then
    exit 0
fi

echo "[$(date -Is)] agent not listening on ${PORT} - starting" >> "$LOG"

# Keep the log from growing without bound (cron runs this every minute).
if [ -f "$LOG" ] && [ "$(stat -c%s "$LOG" 2>/dev/null || echo 0)" -gt 1000000 ]; then
    tail -n 200 "$LOG" > "$LOG.tmp" && mv "$LOG.tmp" "$LOG"
fi

setsid nohup "$DIR/run_agent.sh" >> "$LOG" 2>&1 < /dev/null &
exit 0
