#!/bin/bash
# ==============================================================================================
# ============================= Remote Arr Cache Writer ========================================
# ==============================================================================================
#
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# SSHes to each remote partner host, calls vv_arrs_local_node() on their PHP
# stack, and caches the result locally in /tmp/vv_cache/arrs_remote_hostN.json.
#
# The arrs page reads these files for instant initial load without hitting the
# remote arr APIs on every page view. This script runs every 2 hours so remote
# library counts stay reasonably current without hammering the network.
#
# Accepts --host=HOST2 to refresh a single host (used by the UI refresh button).
#
# ==============================================================================================
# DESIGN PRINCIPLES
# ==============================================================================================
#
# Cache-First, Never Live on Page Load
#   Remote arr APIs have non-trivial latency — calling them on every page view
#   would make the arrs page slow and fragile. Writing to /tmp/vv_cache/ on a
#   2-hour schedule decouples page load time from network availability.
#
# Single-Host Refresh for UI
#   The UI refresh button passes --host=HOSTN to update one host without waiting
#   for the full 2-hour cycle. Keeps the cache fresh when a user requests it.
#
# ==============================================================================================
# OPERATIONAL MODEL
# ==============================================================================================
#
# Per partner host:
#   1. Resolve its Tailscale IP — unresolvable skips that host, not the run
#   2. SSH across and call vv_arrs_local_node() on its own PHP stack
#   3. Write the JSON to /tmp/vv_cache/arrs_remote_<hostid>.json locally
#
# The remote builds its own payload rather than this host querying the remote's arr APIs
# directly — the partner already has working local URLs and keys for its own arrs, so no
# cross-host credentials or path mapping are involved.
#
# Runs every 2 hours. The arrs page reads these files for an instant first paint and falls
# back to live calls when a file is missing or stale.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
#   acquire_lock    — prevents concurrent cache write runs
#   detect_hosts()  — MY_ID and partner host list
#   SSH reachability — skips a host cleanly if it cannot be reached
#   /tmp/vv_cache/  — auto-created if missing; cleared on reboot (intentional)
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#
# host*.conf
#
#   SSH_KEY
#       Used to reach each partner. Written by ssh_setup.sh.
#
#   HOST*  — partner hostnames, resolved to Tailscale IPs at runtime
#
# Cache output: /tmp/vv_cache/arrs_remote_<hostid>.json
#   tmpfs, cleared on reboot. Regenerable by definition — losing it costs one slow page
#   load, never correctness, which is why nothing here retries hard on failure.
#
# No arr credentials are read locally. Each partner uses its own SONARR_*/RADARR_*/LIDARR_*
# values on its own side, so this host never holds keys for a remote's arrs.
#
# ==============================================================================================
# RUNTIME MODES
# ==============================================================================================
#
#   remote_arr_cache_writer.sh               — refresh all remote hosts
#   remote_arr_cache_writer.sh --host=HOST2  — refresh one host only
#   remote_arr_cache_writer.sh --dry-run     — show what would happen
#   remote_arr_cache_writer.sh --log         — verbose output
#
# ==============================================================================================

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

parse_args "$@"

# Reads $SSH_KEY from /root/.ssh to reach partner hosts.
[[ "$EUID" -ne 0 ]] && { error "Must be run as root"; exit 1; }

acquire_lock
detect_hosts

# Parse --host= from raw args
TARGET_HOST=""
for arg in "$@"; do
    case "$arg" in --host=*) TARGET_HOST="${arg#--host=}" ;; esac
done

mkdir -p "$VV_CACHE_DIR"

log "$ICON_GEAR Config: target=${TARGET_HOST:-all hosts} ssh-key=${SSH_KEY}"

FETCH_OK=0
FETCH_FAIL=0
FETCH_SKIP=0

echo ""
echo "━━━ $ICON_SYNC Remote Arr Cache Writer ━━━"
[[ "$DRY_RUN" == true ]] && warn "DRY RUN — no changes will be made"
[[ -n "$TARGET_HOST" ]] && echo "  Target: $TARGET_HOST"
echo ""

for host_var in HOST1 HOST2 HOST3 HOST4 HOST5 HOST6 HOST7 HOST8; do
    [[ "$host_var" == "$MY_ID" ]] && continue

    hostname="${!host_var:-}"
    [[ -z "$hostname" ]] && continue

    # If targeting a specific host, skip others
    if [[ -n "$TARGET_HOST" ]]; then
        [[ "${host_var,,}" != "${TARGET_HOST,,}" && "$host_var" != "$TARGET_HOST" ]] && continue
    fi

    host_id="${host_var,,}"   # host1, host2, …
    cache_file="$VV_CACHE_DIR/arrs_remote_${host_id}.json"

    echo "  $host_var ($hostname)…"

    if [[ "$DRY_RUN" == true ]]; then
        warn "  DRY RUN — would SSH to $hostname and cache arr data"
        (( FETCH_SKIP++ ))
        continue
    fi

    # Resolve Tailscale IP
    REMOTE_IP=$(resolve_tailscale_ip "$hostname")
    if [[ -z "$REMOTE_IP" ]]; then
        warn "  $host_var: cannot resolve Tailscale IP for $hostname — skipping"
        (( FETCH_FAIL++ ))
        continue
    fi
    log "  $host_var: resolved $hostname → $REMOTE_IP"

    # Single SSH connection — fetch arrs + monitor stats together
    RESULT=$(ssh -i "$SSH_KEY" \
        -o ConnectTimeout=10 \
        -o StrictHostKeyChecking=no \
        -o BatchMode=yes \
        "root@${REMOTE_IP}" \
        "php -r \"
            require_once '/usr/local/emhttp/plugins/varaverk/include/arrs.php';
            require_once '/usr/local/emhttp/plugins/varaverk/include/unraid_api.php';
            echo json_encode([
                'arrs'    => vv_arrs_local_node(),
                'monitor' => vv_local_host_stats(),
            ]);
        \"" 2>/dev/null)

    if [[ -z "$RESULT" ]]; then
        warn "  $host_var: empty SSH response — skipping"
        (( FETCH_FAIL++ ))
        continue
    fi

    # Validate combined JSON
    if ! echo "$RESULT" | php -r "
        \$d = json_decode(file_get_contents('php://stdin'), true);
        exit(!is_array(\$d) || !isset(\$d['arrs'], \$d['monitor']) ? 1 : 0);
    " 2>/dev/null; then
        warn "  $host_var: invalid JSON — skipping"
        log "  Response: ${RESULT:0:200}"
        (( FETCH_FAIL++ ))
        continue
    fi

    # Save arr cache
    echo "$RESULT" | php -r "
        \$d = json_decode(file_get_contents('php://stdin'), true);
        file_put_contents('$cache_file', json_encode(\$d['arrs']));
    " 2>/dev/null

    # Save monitor cache
    MONITOR_CACHE="$VV_CACHE_DIR/monitor_remote_${host_id}.json"
    echo "$RESULT" | php -r "
        \$d = json_decode(file_get_contents('php://stdin'), true);
        file_put_contents('$MONITOR_CACHE', json_encode(\$d['monitor']));
    " 2>/dev/null

    CACHED_TYPES=$(echo "$RESULT" | php -r "
        \$d = json_decode(file_get_contents('php://stdin'), true);
        echo implode(', ', array_column(\$d['arrs']['arrs'] ?? [], 'type'));
    " 2>/dev/null)
    echo "  $host_var: arrs [${CACHED_TYPES:-none}] + monitor stats cached ✅"
    (( FETCH_OK++ ))
done

echo ""
echo "━━━━━ $ICON_SUMMARY Cache Writer Summary ━━━━━"
echo "  $FETCH_OK updated · $FETCH_FAIL failed · $FETCH_SKIP skipped"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

[[ "$FETCH_FAIL" -gt 0 ]] && exit 1
exit 0
