#!/usr/bin/env bash
# VM operations for Sysadmin Chronicles.
# Source this file; requires lib/libvirt.sh and PROJECT_ROOT set.

SC_VM_TOOLS="${SC_VM_TOOLS:-${PROJECT_ROOT:-}/tools/vm}"

_sc_validate_snapshot_name() {
    [[ "$1" =~ ^[a-zA-Z0-9][a-zA-Z0-9-]*$ ]]
}

_sc_protected_snapshot() {
    [[ "$1" == baseline.* ]] || [[ "$1" == checkpoint.* ]]
}

vm_build() {
    local profile="$1"
    shift
    local dry_run=false force=false
    for arg in "$@"; do
        case "$arg" in
            --dry-run) dry_run=true ;;
            --force)   force=true ;;
        esac
    done
    local script="$SC_VM_TOOLS/build-${profile}.sh"
    [ -f "$script" ] || { echo "  ✗ No build script for profile: $profile"; return 1; }
    local args=()
    [ "$dry_run" = true ] && args+=(--dry-run)
    [ "$force" = true ]   && args+=(--force)
    bash "$script" "${args[@]}"
}

vm_rebuild() {
    local profile="$1"
    shift
    local dry_run=false
    for arg in "$@"; do [ "$arg" = "--dry-run" ] && dry_run=true; done

    local domain="sc-${profile}"
    if domain_exists "$domain" && [ "$dry_run" = false ]; then
        virsh destroy "$domain" >/dev/null 2>&1 || true
        virsh undefine "$domain" --nvram --snapshots-metadata >/dev/null 2>&1 \
            || virsh undefine "$domain" --snapshots-metadata >/dev/null 2>&1 \
            || virsh undefine "$domain" >/dev/null 2>&1 || true
    fi
    local extra_args=()
    [ "$dry_run" = true ] && extra_args+=(--dry-run)
    vm_build "$profile" "${extra_args[@]}"
}

vm_revert() {
    snapshot_revert "$1" "$2"
}

vm_status() {
    local vm_id="$1"
    domain_exists "$vm_id" && domain_state "$vm_id" || printf 'missing'
}

vm_start() {
    virsh start "$1" >/dev/null 2>&1
}

vm_stop() {
    virsh shutdown "$1" >/dev/null 2>&1 || virsh destroy "$1" >/dev/null 2>&1 || true
}

vm_snapshot_create() {
    local vm_id="$1"
    local name="$2"
    _sc_validate_snapshot_name "$name" \
        || { echo "  ✗ Invalid name (letters, numbers, hyphens only): $name"; return 1; }
    snapshot_create "$vm_id" "$name" "User snapshot — $(date '+%Y-%m-%d %H:%M')"
}

vm_snapshot_list() {
    local vm_id="$1"
    virsh snapshot-list "$vm_id" 2>/dev/null || true
}

vm_snapshot_revert() {
    local vm_id="$1"
    local name="$2"
    snapshot_exists "$vm_id" "$name" \
        || { echo "  ✗ Snapshot not found: $name"; return 1; }
    snapshot_revert "$vm_id" "$name"
}

vm_snapshot_delete() {
    local vm_id="$1"
    local name="$2"
    if _sc_protected_snapshot "$name"; then
        echo "  ✗ Cannot delete protected snapshot: $name"
        return 1
    fi
    snapshot_delete "$vm_id" "$name"
}
