#!/usr/bin/env bash
# snapshot-all.sh — Snapshot or revert all game VMs at once.
#
# Usage:
#   bash tools/vm/snapshot-all.sh --snapshot <name>         Create named snapshot on all VMs
#   bash tools/vm/snapshot-all.sh --revert-to <name>        Revert all VMs to named snapshot
#   bash tools/vm/snapshot-all.sh --list                    List all snapshots per VM
#   bash tools/vm/snapshot-all.sh --dry-run --revert-to ... Dry run (no state changes)
#
# SAFETY:
#   - Only operates on sc- prefixed domains.
#   - Always prints a summary before modifying state.
#   - --revert-to requires explicit confirmation (skipped with --yes flag).
#   - This script is for developer use only. It is NOT available in-game.
#
# AGENT RULES:
#   - Never run --revert-to without explicit user instruction.
#   - Never run against domains that don't start with sc-.

set -euo pipefail

VMS=("sc-workstation" "sc-web-server" "sc-build-machine")
DRY_RUN=false
ASSUME_YES=false
SNAPSHOT_NAME=""
REVERT_NAME=""
LIST_MODE=false

# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        --snapshot)    SNAPSHOT_NAME="$2"; shift 2 ;;
        --revert-to)   REVERT_NAME="$2";   shift 2 ;;
        --list)        LIST_MODE=true;      shift ;;
        --dry-run)     DRY_RUN=true;        shift ;;
        --yes)         ASSUME_YES=true;     shift ;;
        *) echo "Unknown argument: $1"; exit 1 ;;
    esac
done

run() {
    if [ "$DRY_RUN" = "true" ]; then
        echo "  [DRY-RUN] $*"
    else
        "$@"
    fi
}

guard_prefix() {
    local dom="$1"
    if [[ "$dom" != sc-* ]]; then
        echo "SAFETY: refusing to operate on non-game domain: $dom"
        exit 1
    fi
}

# ---------------------------------------------------------------------------

if [ "$LIST_MODE" = "true" ]; then
    echo ""
    echo "── Snapshots per VM ─────────────────────────────"
    for dom in "${VMS[@]}"; do
        echo ""
        echo "  $dom:"
        if virsh dominfo "$dom" &>/dev/null 2>&1; then
            virsh snapshot-list "$dom" --name 2>/dev/null | sed 's/^/    /' || echo "    (none)"
        else
            echo "    (domain does not exist)"
        fi
    done
    echo ""
    exit 0
fi

# ---------------------------------------------------------------------------
# SNAPSHOT
# ---------------------------------------------------------------------------

if [ -n "$SNAPSHOT_NAME" ]; then
    echo ""
    echo "Creating snapshot '$SNAPSHOT_NAME' on all game VMs..."
    [ "$DRY_RUN" = "true" ] && echo "[DRY-RUN mode]"
    echo ""
    for dom in "${VMS[@]}"; do
        guard_prefix "$dom"
        if virsh dominfo "$dom" &>/dev/null 2>&1; then
            echo "  Snapshotting $dom..."
            run virsh snapshot-create-as "$dom" "$SNAPSHOT_NAME" \
                --description "Created by snapshot-all.sh" \
                --atomic
            echo "  ✓ $dom → $SNAPSHOT_NAME"
        else
            echo "  ⚠ $dom not found — skipping"
        fi
    done
    echo ""
    echo "Done."
    exit 0
fi

# ---------------------------------------------------------------------------
# REVERT
# ---------------------------------------------------------------------------

if [ -n "$REVERT_NAME" ]; then
    echo ""
    echo "══════════════════════════════════════════════════"
    echo "  REVERT ALL VMs TO: $REVERT_NAME"
    echo "══════════════════════════════════════════════════"
    echo "  VMs: ${VMS[*]}"
    echo "  This will DISCARD all unsaved VM state."
    [ "$DRY_RUN" = "true" ] && echo "  [DRY-RUN mode — no changes will be made]"
    echo ""

    if [ "$ASSUME_YES" = "false" ] && [ "$DRY_RUN" = "false" ]; then
        read -rp "  Type YES to confirm revert: " confirm
        if [ "$confirm" != "YES" ]; then
            echo "  Aborted."
            exit 0
        fi
    fi

    for dom in "${VMS[@]}"; do
        guard_prefix "$dom"
        if virsh dominfo "$dom" &>/dev/null 2>&1; then
            echo "  Reverting $dom..."
            # Stop VM first if running
            if virsh domstate "$dom" 2>/dev/null | grep -q "running"; then
                run virsh destroy "$dom"
            fi
            run virsh snapshot-revert "$dom" "$REVERT_NAME" --running
            echo "  ✓ $dom → $REVERT_NAME"
        else
            echo "  ⚠ $dom not found — skipping"
        fi
    done
    echo ""
    echo "Revert complete."
    exit 0
fi

# No mode selected
echo "Usage:"
echo "  bash snapshot-all.sh --snapshot <name>"
echo "  bash snapshot-all.sh --revert-to <name>"
echo "  bash snapshot-all.sh --list"
echo "  Add --dry-run to preview without changes."
exit 1
