#!/bin/bash
# ==============================================================================================
# ======================= Upgrade Webhook Listener (continuous) ================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Starts a standalone Node.js HTTP server that receives Sonarr/Radarr/Lidarr
# OnUpgrade webhooks and dispatches upgrade_webhook_handler.sh.
#
# Runs outside Unraid nginx — no session auth required. The shared secret in
# the webhook URL is the only gate. Arrs on this host call:
#
#   http://<HOST_LAN_IP>:<WEBHOOK_PORT>/webhook?key=<WEBHOOK_SECRET>
#
# Runs as a continuous script started by array_started.sh. Execs node which
# replaces this process — the PID stays the same for array_started.sh's check.
#
# Uses Node.js instead of php -S: php -S on Unraid PHP 8.4 silently drops
# POST request bodies, making webhook payloads arrive empty.
#
# If WEBHOOK_SECRET is empty in master.conf: generates and saves one, then starts.
# If WEBHOOK_PORT is 0: exits cleanly (disables the listener).
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
#   1. Check WEBHOOK_PORT — exit cleanly if 0 (listener disabled)
#   2. Check WEBHOOK_SECRET — generate and persist one if empty
#   3. exec node webhook_listener.js — replaces this process; PID stays the same
#
# exec is intentional: array_started.sh tracks the PID of this script to check
# whether the listener is running. exec preserves that PID across the hand-off
# to node.
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Node.js Over php -S
#   php -S on Unraid PHP 8.4 silently drops POST request bodies — webhooks arrive
#   empty and the handler has no payload to act on. Node.js handles POST bodies
#   correctly and has no equivalent silent-drop behaviour.
#
# Runs Outside nginx
#   The listener binds directly to WEBHOOK_PORT — no nginx proxy, no session auth.
#   The shared secret in the URL query string is the only gate. This keeps the
#   webhook path independent of the auth stack.
#
# exec Preserves PID
#   The script execs into node rather than forking it. array_started.sh stores the
#   PID of this script to check liveness — exec ensures that PID continues to
#   refer to the running node process after the hand-off.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
#   WEBHOOK_PORT=0 gate  — exits cleanly before any setup if the listener is disabled
#   Secret auto-generate — WEBHOOK_SECRET generated via openssl rand if empty;
#                          persisted to master.conf immediately so restarts reuse it
#   Shared secret gate   — webhook URL must include ?key=<WEBHOOK_SECRET>;
#                          requests without a valid key are rejected by the Node.js server
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# master.conf
#
#   WEBHOOK_PORT    — port the listener binds to; 0 = disabled
#   WEBHOOK_SECRET  — shared secret for URL auth; auto-generated if empty
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
# start_webhook_listener.sh
#     Started automatically at array start via ARRAY_START_SCRIPTS.
#     Exits immediately if WEBHOOK_PORT=0.
#
# To stop:
#     pkill -f webhook_listener.js
#
# ==============================================================================================

set -uo pipefail

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

source "$ECOSYSTEM_ROOT/load_config.sh"

[[ "${WEBHOOK_PORT:-0}" -eq 0 ]] && {
    echo "[webhook] WEBHOOK_PORT=0 — listener disabled"
    exit 0
}

# ── Auto-generate secret if not yet set ─────────────────────────────────────
if [[ -z "${WEBHOOK_SECRET:-}" ]]; then
    GENERATED=$(openssl rand -hex 32)
    MASTER_CONF="$ECOSYSTEM_ROOT/Configurations/master.conf"
    sed -i "s/WEBHOOK_SECRET=\"\"/WEBHOOK_SECRET=\"$GENERATED\"/" "$MASTER_CONF"
    WEBHOOK_SECRET="$GENERATED"
    echo "[webhook] Generated WEBHOOK_SECRET — run Tools/webhook_setup.sh to register in arrs"
fi

mkdir -p /var/log/varaverk

exec node "$ECOSYSTEM_ROOT/Media/webhook_listener.js" \
    "$WEBHOOK_PORT" "$WEBHOOK_SECRET" "$ECOSYSTEM_ROOT" \
    >> /var/log/varaverk/upgrade_webhook.log 2>&1
