#!/bin/bash
# ==============================================================================================
# ================================= Array Start Orchestrator ===================================
# ==============================================================================================
# Single entry point for array start — fired by the Varaverk plugin's
# disks_mounted event hook (Plugin/unraid/event/disks_mounted/array_start_jobs).
# Launches everything configured in ARRAY_START_SCRIPTS in master.conf.
# This script exits after launching all scripts — the event hook sees it complete normally.
#
# ── WHAT IT LAUNCHES ──────────────────────────────────────────────────────────────────────────
# Configured in master.conf ARRAY_START_SCRIPTS — no changes to this script ever needed.
# Current order (order matters — see below):
#
#   ONE-SHOT (run and exit naturally):
#     System_Essentials/unraid_api_key_renew.sh — re-register Varaverk API key at boot
#     System_Essentials/inotify_tuning.sh       — raise inotify limits before containers start
#     System_Essentials/docker_syslog_filter.sh — suppress veth log noise before logs fill
#     System_Essentials/php_fpm_max_children.sh — WebGUI performance tuning
#     Transcodes/ramdisk_setup.sh               — create tmpfs + symlink before Emby starts
#     Docker_Essentials/docker_network_connect.sh — ensure networks + container connections
#
#   CONTINUOUS (run until array stops):
#     Fallback/fallback.sh                      — mutual fallback monitor
#
#   NOTE: watchdogs (docker, system, stability) are NOT launched here.
#   They run via watchdog_orchestrator.sh every 15 min (cron), not as daemons.
#
# ── WHY ORDER MATTERS ─────────────────────────────────────────────────────────────────────────
#   unraid_api_key_renew.sh — before anything else — self-heals API registry at boot
#   inotify_tuning.sh     — must run BEFORE Code-Server and other containers start
#                           containers that start with low inotify limits keep them ✅
#   docker_syslog_filter  — must run BEFORE any container starts creating veth interfaces
#   ramdisk_setup.sh      — must run BEFORE Emby starts transcoding
#   docker_network_connect — must run BEFORE watchdogs check container states
#   fallback.sh           — last — needs everything else stable to make decisions
#
# ── ONE-SHOT vs CONTINUOUS DETECTION ─────────────────────────────────────────────────────────
# Script is launched in background with bash script.sh &
# After 1 second: if PID still alive → continuous (running in background)
#                  if PID dead + exit 0 → one-shot completed successfully
#                  if PID dead + exit N → failure
#
# ── SAFEGUARDS ────────────────────────────────────────────────────────────────────────────────
#   Root check           — all launched scripts require root
#   acquire_lock         — prevents duplicate array start launches
#   detect_hosts()       — MY_ID in notifications
#   platform_require_cmd  — notify validated before use
#   chmod +x auto-fix    — non-executable scripts fixed before launch
#   Full path on failure — shows exact path for debugging
#   notify on failures   — alert if any script fails to launch
#
# ── CONFIGURATION (master.conf) ───────────────────────────────────────────────────────────────
#   ARRAY_START_SCRIPTS — ordered list of scripts to launch at array start
#
# ── USAGE ─────────────────────────────────────────────────────────────────────────────────────
#   array_started.sh              — normal launch (called by Varaverk disks_mounted event hook)
#   array_started.sh --dry-run    — show what would be launched without launching
#   array_started.sh --status     — show configured scripts and their current state
#   array_started.sh --log        — verbose output per script
# ==============================================================================================

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

[[ "$DRY_RUN" == true ]] && warn "DRY RUN — scripts will not be launched"

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

    for relative_path in "${ARRAY_START_SCRIPTS[@]}"; do
        [[ -z "$relative_path" ]] && continue
        script_path="$ECOSYSTEM_ROOT/$relative_path"
        script_name=$(basename "$script_path")

        if [[ ! -f "$script_path" ]]; then
            echo "  $ICON_ERROR $script_name — FILE NOT FOUND"
            echo "    $script_path"
            continue
        fi

        [[ ! -x "$script_path" ]] && flag=" (not executable — will auto-fix)" || flag=""

        # Check if currently running
        if pgrep -f "$script_path" >/dev/null 2>&1; then
            RUN_PID=$(pgrep -f "$script_path" | head -1)
            echo "  $ICON_RUNNING $script_name — RUNNING (PID $RUN_PID)${flag}"
        else
            echo "  $ICON_NOT_RUNNING $script_name — not running${flag}"
        fi
    done
    echo "━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Launch Scripts ━━━
# ==============================================================================================
if [[ ${#ARRAY_START_SCRIPTS[@]} -eq 0 ]]; then
    notify "Array started on $LOCAL_SERVER_NAME ($MY_ID) but ARRAY_START_SCRIPTS is empty — boot sequence skipped. Check master.conf." \
        "Array Start" "alert"
    error "ARRAY_START_SCRIPTS is empty — check master.conf"
    exit 1
fi

echo ""
echo "━━━ $ICON_GEAR Array Start — $MY_ID — $(date '+%Y-%m-%d %H:%M:%S') ━━━"
log "Ecosystem root: $ECOSYSTEM_ROOT"
log "Launching ${#ARRAY_START_SCRIPTS[@]} script(s)..."
echo ""

START=$(date +%s)
LAUNCHED=0
FAILED=0
FAILED_SCRIPTS=()

for relative_path in "${ARRAY_START_SCRIPTS[@]}"; do
    [[ -z "$relative_path" ]] && continue

    SCRIPT_PATH="$ECOSYSTEM_ROOT/$relative_path"
    SCRIPT_NAME=$(basename "$SCRIPT_PATH")

    # File existence check
    if [[ ! -f "$SCRIPT_PATH" ]]; then
        error "$SCRIPT_NAME — not found"
        error "  Expected: $SCRIPT_PATH"
        (( FAILED++ ))
        FAILED_SCRIPTS+=("$SCRIPT_NAME")
        continue
    fi

    # Auto-fix permissions — chmod +x if needed
    if [[ ! -x "$SCRIPT_PATH" ]]; then
        warn "$SCRIPT_NAME — not executable, fixing..."
        chmod +x "$SCRIPT_PATH" || {
            error "$SCRIPT_NAME — chmod +x failed"
            (( FAILED++ ))
            FAILED_SCRIPTS+=("$SCRIPT_NAME")
            continue
        }
    fi

    if [[ "$DRY_RUN" == true ]]; then
        warn "DRY RUN — would launch: $SCRIPT_NAME"
        (( LAUNCHED++ ))
        continue
    fi

    log "$ICON_START Launching $SCRIPT_NAME..."
    bash "$SCRIPT_PATH" &
    PID=$!

    # Brief settle — 1s enough to detect immediate failures
    sleep 1

    if kill -0 "$PID" 2>/dev/null; then
        # Still running → continuous script
        warn "$SCRIPT_NAME — running (PID $PID) ✅"
        (( LAUNCHED++ ))
    else
        # Exited — check if one-shot success or failure
        wait "$PID"
        EXIT_CODE=$?
        if [[ "$EXIT_CODE" -eq 0 ]]; then
            echo "$SCRIPT_NAME — completed (one-shot) ✅"
            (( LAUNCHED++ ))
        else
            error "$SCRIPT_NAME — exited with code $EXIT_CODE"
            error "  Path: $SCRIPT_PATH"
            (( FAILED++ ))
            FAILED_SCRIPTS+=("$SCRIPT_NAME")
        fi
    fi

done

END=$(date +%s)

# ==============================================================================================
# ━━━ Summary ━━━
# ==============================================================================================
echo ""
echo "━━━━━ $ICON_SUMMARY ARRAY START SUMMARY ━━━━━"
echo "$ICON_HOST    Identity: $MY_ID ($LOCAL_SERVER_NAME)"
echo "$ICON_SUCCESS Launched: $LAUNCHED"
[[ "$FAILED" -gt 0 ]] && echo "$ICON_ERROR  Failed:   $FAILED — ${FAILED_SCRIPTS[*]}"
echo "$ICON_TIME    Duration: $(format_duration $(( END - START )))"
echo ""

if [[ "$DRY_RUN" == true ]]; then
    warn "DRY RUN — no scripts launched"
elif [[ "$FAILED" -gt 0 ]]; then
    warn "Status: $FAILED script(s) failed — ${FAILED_SCRIPTS[*]}"
    notify "Array start on $(hostname) ($MY_ID) — $FAILED script(s) failed: ${FAILED_SCRIPTS[*]}" \
        "Array Start" "warning"
else
    echo "$ICON_DONE Status: all $LAUNCHED script(s) launched ✅"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"