#!/bin/bash
# ==============================================================================================
# ================================= System Watchdog ============================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Thin orchestrator — runs SYSTEM_WATCHDOG_SCRIPTS from master.conf sequentially.
# Called by watchdog_orchestrator.sh each cycle. Covers system component health:
# storage pool growth, runaway logs, WebGUI availability, and network connectivity.
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
# Driven by SYSTEM_WATCHDOG_SCRIPTS in master.conf — add, remove, or reorder there.
# Default: storage_watchdog → webgui_watchdog → network_watchdog
#
# All scripts run in the foreground. Each must complete before the next starts.
# A failed script is logged but does not prevent remaining scripts from running.
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Configuration Owns the List
#   SYSTEM_WATCHDOG_SCRIPTS in master.conf is the only place scripts are added
#   or removed. This orchestrator never needs to be edited to change what runs.
#
# Non-Fatal Steps
#   A failed watchdog step is logged and noted in the summary, but the remaining
#   steps still execute. Partial coverage is better than a halted watchdog chain.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# Root Enforcement
#   Every child script requires root. Failing here gives one clear error instead
#   of the same permission failure repeated once per child.
#
# Lock Acquisition
#   acquire_lock() prevents concurrent system watchdog runs. This is called every
#   cycle by watchdog_orchestrator.sh — a slow child must not cause two chains to
#   overlap and run the same watchdog twice.
#
# Host Detection
#   detect_hosts() sets MY_ID for notifications and logs.
#
# Empty List Guard
#   Warns and exits if SYSTEM_WATCHDOG_SCRIPTS is unconfigured. An empty list
#   would otherwise report "0/0 passed" every cycle — indistinguishable from
#   healthy, while no system monitoring is actually running.
#
# Missing Script Tolerance
#   run_orch_child() records a missing or failing child as a failed step and
#   continues. One broken watchdog never suppresses the rest of the chain.
#
# Non-Fatal Steps
#   A failed step is logged and surfaces in the summary and notification, but
#   remaining steps still execute. Partial coverage beats a halted chain.
#
# Dry Run Propagation
#   --dry-run and --log are passed through to every child script.
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master.conf
#
#   SYSTEM_WATCHDOG_SCRIPTS — ordered list of system component watchdog scripts to run
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# system_watchdog.sh
#     Run all system component watchdogs.
#
# system_watchdog.sh --dry-run
#     Passes --dry-run to each sub-script — no changes made.
#
# system_watchdog.sh --status
#     Show configured scripts and exit.
#
# system_watchdog.sh --log
#     Passes --log to each sub-script for verbose output.
#
# ==============================================================================================

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ECOSYSTEM_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

source "$ECOSYSTEM_ROOT/load_config.sh"

parse_args "$@"

# ==============================================================================================
# ━━━ Setup ━━━
# ==============================================================================================
if [[ "$EUID" -ne 0 ]]; then
    error "Must be run as root"
    exit 1
fi


acquire_lock

detect_hosts

# An empty list reports "0/0 passed" every cycle — reads as healthy while nothing is monitored.
if [[ ${#SYSTEM_WATCHDOG_SCRIPTS[@]} -eq 0 ]]; then
    warn "SYSTEM_WATCHDOG_SCRIPTS is empty — no system watchdogs will run"
    warn "Check SYSTEM_WATCHDOG_SCRIPTS in master.conf"
    exit 0
fi

[[ "$DRY_RUN" == true ]] && warn "DRY RUN — passing --dry-run to all sub-scripts"

# ==============================================================================================
# ━━━ Status ━━━
# ==============================================================================================
if [[ "$SHOW_STATUS" == true ]]; then
    echo ""
    echo "━━━━━ $ICON_SUMMARY SYSTEM WATCHDOG STATUS ━━━━━"
    echo "$ICON_HOST  Identity: $MY_ID ($LOCAL_SERVER_NAME)"
    echo "$ICON_GEAR  Scripts:  ${#SYSTEM_WATCHDOG_SCRIPTS[@]} configured"
    echo ""

    for entry in "${SYSTEM_WATCHDOG_SCRIPTS[@]}"; do
        [[ -z "$entry" ]] && continue
        read -r -a parts <<< "$entry"
        script_path="$ECOSYSTEM_ROOT/${parts[0]}"
        script_name=$(basename "${parts[0]}")
        if [[ ! -f "$script_path" ]]; then
            echo "  $ICON_ERROR $script_name — FILE NOT FOUND"
        else
            echo "  $ICON_GEAR $script_name"
        fi
    done
    echo "━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Run Sequence ━━━
# ==============================================================================================
echo "━━━ $ICON_SHIELD System Watchdog — $(date '+%Y-%m-%d %H:%M:%S') ━━━"

START=$(date +%s)
JOB_PASS=()
JOB_FAIL=()

for entry in "${SYSTEM_WATCHDOG_SCRIPTS[@]}"; do
    [[ -z "$entry" ]] && continue
    run_orch_child "$entry"
done

END=$(date +%s)

# ==============================================================================================
# ━━━ Summary ━━━
# ==============================================================================================
log "System watchdog — ${#JOB_PASS[@]}/${#SYSTEM_WATCHDOG_SCRIPTS[@]} passed — $(format_duration $(( END - START )))"

if [[ ${#JOB_FAIL[@]} -gt 0 ]]; then
    notify "System watchdog failed on $(hostname) ($MY_ID) — ${JOB_FAIL[*]}" \
        "System Watchdog" "warning"
    exit 1
fi

exit 0
