#!/bin/bash
# check_uptime - system uptime (Nagios/NRPE plugin).
# Usage: check_uptime [-w <hours>] [-c <hours>]
# Thresholds are in HOURS (decimals allowed) to match the Vexor "Uptime"
# service UI and the Windows/NSClient++ variant. WARN/CRIT when the host has
# been up LESS than the threshold (i.e. a recent/unexpected reboot).
# Empty or non-numeric thresholds are treated as unset (disabled), so calling
# the plugin with no options - or with the args NRPE forwards when a field is
# left blank - is always OK instead of erroring.
set -u
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"

warn_h=""; crit_h=""
# Leading ':' -> we handle unknown options / missing args ourselves (ignore),
# so a stray token forwarded by NRPE never turns into a hard UNKNOWN.
while getopts ":w:c:h" o; do
    case "$o" in
        w) warn_h=$OPTARG ;;
        c) crit_h=$OPTARG ;;
        h) echo "Usage: $(basename "$0") [-w hours] [-c hours]"; exit 3 ;;
        *) : ;;
    esac
done

is_num() { case "$1" in ''|*[!0-9.]*|*.*.*|.) return 1 ;; *) return 0 ;; esac; }

# hours -> integer seconds; empty/non-numeric -> "" (threshold disabled)
to_sec() { if is_num "$1"; then awk -v h="$1" 'BEGIN{printf "%d", h*3600}'; else echo ""; fi; }
warn=$(to_sec "$warn_h")
crit=$(to_sec "$crit_h")

[ -r /proc/uptime ] || { echo "UNKNOWN: cannot read /proc/uptime"; exit 3; }
up=$(cut -d. -f1 /proc/uptime)
[ -n "${up:-}" ] || { echo "UNKNOWN: cannot parse uptime"; exit 3; }

d=$(( up / 86400 ))
h=$(( up % 86400 / 3600 ))
m=$(( up % 3600 / 60 ))
pretty=""
[ "$d" -gt 0 ] && pretty="${d}d "
pretty="${pretty}${h}h ${m}m"

perf="uptime=${up}s;${warn};${crit};0;"

if [ -n "$crit" ] && [ "$up" -lt "$crit" ]; then
    echo "CRITICAL: up $pretty (recent reboot) | $perf"; exit 2
fi
if [ -n "$warn" ] && [ "$up" -lt "$warn" ]; then
    echo "WARNING: up $pretty (recent reboot) | $perf"; exit 1
fi
echo "OK: up $pretty | $perf"; exit 0
