#!/usr/bin/env bash
set -u

# =====================================================
# recover_batocera_saves.sh
# Author: pacmaN (altbox.de)
# Release date: 2026-01-22
#
# This script restores a previously created Batocera
# backup snapshot to a running Batocera system via SSH.
#
# What this script does:
# - Lists all available backup snapshots interactively
# - Shows snapshot size and file count
# - Lets the user choose which snapshot to restore
# - Fully restores:
#     * /userdata (savegames, memory cards, savestates)
#     * batocera.conf (system configuration)
#     * PCSX2 configuration files
# - Always overwrites existing files
# - Reboots Batocera automatically after restore
#
# Intended usage:
# - Private home networks
# - Batocera reachable via SSH
# - No game running during restore
#
# WARNING:
# This operation is destructive and replaces the
# current Batocera state completely.
# =====================================================

BATOCERA_HOST="batocera.local"
BATOCERA_USER="root"
BATOCERA_PASS="YOUR_PASSWORD_HERE"
BATOCERA_PORT="22"

BASE_DIR="$HOME/batocera"
BACKUPS_DIR="$BASE_DIR/backups"

SSH_OPTS=(
  -p "$BATOCERA_PORT"
  -o "ConnectTimeout=30"
  -o "StrictHostKeyChecking=accept-new"
)

die() { echo "ERROR: $*" >&2; exit 1; }
need() { command -v "$1" >/dev/null 2>&1 || die "Missing dependency: $1"; }

need ssh
need rsync
need sshpass
need find
need wc
need du
need awk
need sort
need sed

ssh_run() {
  sshpass -p "$BATOCERA_PASS" ssh "${SSH_OPTS[@]}" \
    "${BATOCERA_USER}@${BATOCERA_HOST}" "$@"
}

echo "=== Batocera Restore ==="
echo "Backups directory: $BACKUPS_DIR"
echo "Target system    : ${BATOCERA_USER}@${BATOCERA_HOST}:${BATOCERA_PORT}"
echo

[[ -d "$BACKUPS_DIR" ]] || die "Backup directory not found: $BACKUPS_DIR"
ssh_run "true" >/dev/null 2>&1 || die "Unable to connect to Batocera via SSH."

SNAPS="$(find "$BACKUPS_DIR" -mindepth 1 -maxdepth 1 -type d -printf "%f\n" | sort -r)"
[[ -n "$SNAPS" ]] || die "No backup snapshots found."

echo "Available snapshots:"
i=1
echo "$SNAPS" | while read -r bn; do
  s="$BACKUPS_DIR/$bn"
  size="$(du -sh "$s" | awk '{print $1}')"
  files="$(find "$s" -type f | wc -l | tr -d ' ')"
  echo "  [$i] $bn | Size: $size | Files: $files"
  i=$((i+1))
done
echo

read -r -p "Select snapshot number to restore: " CHOICE
[[ "$CHOICE" =~ ^[0-9]+$ ]] || die "Invalid input."
SNAP_BN="$(echo "$SNAPS" | sed -n "${CHOICE}p")"
[[ -n "$SNAP_BN" ]] || die "Invalid selection."

SNAP="$BACKUPS_DIR/$SNAP_BN"

echo
echo "Selected snapshot: $SNAP_BN"
echo "This will OVERWRITE existing files."
echo "Batocera will reboot automatically after restore."
echo

read -r -p "Type 'YES' to continue: " OK
[[ "$OK" == "YES" ]] || die "Aborted by user."

RSYNC_BASE=( -aH --numeric-ids --ignore-times --info=progress2 )
RSYNC_SSH=( -e "sshpass -p '$BATOCERA_PASS' ssh ${SSH_OPTS[*]}" )

if [[ -d "$SNAP/userdata" ]]; then
  echo
  echo "Restoring userdata/ -> /userdata/"
  rsync "${RSYNC_BASE[@]}" "${RSYNC_SSH[@]}" \
    "$SNAP/userdata/" \
    "${BATOCERA_USER}@${BATOCERA_HOST}:/userdata/"
fi

if [[ -f "$SNAP/batocera.conf" ]]; then
  echo
  echo "Restoring batocera.conf -> /userdata/system/batocera.conf"
  rsync "${RSYNC_BASE[@]}" "${RSYNC_SSH[@]}" \
    "$SNAP/batocera.conf" \
    "${BATOCERA_USER}@${BATOCERA_HOST}:/userdata/system/batocera.conf"
fi

if [[ -d "$SNAP/pcsx2_configs" ]]; then
  echo
  echo "Restoring PCSX2 configs -> /userdata/system/configs/PCSX2/"
  ssh_run "mkdir -p /userdata/system/configs/PCSX2"
  rsync "${RSYNC_BASE[@]}" "${RSYNC_SSH[@]}" \
    "$SNAP/pcsx2_configs/" \
    "${BATOCERA_USER}@${BATOCERA_HOST}:/userdata/system/configs/PCSX2/"
fi

echo
echo "Restore completed successfully."
echo "Rebooting Batocera in 10 seconds..."

sleep 10
ssh_run "reboot" || true
