#!/bin/bash
# pvmcp - Proxmox VM/LXC Copy Tool (Non-cluster)
# Using zynclib for ZFS replication
VERSION="0.2.0"
set -euo pipefail

TOOL_NAME="pvmcp"
TOOL_LOGNAME="Transfer"

DAEMON_LIB="${DAEMON_LIB:-/usr/lib/pvmzync/daemon_lib}"
source "$DAEMON_LIB" || { echo "ERROR: daemon_lib not found" >&2; exit 1; }
source "$ZYNCLIB"     || { echo "ERROR: zynclib not found" >&2; exit 1; }

show_usage() {
  cat <<EOF
USAGE:
  pvmcp <VMID> <REMOTE_HOST> [OPTIONS]
  pvmcp              # monitor running transfer

DESCRIPTION:
  Copy a VM/LXC between non-clustered Proxmox nodes.
  Uses ZFS send/recv via zynclib for efficient incremental transfers.
  Only one transfer can run at a time.

  For copying arbitrary ZFS datasets, use pdscp(1).

  By default pushes from local to remote. Use --pull to reverse.

CONSTRAINTS:
  - One side must always be the local host.
  - Supports ZFS-backed local disks only (shared storages are skipped).
  - Currently assumes Storage IDs and underlying ZFS pool names are identical
    on both sides (TODO: implement storage mapping).

  No arguments:
    If a transfer is running — monitor it (live log).
    If no transfer is running — show this help.

OPTIONS:
  --pull           Pull from remote instead of push (default: push).
  -f, --force      Override safety checks (e.g., overwrite existing VM).
  --savelogs       Save all logs to pvmcp_logs_<timestamp>.tar.gz.
  -h, --help       Display this help message.

EXAMPLES:
  pvmcp 105 pve-02               # Push VM 105 to pve-02
  pvmcp 105 pve-02 --pull -f     # Pull VM 105 from pve-02, overwrite if exists
  pvmcp                           # Monitor running transfer

SEE ALSO:
  pdscp(1) - Copy arbitrary ZFS datasets
  pvmig(1) - Migrate VMs within a cluster
EOF
}

# --- VM helpers ---

# --- Callbacks for sync_vm_disks ---

disk_pre_sync_cb() {
  if [[ "$vm_state" == "stopped" ]]; then
    ssh_src "zfs snapshot $src_ds@$final_snap"
  fi
}

# --- Argument parsing ---

parse_args() {
  declare -g vmid remote_host vmconf pvectl vm_state FORCE=false

  while [[ $# -gt 0 ]]; do
    case "$1" in
      -h|--help)
        show_usage
        exit 0
        ;;
      --pull)
        direction="pull"
        shift
        ;;
      -f|--force)
        FORCE=true
        shift
        ;;
      --savelogs)
        SAVELOGS=true
        shift
        ;;
      -*)
        error "Unknown option: $1"
        ;;
      *)
        if [[ -z "${vmid:-}" ]]; then
          [[ "$1" =~ ^[0-9]+$ ]] || error "VMID must be numeric. For datasets, use pdscp."
          vmid="$1"
        elif [[ -z "${remote_host:-}" ]]; then
          remote_host="$1"
        else
          error "Unknown argument: $1"
        fi
        shift
        ;;
    esac
  done

  [[ -z "${vmid:-}" ]]        && error "VMID is required"
  [[ -z "${remote_host:-}" ]] && error "REMOTE_HOST is required"
  return 0
}

# --- Main tool logic ---

tool_main() {
  log "=== VM COPY MODE ==="
  log "VM: $vmid | Direction: $direction | Target: $remote_host"

  vmconf=$(ssh_src "ls /etc/pve/qemu-server/${vmid}.conf /etc/pve/lxc/${vmid}.conf 2>/dev/null" || true)
  [[ -z "$vmconf" ]] && error "VM $vmid not found on $src_host"

  pvectl=qm; [[ "$vmconf" =~ /lxc/ ]] && pvectl=pct

  # TODO: Implement advanced storage mapping.
  # Currently assuming Storage IDs and underlying ZFS pools are identical on both sides.
  parse_storage "" < <(ssh_src "cat /etc/pve/storage.cfg")
  parse_vmconf < <(ssh_src "cat $vmconf")

  if ssh_src "$pvectl status $vmid" | grep -q running; then
    vm_state="running"
  else
    vm_state="stopped"
  fi

  if ssh_dst "[[ -f '$vmconf' ]]" 2>/dev/null && [[ "$FORCE" == false ]]; then
    error "VM $vmid already exists on $remote_host. Use -f to overwrite."
  fi

  log "VM state: $vm_state"

  final_snap="omix_cp_$(date +%Y%m%d_%H%M%S)"
  if [[ "$vm_state" == "stopped" ]]; then
    log "VM stopped — will create final snapshot: $final_snap"
  fi

  sync_vm_disks

  if [[ "$vm_state" == "stopped" ]]; then
    log "Finalizing configuration..."
    ssh_src "cat $vmconf" | ssh_dst "cat > $vmconf"
  fi

  log "=== COPY COMPLETE ==="
  log "VM $vmid successfully copied to $remote_host"
}

main "$@"
