#!/bin/bash
# Webcam presence detection daemon.
# Checks for a face every 2 minutes; holds a systemd-inhibit idle lock while
# the user is detected so hypridle never fires during an active session.
#
# Camera selection: set PRESENCE_DETECT_CAMERA env var or write
#   CAMERA=<id>  to ~/.config/presence-detect.conf
#
# Exit codes from python helper: 0=face, 1=no face, 2=camera error

# Resolve the script's real directory so the Python helper path stays valid
# even when invoked via a symlink or from a different cwd.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYTHON_DETECT="$SCRIPT_DIR/python/presence_detect.py"
INHIBIT_PID_FILE="/tmp/presence-inhibit.pid"
PRESENCE_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/presence-detect.conf"
INTERVAL=120    # seconds between checks

# Resolve camera ID: env var takes highest priority, then config file, then default 0.
_camera_id() {
    if [[ -n "$PRESENCE_DETECT_CAMERA" ]]; then
        echo "$PRESENCE_DETECT_CAMERA"
    elif [[ -f "$PRESENCE_CFG" ]]; then
        # -oP 'CAMERA=\K[0-9]+': Perl-style look-behind strips "CAMERA=" prefix.
        grep -oP 'CAMERA=\K[0-9]+' "$PRESENCE_CFG" 2>/dev/null || echo 0
    else
        echo 0
    fi
}

# Returns true if the inhibitor sentinel process is still alive.
_inhibit_running() {
    [[ -f "$INHIBIT_PID_FILE" ]] && kill -0 "$(cat "$INHIBIT_PID_FILE")" 2>/dev/null
}

_start_inhibit() {
    # Guard: don't start a second inhibitor if one is already active.
    _inhibit_running && return
    # --what=idle: target the logind idle-inhibit lock that hypridle polls.
    # "sleep infinity" is the sentinel; its PID is saved so we can kill it later.
    systemd-inhibit --what=idle --who="presence-detect" \
        --why="User presence detected" --mode=block \
        sleep infinity &
    echo $! > "$INHIBIT_PID_FILE"
    # logger writes to the system journal — visible via `journalctl -t presence-detect`.
    logger -t presence-detect "Presence detected — idle inhibited"
}

_stop_inhibit() {
    _inhibit_running || return
    # Killing the sleep process releases the systemd-inhibit lock automatically.
    kill "$(cat "$INHIBIT_PID_FILE")" 2>/dev/null
    rm -f "$INHIBIT_PID_FILE"
    logger -t presence-detect "No presence — idle inhibit released"
}

_cleanup() {
    # On daemon stop (systemd unit stop, user logout, etc.), release the lock cleanly.
    _stop_inhibit
    exit 0
}
# Intercept termination signals to ensure the inhibitor PID is never orphaned.
trap _cleanup SIGTERM SIGINT SIGHUP

while true; do
    CAMERA="$(_camera_id)"
    # Run the OpenCV haar-cascade detector; stderr suppressed to keep the journal clean.
    python3 "$PYTHON_DETECT" "$CAMERA" 2>/dev/null
    rc=$?
    case $rc in
        0) _start_inhibit ;;
        1) _stop_inhibit  ;;
        # rc=2 = camera unavailable — leave current inhibit state unchanged
    esac
    sleep "$INTERVAL"
done
