#!/bin/bash
#
# Watchdog test script for watter-collector
#
# Detects a stalled collectd process by checking the staleness of the
# watter-collector log file. A kernel hang (e.g. spidev mutex deadlock)
# can leave collectd unable to write logs while the heating element GPIO
# remains energized — a serious safety issue. If the log is stale for
# more than 60 seconds while collectd is supposedly active, we signal
# failure so the hardware watchdog triggers a reboot.
#
# Called by the watchdog daemon with:
#   <script> test    — periodic health check (exit 0 = healthy)
#   <script> repair  — attempt repair after test failure
#
# Exit codes:
#   0   — healthy / not our problem
#   250 — file not changed in given interval (watchdog reserved code)

WATTER_LOG="${WATTER_LOG:-/var/log/watter-collector/watter.log}"
STALE_THRESHOLD=60

case "${1}" in
    test)
        # If collectd is not running, this is not a hang — don't reboot
        if ! systemctl is-active --quiet collectd.service; then
            exit 0
        fi

        # If the log file doesn't exist, collectd may have just started
        if [ ! -f "$WATTER_LOG" ]; then
            exit 0
        fi

        # Read the last line of the log
        last_line=$(tail -1 "$WATTER_LOG" 2>/dev/null)
        if [ -z "$last_line" ]; then
            exit 0
        fi

        # Extract the timestamp and check staleness
        # Fail open: if we can't parse, exit 0 (don't reboot on our errors)
        age=$(python3 -c "
import json, sys, time
try:
    entry = json.loads(sys.stdin.readline())
    log_time = float(entry['time'])
    print(int(time.time() - log_time))
except Exception:
    print(0)
" <<< "$last_line" 2>/dev/null)

        if [ -z "$age" ]; then
            exit 0
        fi

        if [ "$age" -gt "$STALE_THRESHOLD" ]; then
            exit 250
        fi

        exit 0
        ;;

    repair)
        # No meaningful repair for a kernel deadlock — proceed to reboot
        exit 250
        ;;

    *)
        # Unknown argument or no argument — safe default
        exit 0
        ;;
esac
