#!/bin/bash
# ==============================================================================================
# ============================= Transcode Management ===========================================
# ==============================================================================================
# Orchestrator — runs transcode_cleanup.sh then transcode_manager.sh in the correct order.
# Replace individual transcode_manager and transcode_cleanup cron entries with this.
# Schedule: */7 * * * * (every 7 minutes via User Scripts plugin)
#
# ── WHY CLEANUP BEFORE MANAGER ────────────────────────────────────────────────────────────────
# Cleanup runs first — removes stale segment files from ended sessions.
# Manager runs after — threshold decisions based on real current usage post-cleanup.
# Without this order, stale files inflate the ramdisk usage reading and trigger
# unnecessary SSD flips even when active sessions would fit on the ramdisk.
#
# ── WHAT EACH SCRIPT DOES ─────────────────────────────────────────────────────────────────────
#   transcode_cleanup.sh  — removes aged segment files not open by any process
#                           uses lsof for O(1) per-file active check (never per-file lsof)
#                           also triggers flip-back to ramdisk after cleanup if recovered ✅
#
#   transcode_manager.sh  — checks ramdisk usage against thresholds
#                           flips symlink between ramdisk and SSD as needed
#                           writes one entry to TRANSCODE_DAILY_LOG after each run
#                           shows active Emby sessions with play method
#
# ── DAILY LOG ─────────────────────────────────────────────────────────────────────────────────
# transcode_manager.sh writes to TRANSCODE_DAILY_LOG after each run:
#   Format: DATE|RAMDISK_USED_GB|FLIP_COUNT|RAM_SESSIONS|SSD_SESSIONS
# This orchestrator does NOT write its own log — manager handles it ✅
# Log trimmed to TRANSCODE_LOG_RETENTION days by manager on each write.
# Read by sunday_morning_coffee_report.sh and weekly_health_digest.sh.
#
# ── HOST AWARENESS ────────────────────────────────────────────────────────────────────────────
# detect_hosts() sets MY_ID and aliases RAMDISK_PATH, TRANSCODE_SSD, RAMDISK_WARN_GB etc.
# Each server manages its own transcode location independently.
#
# ── SAFEGUARDS ────────────────────────────────────────────────────────────────────────────────
#   Root check      — mount and docker operations require root
#   acquire_lock    — prevents concurrent 3-minute cycles overlapping
#   detect_hosts()  — correct paths per host
#   --dry-run       — passed through to both child scripts
#   Exit code       — worst exit code of both scripts returned
#
# ── CONFIGURATION (master.conf) ───────────────────────────────────────────────────────────────
#   TRANSCODE_DAILY_LOG    — daily stats log (written by transcode_manager.sh)
#   TRANSCODE_LOG_RETENTION — days to keep (trimmed by manager)
#   TRANSCODE_STATE_FILE   — current state (ramdisk_used, flip_count etc.)
#   All TRANSCODE_* threshold vars — see master.conf Transcode Manager section
#
# ── USAGE ─────────────────────────────────────────────────────────────────────────────────────
#   transcode_management.sh              — normal run (every 7 minutes via cron)
#   transcode_management.sh --dry-run    — preview without changes (passed to children)
#   transcode_management.sh --status     — show configuration and current state
#   transcode_management.sh --log        — verbose output from both child scripts
# ==============================================================================================

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

source "$SCRIPT_DIR/../load_config.sh"

parse_args "$@"

CLEANUP_SCRIPT="$SCRIPT_DIR/../Transcodes/transcode_cleanup.sh"
MANAGER_SCRIPT="$SCRIPT_DIR/../Transcodes/transcode_manager.sh"

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

acquire_lock "wait"

if ! command -v docker &>/dev/null; then
    error "Docker command not found"
    exit 1
fi

# detect_hosts() sets MY_ID and aliases all HOST*_TRANSCODE_* vars
detect_hosts

[[ "$DRY_RUN" == true ]] && warn "DRY RUN — passing through to child scripts"

# ==============================================================================================
# ━━━ Status ━━━
# ==============================================================================================
if [[ "$SHOW_STATUS" == true ]]; then
    echo ""
    echo "━━━━━ $ICON_SUMMARY TRANSCODE MANAGEMENT STATUS ━━━━━"
    echo "$ICON_HOST   Identity:       $MY_ID ($LOCAL_SERVER_NAME)"
    echo "$ICON_RAM    Ramdisk:        $RAMDISK_PATH ($RAMDISK_SIZE)"
    echo "$ICON_DISK   SSD fallback:   $TRANSCODE_SSD"
    echo "$ICON_LINK   Symlink:        $TRANSCODE_LINK"
    echo "$ICON_TIME   Schedule:       every 7 minutes"
    echo ""
    echo "━━━ Child Scripts ━━━"
    [[ -f "$CLEANUP_SCRIPT" ]] && \
        echo "  $ICON_SUCCESS transcode_cleanup.sh — found" || \
        echo "  $ICON_ERROR  transcode_cleanup.sh — NOT FOUND at $CLEANUP_SCRIPT"
    [[ -f "$MANAGER_SCRIPT" ]] && \
        echo "  $ICON_SUCCESS transcode_manager.sh — found" || \
        echo "  $ICON_ERROR  transcode_manager.sh — NOT FOUND at $MANAGER_SCRIPT"
    echo ""
    echo "━━━ Daily Log ━━━"
    if [[ -f "${TRANSCODE_DAILY_LOG:-}" ]] && [[ -s "$TRANSCODE_DAILY_LOG" ]]; then
        ENTRY_COUNT=$(wc -l < "$TRANSCODE_DAILY_LOG")
        OLDEST=$(awk -F'|' 'NR==1{print $1}' "$TRANSCODE_DAILY_LOG")
        NEWEST=$(awk -F'|' 'END{print $1}' "$TRANSCODE_DAILY_LOG")
        echo "  $ICON_SUCCESS $TRANSCODE_DAILY_LOG ($ENTRY_COUNT entries, $OLDEST → $NEWEST)"
    else
        echo "  $ICON_SKIP $TRANSCODE_DAILY_LOG — no data yet"
    fi
    echo ""
    echo "━━━ Current State ━━━"
    if [[ -f "${TRANSCODE_STATE_FILE:-/tmp/transcode_state.db}" ]]; then
        while IFS='=' read -r key val; do
            [[ -n "$key" ]] && echo "  $key = $val"
        done < "${TRANSCODE_STATE_FILE:-/tmp/transcode_state.db}"
    else
        echo "  State file not found (ramdisk_setup.sh creates it at array start)"
    fi
    echo "━━━━━━━━━━━━━━━━━━━━━━━"
    exit 0
fi

# ==============================================================================================
# ━━━ Validate Child Scripts ━━━
# ==============================================================================================
if [[ ! -f "$CLEANUP_SCRIPT" ]]; then
    error "transcode_cleanup.sh not found: $CLEANUP_SCRIPT"
    exit 1
fi

if [[ ! -f "$MANAGER_SCRIPT" ]]; then
    error "transcode_manager.sh not found: $MANAGER_SCRIPT"
    exit 1
fi

# ==============================================================================================
# ━━━ Pre-run State Snapshot ━━━
# ==============================================================================================
if mountpoint -q "${RAMDISK_PATH:-}" 2>/dev/null; then
    _rd_used=$(df "$RAMDISK_PATH" --output=used  2>/dev/null | tail -1 | tr -d ' ')
    _rd_avail=$(df "$RAMDISK_PATH" --output=avail 2>/dev/null | tail -1 | tr -d ' ')
    _rd_used_gb=$(awk "BEGIN {printf \"%.2f\", ${_rd_used:-0}/1048576}")
    _rd_avail_gb=$(awk "BEGIN {printf \"%.2f\", ${_rd_avail:-0}/1048576}")
    _rd_target=$(readlink "${TRANSCODE_LINK:-}" 2>/dev/null || echo "unknown")
    log "$ICON_RAM Ramdisk: ${_rd_used_gb}GB used / ${_rd_avail_gb}GB avail — symlink → ${_rd_target##*/}"
else
    log "$ICON_RAM Ramdisk: not mounted"
fi

# ==============================================================================================
# ━━━ Run Cleanup ━━━
# ==============================================================================================
DRY_FLAG=""
[[ "$DRY_RUN" == true ]] && DRY_FLAG="--dry-run"

_cleanup_start=$(date +%s)
bash "$CLEANUP_SCRIPT" $DRY_FLAG
CLEANUP_EXIT=$?
log "cleanup: $(format_duration $(( $(date +%s) - _cleanup_start ))) (exit $CLEANUP_EXIT)"

# ==============================================================================================
# ━━━ Run Manager ━━━
# ==============================================================================================
# transcode_manager.sh writes to TRANSCODE_DAILY_LOG after each run
# No --no-log flag here — manager owns the log write for this cycle ✅
_manager_start=$(date +%s)
bash "$MANAGER_SCRIPT" $DRY_FLAG
MANAGER_EXIT=$?
log "manager: $(format_duration $(( $(date +%s) - _manager_start ))) (exit $MANAGER_EXIT)"

# ==============================================================================================
# ━━━ Exit ━━━
# ==============================================================================================
# Return worst exit code — caller knows if either script failed
[[ "$CLEANUP_EXIT" -ne 0 || "$MANAGER_EXIT" -ne 0 ]] && exit 1
exit 0