#!/bin/sh
### BEGIN INIT INFO
# Provides:          anvillm-inbox-notify
# Required-Start:    $local_fs $syslog
# Required-Stop:     $local_fs $syslog
# Should-Start:      $network dbus
# Should-Stop:       $network dbus
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: AnviLLM inbox notification daemon
# Description:       Monitors the AnviLLM event stream and delivers desktop
#                    notifications (via notify-send) when messages of configured
#                    types (default: APPROVAL_REQUEST, REVIEW_REQUEST) arrive in
#                    the human user's inbox.
### END INIT INFO

# ── configuration ─────────────────────────────────────────────────────────────
#
# Set ANVILLM_USER to the login name of the desktop user who should receive
# notifications.  The daemon needs that user's X11 DISPLAY and D-Bus session
# bus address; this script discovers them automatically from /proc.
#
# Override in /etc/default/anvillm-inbox-notify (sourced below if it exists).
#
ANVILLM_USER="${ANVILLM_USER:-}"

NAME="anvillm-inbox-notify"
DAEMON="/usr/local/bin/anvillm-inbox-notify"
PIDFILE="/var/run/${NAME}.pid"
LOGFILE="/var/log/${NAME}.log"

# Source distro defaults (if any).
[ -r /etc/default/anvillm-inbox-notify ] && . /etc/default/anvillm-inbox-notify

# ── sanity checks ─────────────────────────────────────────────────────────────

if [ -z "$ANVILLM_USER" ]; then
    echo "${NAME}: ANVILLM_USER is not set." >&2
    echo "  Set it in /etc/default/anvillm-inbox-notify:" >&2
    echo "    ANVILLM_USER=yourlogin" >&2
    exit 6   # LSB: program not configured
fi

if [ ! -x "$DAEMON" ]; then
    echo "${NAME}: daemon not found at ${DAEMON}" >&2
    exit 5   # LSB: program not installed
fi

# ── helpers ───────────────────────────────────────────────────────────────────

# get_env_var VAR USER
# Read an environment variable from any running process owned by USER.
get_env_var() {
    local var="$1" user="$2"
    local pid
    pid=$(pgrep -u "$user" -x Xorg 2>/dev/null || pgrep -u "$user" -x X 2>/dev/null || pgrep -u "$user" 2>/dev/null | head -1)
    [ -z "$pid" ] && return 1
    # /proc/<pid>/environ is null-separated; grep for the variable and extract value
    tr '\0' '\n' < "/proc/${pid}/environ" 2>/dev/null | grep "^${var}=" | head -1 | cut -d= -f2-
}

# discover_session_env
# Populates DISPLAY_ENV and DBUS_ENV for ANVILLM_USER.
discover_session_env() {
    DISPLAY_ENV=$(get_env_var DISPLAY "$ANVILLM_USER")
    DBUS_ENV=$(get_env_var DBUS_SESSION_BUS_ADDRESS "$ANVILLM_USER")

    if [ -z "$DISPLAY_ENV" ]; then
        # Fall back to :0 — correct for a single local X session
        DISPLAY_ENV=":0"
    fi

    if [ -z "$DBUS_ENV" ]; then
        # Try the well-known systemd path for the user's UID
        local uid
        uid=$(id -u "$ANVILLM_USER" 2>/dev/null)
        if [ -n "$uid" ]; then
            DBUS_ENV="unix:path=/run/user/${uid}/bus"
        fi
    fi
}

daemon_running() {
    [ -s "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null
}

# ── actions ───────────────────────────────────────────────────────────────────

do_start() {
    if daemon_running; then
        echo "${NAME} is already running (PID $(cat "$PIDFILE"))."
        return 0   # LSB: 0 = already running is not an error
    fi

    discover_session_env

    echo "Starting ${NAME} as ${ANVILLM_USER} (DISPLAY=${DISPLAY_ENV})..."

    su -s /bin/sh -l "$ANVILLM_USER" -c "
        export DISPLAY='${DISPLAY_ENV}'
        export DBUS_SESSION_BUS_ADDRESS='${DBUS_ENV}'
        nohup '${DAEMON}' >> '${LOGFILE}' 2>&1 &
        echo \$! > '${PIDFILE}'
    "

    # Brief wait and confirm.
    sleep 1
    if daemon_running; then
        echo "${NAME} started (PID $(cat "$PIDFILE"))."
        return 0
    else
        echo "${NAME}: failed to start — check ${LOGFILE}" >&2
        rm -f "$PIDFILE"
        return 1
    fi
}

do_stop() {
    if ! daemon_running; then
        echo "${NAME} is not running."
        rm -f "$PIDFILE"
        return 0   # LSB: 0 = already stopped is not an error
    fi

    local pid
    pid=$(cat "$PIDFILE")
    echo "Stopping ${NAME} (PID ${pid})..."
    kill "$pid" 2>/dev/null
    # Wait up to 5 s for the process to exit.
    local i=0
    while kill -0 "$pid" 2>/dev/null && [ "$i" -lt 5 ]; do
        sleep 1
        i=$((i + 1))
    done
    if kill -0 "$pid" 2>/dev/null; then
        echo "${NAME}: still running after 5 s, sending SIGKILL..."
        kill -9 "$pid" 2>/dev/null
    fi
    rm -f "$PIDFILE"
    echo "${NAME} stopped."
    return 0
}

do_status() {
    if daemon_running; then
        echo "${NAME} is running (PID $(cat "$PIDFILE"))."
        return 0   # LSB status: 0 = running
    elif [ -s "$PIDFILE" ]; then
        echo "${NAME} is dead but PID file ${PIDFILE} exists."
        return 1   # LSB status: 1 = dead, pidfile exists
    else
        echo "${NAME} is not running."
        return 3   # LSB status: 3 = not running
    fi
}

# ── dispatch ──────────────────────────────────────────────────────────────────

case "$1" in
    start)
        do_start
        ;;
    stop)
        do_stop
        ;;
    restart|force-reload)
        do_stop
        sleep 1
        do_start
        ;;
    reload)
        # The daemon re-reads its config on next startup; no live reload needed.
        echo "${NAME}: reload not supported — use restart instead."
        exit 3   # LSB: unimplemented feature
        ;;
    status)
        do_status
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
        exit 2   # LSB: invalid argument
        ;;
esac

exit $?
