#!/usr/bin/env bash
# vm-exec.sh — Execute commands inside the test VM via VBoxManage guestcontrol.
#
# Usage:
#   vm-exec.sh cmd  "volta --version"
#   vm-exec.sh ps   "Get-Command node"
#   vm-exec.sh wsl  "redis-cli ping"
#   vm-exec.sh copy-to <local-path> <guest-path>
#
# Options:
#   --timeout <seconds>   Override default timeout (default: 300)
#   --no-log              Don't write to log file
#
# Exit code is forwarded from the guest command.

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/config.sh"

# ─── Argument Parsing ───────────────────────────────────────

TIMEOUT="$TIMEOUT_DEFAULT"
NO_LOG=false
MODE=""
GUEST_CMD=""

while [[ $# -gt 0 ]]; do
  case "$1" in
    --timeout) TIMEOUT="$2"; shift 2 ;;
    --no-log) NO_LOG=true; shift ;;
    cmd|ps|wsl|copy-to)
      MODE="$1"
      shift
      GUEST_CMD="$*"
      break
      ;;
    *)
      echo "Usage: vm-exec.sh [--timeout N] [--no-log] <cmd|ps|wsl|copy-to> <command...>"
      exit 1
      ;;
  esac
done

if [[ -z "$MODE" ]]; then
  echo "Usage: vm-exec.sh [--timeout N] [--no-log] <cmd|ps|wsl|copy-to> <command...>"
  exit 1
fi

require_vbox
ensure_dirs

# ─── Log Setup ──────────────────────────────────────────────

LOG_FILE="$LOG_DIR/exec-$(timestamp).log"
if $NO_LOG; then
  LOG_FILE="/dev/null"
fi

log_exec() {
  echo "[$(date '+%H:%M:%S')] [$MODE] $GUEST_CMD" >> "$LOG_FILE"
}

# ─── Execution Modes ───────────────────────────────────────

run_cmd() {
  # Run a command via cmd.exe in the guest
  log_exec
  "$VBOXMANAGE" guestcontrol "$VM_NAME" run \
    --exe "C:\\Windows\\System32\\cmd.exe" \
    --username "$VM_USER" --password "$VM_PASS" \
    --wait-stdout --wait-stderr \
    --timeout "$((TIMEOUT * 1000))" \
    -- /c "$GUEST_CMD" 2>&1 | tee -a "$LOG_FILE"
  return "${PIPESTATUS[0]}"
}

run_ps() {
  # Run a PowerShell command in the guest
  log_exec
  "$VBOXMANAGE" guestcontrol "$VM_NAME" run \
    --exe "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" \
    --username "$VM_USER" --password "$VM_PASS" \
    --wait-stdout --wait-stderr \
    --timeout "$((TIMEOUT * 1000))" \
    -- -NoProfile -NonInteractive -Command "$GUEST_CMD" 2>&1 | tee -a "$LOG_FILE"
  return "${PIPESTATUS[0]}"
}

run_wsl() {
  # Run a bash command inside the guest's WSL Ubuntu distro
  log_exec
  "$VBOXMANAGE" guestcontrol "$VM_NAME" run \
    --exe "C:\\Windows\\System32\\wsl.exe" \
    --username "$VM_USER" --password "$VM_PASS" \
    --wait-stdout --wait-stderr \
    --timeout "$((TIMEOUT * 1000))" \
    -- -d Ubuntu -- bash -c "$GUEST_CMD" 2>&1 | tee -a "$LOG_FILE"
  return "${PIPESTATUS[0]}"
}

run_copy_to() {
  # Copy a file from host to guest
  # GUEST_CMD is "<local-path> <guest-path>" (two args)
  local local_path guest_path
  local_path="$(echo "$GUEST_CMD" | awk '{print $1}')"
  guest_path="$(echo "$GUEST_CMD" | awk '{$1=""; print $0}' | sed 's/^ //')"

  if [[ ! -f "$local_path" ]]; then
    log_fail "Local file not found: $local_path"
    return 1
  fi

  log_info "Copying $local_path -> $guest_path (in VM)"
  echo "[$(date '+%H:%M:%S')] [copy-to] $local_path -> $guest_path" >> "$LOG_FILE"

  # Ensure the target directory exists in the guest
  local guest_dir
  guest_dir=$(dirname "$guest_path" | sed 's|/|\\|g')
  "$VBOXMANAGE" guestcontrol "$VM_NAME" run \
    --exe "C:\\Windows\\System32\\cmd.exe" \
    --username "$VM_USER" --password "$VM_PASS" \
    --wait-stdout --wait-stderr \
    -- /c "mkdir \"$guest_dir\" 2>NUL & echo ok" &>/dev/null || true

  "$VBOXMANAGE" guestcontrol "$VM_NAME" copyto \
    --username "$VM_USER" --password "$VM_PASS" \
    --target-directory "$guest_dir" \
    "$local_path" 2>&1 | tee -a "$LOG_FILE"
  return "${PIPESTATUS[0]}"
}

# ─── Dispatch ──────────────────────────────────────────────

case "$MODE" in
  cmd)     run_cmd ;;
  ps)      run_ps ;;
  wsl)     run_wsl ;;
  copy-to) run_copy_to ;;
esac
