#!/bin/bash
# services/gaming-backup.sh — Frequent gaming-saves backup (no service downtime).
# Part of the modular post-install system (sourced by setup.sh).
#
# Can also be run standalone on any machine:
#   sudo bash gaming-backup.sh
# (Docker must already be installed when run standalone)
#
# Backs up the things you can't re-download — progress, saved games, user data:
#   • Minecraft worlds / player data  (every <id>/data instance under $DOCKER_DIR)
#   • Emulator saves & save states    ($GAME_STORAGE_DIR/saves)      [gaming box]
#   • Emulator BIOS / firmware        ($GAME_STORAGE_DIR/bios)       [gaming box]
#   • RetroArch shaders & overlays    ($GAME_STORAGE_DIR/retroarch)  [gaming box]
#   • ES-DE scraped artwork           ($GAME_STORAGE_DIR/media)      [gaming box]
#   • Steam user data & game saves    ($GAME_STORAGE_DIR/steam)      [gaming box]
#   • Wolf state                      (/etc/wolf — config + profile_data) [gaming box]
#
# Unlike the 'backup' service, nothing is stopped — Minecraft worlds are flushed
# to disk (save-all) and snapshotted live. Run this hourly or every few hours for
# frequent save protection; use 'backup' nightly for full service recovery.
#
# It does NOT back up ROMs or Steam game installs — those are re-downloadable.
#
# Safe to re-run: it reconnects to an existing repository and refreshes the
# config, policies, worker script and timer.

# ── Standalone bootstrap ──────────────────────────────────────────────────────
# Detected when the script is executed directly rather than sourced by setup.sh.
# Sets up helpers and globals, then defers execution until after the function
# definition at the bottom of this file.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    [[ "$(id -u)" == "0" ]] || { echo "Run with sudo: sudo bash $0"; exit 1; }

    _SELF_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    _COMMON="$_SELF_DIR/../lib/common.sh"

    if [[ -f "$_COMMON" ]]; then
        # Full repo present — use the real helpers (picks up ~/docker/.config too)
        # shellcheck source=../lib/common.sh
        source "$_COMMON"
    else
        # One-off copy — inline minimal stubs so the script works without the repo
        log_info()    { echo -e "\033[0;34m[INFO]\033[0m $*"; }
        log_success() { echo -e "\033[0;32m[OK]\033[0m $*"; }
        log_warning() { echo -e "\033[1;33m[WARN]\033[0m $*"; }
        log_error()   { echo -e "\033[0;31m[ERROR]\033[0m $*" >&2; }

        ensure_docker_dir_ownership() {
            chown -R "$ACTUAL_USER:$ACTUAL_USER" "$@" 2>/dev/null || true
        }

        # Match common.sh's eval-based pattern so local vars in install_* are set correctly
        prompt_text() {
            local _q="$1" _def="$2" _var="$3" _r
            [[ "${UNATTENDED:-false}" == "true" ]] && { eval "$_var='$_def'"; return; }
            read -r -p "  $_q " _r
            eval "$_var='${_r:-$_def}'"
        }

        prompt_yn() {
            local _q="$1" _def="$2" _var="$3" _r
            [[ "${UNATTENDED:-false}" == "true" ]] && { eval "$_var='$_def'"; return; }
            read -r -p "  $_q " _r
            eval "$_var='${_r:-$_def}'"
        }

        generate_password() {
            local _len="${1:-32}"
            tr -dc 'A-Za-z0-9' < /dev/urandom | head -c "$_len"
        }
    fi

    # Globals — ACTUAL_USER/ACTUAL_HOME must come before DOCKER_DIR
    # ($HOME under sudo is /root, not the real user's home)
    ACTUAL_USER="${ACTUAL_USER:-${SUDO_USER:-$USER}}"
    ACTUAL_HOME="$(getent passwd "$ACTUAL_USER" 2>/dev/null | cut -d: -f6 || echo "${HOME:-/root}")"
    DOCKER_DIR="${DOCKER_DIR:-$ACTUAL_HOME/docker}"
    DRY_RUN="${DRY_RUN:-false}"
    UNATTENDED="${UNATTENDED:-false}"
    SITE_TZ="${SITE_TZ:-$(cat /etc/timezone 2>/dev/null || echo UTC)}"
    SITE_DOMAIN="${SITE_DOMAIN:-example.com}"
    SITE_CADDY_NET="${SITE_CADDY_NET:-caddy_net}"
    CADDY_REMOTE_HOST="${CADDY_REMOTE_HOST:-}"

    register_service() { :; }   # no-op — no wizard to register into
    _RUN_STANDALONE=1
fi
# ─────────────────────────────────────────────────────────────────────────────

register_service gaming-backup backup "Gaming saves backup (Minecraft worlds, emulator saves, Steam)"

install_gaming-backup() {
    log_info "Setting up gaming saves backup (Kopia)..."

    # ── Repo-conventional paths ──────────────────────────────────────────────
    local BACKUP_DIR="$DOCKER_DIR/gaming-backup"
    local CONF_FILE="$BACKUP_DIR/backup.conf"        # editable settings
    local WORKER="$BACKUP_DIR/backup_gaming.sh"        # worker script
    local KOPIA_CONFIG="/etc/gaming-backup/repository.config"
    local CACHE_DIR="/var/cache/gaming-backup"
    local SVC_NAME="post-install-gaming-backup"
    local DEFAULT_REPO="$ACTUAL_HOME/backups/gaming-kopia"

    echo ""
    echo "╔═══════════════════════════════════════════════════════╗"
    echo "║   Gaming Backup Setup  ·  Kopia                       ║"
    echo "║   Minecraft worlds · game saves · user data           ║"
    echo "╚═══════════════════════════════════════════════════════╝"
    echo ""
    echo "  Backs up progress / saves / user data — NOT ROMs or game installs."
    echo "  Nothing is stopped: Minecraft worlds are flushed to disk then snapshotted."
    echo "  Run frequently (hourly or every few hours) without disrupting gameplay."
    echo "  Use the 'backup' service for full service recovery (nightly)."
    echo ""

    # ── DRY-RUN ──────────────────────────────────────────────────────────────
    if [ "$DRY_RUN" = true ]; then
        echo "[DRY-RUN] Would install Kopia from the official apt repository"
        echo "[DRY-RUN] Would create $BACKUP_DIR (owned by $ACTUAL_USER)"
        echo "[DRY-RUN] Would create/connect a Kopia repository at $DEFAULT_REPO"
        echo "[DRY-RUN] Would write config $CONF_FILE and worker $WORKER"
        echo "[DRY-RUN] Would install systemd service+timer $SVC_NAME (cron fallback)"
        echo "[DRY-RUN] Would optionally run the first backup"
        return 0
    fi

    # ── 1. Ensure Kopia is installed ─────────────────────────────────────────
    if ! command -v kopia >/dev/null 2>&1; then
        log_info "Kopia not found — installing from the official apt repository..."
        if command -v apt-get >/dev/null 2>&1; then
            install -d -m 0755 /etc/apt/keyrings
            if curl -fsSL https://kopia.io/signing-key \
                | gpg --dearmor --yes -o /etc/apt/keyrings/kopia-keyring.gpg; then
                echo "deb [signed-by=/etc/apt/keyrings/kopia-keyring.gpg] http://packages.kopia.io/apt/ stable main" \
                    > /etc/apt/sources.list.d/kopia.list
                apt-get update -y && apt-get install -y kopia
            fi
        fi
    fi
    if ! command -v kopia >/dev/null 2>&1; then
        log_error "Kopia is still not installed."
        echo "  Install it manually, then re-run this service:"
        echo "    https://kopia.io/docs/installation/"
        return 1
    fi
    local KOPIA_BIN; KOPIA_BIN="$(command -v kopia)"
    log_success "Kopia: $("$KOPIA_BIN" --version 2>/dev/null | head -1)"

    mkdir -p "$BACKUP_DIR" || return 1
    ensure_docker_dir_ownership "$BACKUP_DIR"

    # ── 2. What to back up ───────────────────────────────────────────────────
    echo ""
    echo "═══════════════════════════════════════════════════════"
    echo "  WHAT TO BACK UP"
    echo "═══════════════════════════════════════════════════════"
    echo ""

    local DEFAULT_MCBASE="$DOCKER_DIR"
    echo "  Each Minecraft instance's world is backed up from its <id>/data folder;"
    echo "  all instances under this folder are detected automatically."
    echo "  (type 'none' to exclude Minecraft)"
    local MC_BASE_DIR=""
    prompt_text "  Folder containing Minecraft instance(s) [${DEFAULT_MCBASE}]:" "$DEFAULT_MCBASE" MC_BASE_DIR
    if [ "$MC_BASE_DIR" = none ]; then
        MC_BASE_DIR=""
    else
        MC_BASE_DIR="${MC_BASE_DIR/#\~/$ACTUAL_HOME}"; MC_BASE_DIR="${MC_BASE_DIR%/}"
        local _found=() d
        for d in "$MC_BASE_DIR"/*/; do
            [ -f "${d}Dockerfile" ] && grep -qs itzg "${d}Dockerfile" && [ -d "${d}data" ] \
                && _found+=("$(basename "$d")")
        done
        if [ "${#_found[@]}" -gt 0 ]; then
            log_success "  Detected Minecraft instance(s): ${_found[*]}"
        else
            log_warning "  No instances detected yet under $MC_BASE_DIR — picked up once created."
        fi
    fi

    # ── Optional gaming-box sources ──────────────────────────────────────────
    echo ""
    echo "  The following are only relevant on a gaming box (Wolf + emulators +"
    echo "  Steam). On a plain homelab server you can leave them disabled."
    local DEFAULT_STORAGE="$ACTUAL_HOME/drives/games"
    local GAME_STORAGE_DIR=""
    prompt_text "  Game storage dir (ROMs/Steam/saves live here) [${DEFAULT_STORAGE}]:" "$DEFAULT_STORAGE" GAME_STORAGE_DIR
    GAME_STORAGE_DIR="${GAME_STORAGE_DIR/#\~/$ACTUAL_HOME}"
    GAME_STORAGE_DIR="${GAME_STORAGE_DIR%/}"

    echo ""
    local _a=""
    prompt_yn "  Back up emulator saves ($GAME_STORAGE_DIR/saves)? (y/N):" "n" _a
    local BACKUP_SAVES; BACKUP_SAVES=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    prompt_yn "  Back up emulator BIOS/firmware ($GAME_STORAGE_DIR/bios)? (y/N):" "n" _a
    local BACKUP_BIOS; BACKUP_BIOS=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    prompt_yn "  Back up RetroArch shaders & overlays ($GAME_STORAGE_DIR/retroarch)? (y/N):" "n" _a
    local BACKUP_RA_SHADERS; BACKUP_RA_SHADERS=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    prompt_yn "  Back up Steam user data/saves (game installs excluded)? (y/N):" "n" _a
    local BACKUP_STEAM; BACKUP_STEAM=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    prompt_yn "  Back up ES-DE scraped artwork ($GAME_STORAGE_DIR/media)? (y/N):" "n" _a
    local BACKUP_MEDIA; BACKUP_MEDIA=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    echo ""
    echo "  /etc/wolf includes pairing/config AND profile_data — where Wolf stores"
    echo "  every app's home dir (ES-DE settings, controller mappings, RetroArch"
    echo "  saves & save states, standalone-emulator saves)."
    prompt_yn "  Back up Wolf state (/etc/wolf)? (y/N):" "n" _a
    local BACKUP_WOLF; BACKUP_WOLF=$([[ "$_a" =~ ^[Yy]$ ]] && echo yes || echo no)
    local WOLF_STATE_DIR="/etc/wolf"

    # ── 3. Repository location ────────────────────────────────────────────────
    echo ""
    echo "═══════════════════════════════════════════════════════"
    echo "  BACKUP REPOSITORY (local)"
    echo "═══════════════════════════════════════════════════════"
    echo ""
    echo "  Backups are stored in a local Kopia repository. You can mirror it to"
    echo "  another computer or the cloud later (see backup.conf, REMOTE_* lines)."
    echo "  Put it on a DIFFERENT drive from your data if you can."
    echo ""
    local REPO_DIR=""
    prompt_text "  Repository path [${DEFAULT_REPO}]:" "$DEFAULT_REPO" REPO_DIR
    REPO_DIR="${REPO_DIR/#\~/$ACTUAL_HOME}"
    REPO_DIR="${REPO_DIR%/}"

    echo ""
    echo "  The repository is encrypted. A strong password is generated and stored"
    echo "  in backup.conf (root-only). KEEP A COPY — without it backups cannot be"
    echo "  restored, even by you."
    echo ""
    local KOPIA_PASSWORD=""
    if [ "$UNATTENDED" = true ]; then
        echo "  [auto] Generating a random repository password."
    else
        read -rsp "  Repository password [Enter = auto-generate]: " KOPIA_PASSWORD; echo
    fi
    if [ -z "$KOPIA_PASSWORD" ]; then
        KOPIA_PASSWORD="$(generate_password 32)"
        log_info "  Generated a random repository password (saved in backup.conf)."
    fi

    # ── 4. Retention + schedule ───────────────────────────────────────────────
    echo ""
    echo "═══════════════════════════════════════════════════════"
    echo "  SCHEDULE & RETENTION"
    echo "═══════════════════════════════════════════════════════"
    echo ""
    echo "    1) Daily at 03:00"
    echo "    2) Every 6 hours"
    echo "    3) Hourly              (recommended for active gaming)"
    echo "    4) Custom (systemd OnCalendar)"
    echo ""
    local _sch=""
    prompt_text "  How often? [3]:" "3" _sch
    local ONCALENDAR SCHED_LABEL
    case "${_sch:-3}" in
        1) ONCALENDAR="*-*-* 03:00:00";          SCHED_LABEL="daily at 03:00" ;;
        2) ONCALENDAR="*-*-* 00,06,12,18:00:00"; SCHED_LABEL="every 6 hours" ;;
        4) prompt_text "  OnCalendar expression:" "hourly" ONCALENDAR; SCHED_LABEL="$ONCALENDAR" ;;
        *) ONCALENDAR="hourly";                  SCHED_LABEL="hourly" ;;
    esac

    echo ""
    local KEEP_LATEST=""
    prompt_text "  How many recent snapshots to keep (latest)? [24]:" "24" KEEP_LATEST
    local KEEP_DAILY=7 KEEP_WEEKLY=4 KEEP_MONTHLY=6

    # ── Notifications (ntfy) ─────────────────────────────────────────────────
    echo ""
    echo "═══════════════════════════════════════════════════════"
    echo "  NOTIFICATIONS (optional)"
    echo "═══════════════════════════════════════════════════════"
    echo ""
    echo "  Receive a push notification after every backup (and on failures)."
    echo "  Uses ntfy — free and self-hostable. Create a topic at https://ntfy.sh"
    echo ""
    local NTFY_URL="" NTFY_TOKEN=""
    prompt_text "  ntfy topic URL (blank to skip):" "" NTFY_URL
    if [ -n "$NTFY_URL" ]; then
        prompt_text "  ntfy access token (blank if public/no auth):" "" NTFY_TOKEN
    fi

    # ── 5. Write backup.conf ──────────────────────────────────────────────────
    log_info "Writing $CONF_FILE ..."
    tee "$CONF_FILE" >/dev/null << CONFEOF
# ── gaming-backup config (read by gaming-backup.sh) ──────────────────────────
# Generated on $(date '+%F %T'). Safe to hand-edit.

KOPIA="$KOPIA_BIN"
KOPIA_CONFIG="$KOPIA_CONFIG"
KOPIA_CACHE_DIR="$CACHE_DIR"
# Repository encryption password — KEEP A COPY somewhere safe.
KOPIA_PASSWORD='$KOPIA_PASSWORD'

# ── Sources (progress / saves / user data only) ──────────────────────────────
# MC_BASE_DIR holds Minecraft instances; every <id>/data with an itzg Dockerfile
# is snapshotted automatically (covers multi-server setups).
MC_BASE_DIR="$MC_BASE_DIR"
GAME_STORAGE_DIR="$GAME_STORAGE_DIR"
WOLF_STATE_DIR="$WOLF_STATE_DIR"
BACKUP_SAVES="$BACKUP_SAVES"   # \$GAME_STORAGE_DIR/saves
BACKUP_BIOS="$BACKUP_BIOS"   # \$GAME_STORAGE_DIR/bios (emulator BIOS/firmware — user-provided)
BACKUP_RA_SHADERS="$BACKUP_RA_SHADERS"   # \$GAME_STORAGE_DIR/retroarch/{shaders,overlays} (cores excluded — re-downloadable)
BACKUP_STEAM="$BACKUP_STEAM"   # \$GAME_STORAGE_DIR/steam (game installs excluded by policy)
BACKUP_MEDIA="$BACKUP_MEDIA"   # \$GAME_STORAGE_DIR/media (ES-DE scraped artwork)
BACKUP_WOLF="$BACKUP_WOLF"     # /etc/wolf — config + profile_data

# ── Optional offsite mirror ──────────────────────────────────────────────────
# Mirror the WHOLE repository to another computer or the cloud after each run.
# Leave REMOTE_TYPE=none to stay local-only.
#
#   SFTP:    REMOTE_TYPE="sftp"  REMOTE_ARGS="--host H --username U --path /srv/..."
#   B2:      REMOTE_TYPE="b2"   REMOTE_ARGS="--bucket B --key-id K --key A"
#   S3:      REMOTE_TYPE="s3"   REMOTE_ARGS="--bucket B --endpoint E --access-key K --secret-access-key S"
#   rclone:  REMOTE_TYPE="rclone"  REMOTE_ARGS="--remote-path myremote:gaming-kopia"
#
REMOTE_TYPE="none"
REMOTE_ARGS=""

# ── Notifications (ntfy) ─────────────────────────────────────────────────────
# Set NTFY_URL to receive backup success/failure alerts.
# Leave blank to disable. NTFY_TOKEN is optional (for private topics).
NTFY_URL="$NTFY_URL"
NTFY_TOKEN="$NTFY_TOKEN"
CONFEOF
    chown root:root "$CONF_FILE" 2>/dev/null || true
    chmod 600 "$CONF_FILE"
    log_success "backup.conf written (chmod 600 — contains the repo password)"

    # ── 6. Create / connect the repository, set policies ─────────────────────
    log_info "Preparing repository at $REPO_DIR ..."
    mkdir -p "$REPO_DIR" "$CACHE_DIR" "$(dirname "$KOPIA_CONFIG")"

    kp() { env KOPIA_PASSWORD="$KOPIA_PASSWORD" "$KOPIA_BIN" --config-file="$KOPIA_CONFIG" "$@"; }

    if kp repository status >/dev/null 2>&1; then
        log_success "Already connected to a repository."
    elif test -e "$REPO_DIR/kopia.repository.f"; then
        log_info "Existing repository found — connecting..."
        kp repository connect filesystem --path="$REPO_DIR" --cache-directory="$CACHE_DIR" \
            || { log_error "Failed to connect to existing repository."; return 1; }
        log_success "Connected to existing repository."
    else
        log_info "Creating new repository..."
        kp repository create filesystem --path="$REPO_DIR" --cache-directory="$CACHE_DIR" \
            || { log_error "Failed to create repository."; return 1; }
        log_success "Repository created."
    fi

    log_info "Applying global policy (zstd compression + retention)..."
    kp policy set --global --compression=zstd >/dev/null
    kp policy set --global \
        --keep-latest="$KEEP_LATEST" \
        --keep-daily="$KEEP_DAILY" \
        --keep-weekly="$KEEP_WEEKLY" \
        --keep-monthly="$KEEP_MONTHLY" \
        --keep-annual=0 --keep-hourly=0 >/dev/null
    log_success "Retention: keep latest $KEEP_LATEST, $KEEP_DAILY daily, $KEEP_WEEKLY weekly, $KEEP_MONTHLY monthly"

    if [ "$BACKUP_STEAM" = yes ]; then
        log_info "Setting Steam ignore rules (excluding game installs, keeping saves)..."
        kp policy set "$GAME_STORAGE_DIR/steam" \
            --add-ignore='**/steamapps/common' \
            --add-ignore='**/steamapps/downloading' \
            --add-ignore='**/steamapps/shadercache' \
            --add-ignore='**/steamapps/temp' \
            --add-ignore='**/steamapps/workshop' \
            --add-ignore='**/depotcache' >/dev/null 2>&1 \
            || log_warning "Could not pre-set Steam ignore policy (applies on first snapshot)."
    fi

    # ── 7. Install the worker script ─────────────────────────────────────────
    log_info "Installing worker $WORKER ..."
    cp "${HERE:-}/extras/backup_gaming.sh" "$WORKER"
    chmod +x "$WORKER"
    chown root:root "$WORKER" 2>/dev/null || true
    log_success "backup_gaming.sh installed"

    # ── Copy the interactive restore script ───────────────────────────────────
    local RESTORE_SRC="${HERE:-}/extras/restore_kopia.sh"
    local RESTORE_DEST="$BACKUP_DIR/restore_gaming.sh"
    if [ -f "$RESTORE_SRC" ]; then
        cp "$RESTORE_SRC" "$RESTORE_DEST"
        chmod +x "$RESTORE_DEST"
        chown root:root "$RESTORE_DEST" 2>/dev/null || true
        log_success "restore_kopia.sh installed"
    else
        log_warning "extras/restore_kopia.sh not found — restore script not installed"
    fi

    # ── Install test script ───────────────────────────────────────────────────
    local TEST_SCRIPT="$BACKUP_DIR/test_backup.sh"
    local TEST_SRC="${HERE:-}/extras/test_backup.sh"
    if [ -f "$TEST_SRC" ]; then
        cp "$TEST_SRC" "$TEST_SCRIPT"
        chmod +x "$TEST_SCRIPT"
        chown root:root "$TEST_SCRIPT" 2>/dev/null || true
        log_success "test_backup.sh installed"
    else
        log_warning "extras/test_backup.sh not found — test script not installed"
    fi

    # ── 8. Install systemd timer (fallback: cron) ────────────────────────────
    local AUTORUN=""
    if command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
        log_info "Installing systemd service + timer ($SCHED_LABEL)..."
        tee "/etc/systemd/system/${SVC_NAME}.service" >/dev/null << UNITEOF
[Unit]
Description=Post-install gaming backup (Minecraft world + game saves via Kopia)
After=docker.service network-online.target
Wants=docker.service

[Service]
Type=oneshot
ExecStart=/bin/bash $WORKER run
UNITEOF

        tee "/etc/systemd/system/${SVC_NAME}.timer" >/dev/null << UNITEOF
[Unit]
Description=Schedule gaming backup ($SCHED_LABEL)

[Timer]
OnCalendar=$ONCALENDAR
Persistent=true
RandomizedDelaySec=300

[Install]
WantedBy=timers.target
UNITEOF

        systemctl daemon-reload
        systemctl enable --now "${SVC_NAME}.timer"
        log_success "Timer enabled: $SCHED_LABEL"
        AUTORUN="systemctl list-timers ${SVC_NAME}.timer"
    else
        log_warning "systemd not detected — installing a cron job instead."
        local CRON
        case "${_sch:-3}" in
            1) CRON="0 3 * * *"          ;;
            2) CRON="0 0,6,12,18 * * *"  ;;
            *) CRON="0 * * * *"          ;;
        esac
        echo "$CRON root /bin/bash $WORKER run >> /var/log/${SVC_NAME}.log 2>&1" \
            > "/etc/cron.d/${SVC_NAME}"
        log_success "Cron job installed: $CRON"
        AUTORUN="cat /etc/cron.d/${SVC_NAME}"
    fi

    # ── 9. First backup now? ─────────────────────────────────────────────────
    echo ""
    local _now=""
    prompt_yn "  Run the first gaming backup now? (Y/n):" "y" _now
    if [[ ! "$_now" =~ ^[Nn]$ ]]; then
        /bin/bash "$WORKER" run || log_warning "First backup reported warnings — check the output above."
    fi

    # ── Summary ──────────────────────────────────────────────────────────────
    echo ""
    echo "═══════════════════════════════════════════════════════"
    echo "  GAMING BACKUP CONFIGURED"
    echo "═══════════════════════════════════════════════════════"
    echo ""
    echo "  Repository : $REPO_DIR  (encrypted, dedup + zstd)"
    echo "  Schedule   : $SCHED_LABEL"
    echo "  Config     : $CONF_FILE"
    echo "  Worker     : $WORKER"
    echo "  Backing up :"
    [ -n "$MC_BASE_DIR" ]        && echo "    • Minecraft worlds     $MC_BASE_DIR/*/data  (all instances)"
    [ "$BACKUP_SAVES" = yes ]    && echo "    • Emulator saves       $GAME_STORAGE_DIR/saves"
    [ "$BACKUP_BIOS"  = yes ]    && echo "    • Emulator BIOS        $GAME_STORAGE_DIR/bios"
    [ "$BACKUP_RA_SHADERS" = yes ] && echo "    • RA shaders/overlays  $GAME_STORAGE_DIR/retroarch/{shaders,overlays}"
    [ "$BACKUP_STEAM" = yes ]    && echo "    • Steam user data      $GAME_STORAGE_DIR/steam  (game installs excluded)"
    [ "$BACKUP_MEDIA" = yes ]    && echo "    • ES-DE scraped art    $GAME_STORAGE_DIR/media"
    [ "$BACKUP_WOLF"  = yes ]    && echo "    • Wolf state           $WOLF_STATE_DIR  (config + profile_data)"
    echo "  NOT backed up: ROMs, Steam game installs (re-downloadable)."
    echo ""
    echo "  Commands:"
    echo "    sudo $WORKER                         back up now"
    echo "    sudo $WORKER snapshots               list snapshots"
    echo "    sudo $RESTORE_DEST                  interactive restore"
    echo "    sudo $RESTORE_DEST --list           list all snapshot sources"
    echo ""
    echo "  Backup test (restore latest, compare, restore-back):"
    echo "    sudo $TEST_SCRIPT                test most recent backup"
    echo "    sudo $TEST_SCRIPT --list         list testable sources"
    echo "    sudo $TEST_SCRIPT <source>       test a specific source"
    [ -n "${NTFY_URL:-}" ] && echo "" && echo "  Notifications: $NTFY_URL"
    echo ""
    echo "    $AUTORUN"
    echo ""
    echo "  Tip: also install the 'backup' service for nightly full-service recovery."
    echo ""
    log_warning "Save your repository password (in backup.conf) somewhere safe —"
    log_warning "without it the encrypted backups cannot be restored."
    echo ""
    log_success "Gaming backup configured."
}

# Run immediately when executed directly (deferred until after function definition)
[[ "${_RUN_STANDALONE:-0}" == 1 ]] && install_gaming-backup
