#!/usr/bin/env bash
# config.sh — Shared constants, paths, and helper functions for the test harness.
# Sourced by every other script in the harness.

set -euo pipefail

# ─── VM Configuration ───────────────────────────────────────
VM_NAME="bigstack-test"
VM_DIR="C:/bigstack-test-vm"
VM_RAM_MB=8192
VM_CPUS=4
VM_VRAM_MB=128
VM_DISK_MB=65536
VM_USER="testuser"
VM_PASS="BigstackTest1!"

# ─── Snapshots ──────────────────────────────────────────────
SNAPSHOT_CLEAN="clean-windows"
SNAPSHOT_WSL="clean-with-wsl"

# ─── Paths ──────────────────────────────────────────────────
BIGSTACK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SKILL_DIR="$BIGSTACK_DIR/bigstack-cloud-setup"
TEST_DIR="$SKILL_DIR/test"
LOG_DIR="$VM_DIR/logs"

# Guest paths (Windows paths inside the VM)
GUEST_TEMP="C:\\bigstack-test"
GUEST_CHECK_SCRIPT="$GUEST_TEMP\\check-prerequisites.sh"

# ─── Timeouts (seconds) ────────────────────────────────────
TIMEOUT_DEFAULT=300          # 5 min for most steps
TIMEOUT_INSTALL=900          # 15 min for Windows install / large compilations
TIMEOUT_BOOT=60              # 1 min for guest additions to respond after reboot
TIMEOUT_POLL_INTERVAL=10     # seconds between guestcontrol polls

# ─── Colors ─────────────────────────────────────────────────
if [[ -t 1 ]]; then
  GREEN='\033[0;32m'
  RED='\033[0;31m'
  YELLOW='\033[0;33m'
  CYAN='\033[0;36m'
  BOLD='\033[1m'
  RESET='\033[0m'
else
  GREEN='' RED='' YELLOW='' CYAN='' BOLD='' RESET=''
fi

# ─── Logging Helpers ────────────────────────────────────────

log_pass() { echo -e "${GREEN}[PASS]${RESET} $*"; }
log_fail() { echo -e "${RED}[FAIL]${RESET} $*"; }
log_info() { echo -e "${CYAN}[INFO]${RESET} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${RESET} $*"; }
log_step() { echo -e "\n${BOLD}=== $* ===${RESET}"; }

# ─── Ensure Directories ────────────────────────────────────

ensure_dirs() {
  mkdir -p "$VM_DIR" "$LOG_DIR"
}

# ─── VBoxManage Path ───────────────────────────────────────

resolve_vboxmanage() {
  if command -v VBoxManage &>/dev/null; then
    echo "VBoxManage"
    return
  fi
  # Common Windows install locations (accessed from Git Bash / MSYS2)
  local candidates=(
    "/c/Program Files/Oracle/VirtualBox/VBoxManage.exe"
    "/c/Program Files (x86)/Oracle/VirtualBox/VBoxManage.exe"
  )
  for c in "${candidates[@]}"; do
    if [[ -f "$c" ]]; then
      echo "$c"
      return
    fi
  done
  echo ""
}

VBOXMANAGE="$(resolve_vboxmanage)"

require_vbox() {
  if [[ -z "$VBOXMANAGE" ]]; then
    log_fail "VBoxManage not found. Install VirtualBox 7+ from https://www.virtualbox.org/"
    exit 1
  fi
  local ver
  ver=$("$VBOXMANAGE" --version 2>/dev/null || echo "unknown")
  log_info "VirtualBox: $ver"
}

# ─── Timestamp ──────────────────────────────────────────────

timestamp() { date +%Y%m%d-%H%M%S; }

# ─── VM State Helpers ───────────────────────────────────────

vm_exists() {
  "$VBOXMANAGE" showvminfo "$VM_NAME" &>/dev/null
}

vm_running() {
  local state
  state=$("$VBOXMANAGE" showvminfo "$VM_NAME" --machinereadable 2>/dev/null | grep '^VMState=' | cut -d'"' -f2)
  [[ "$state" == "running" ]]
}

vm_has_snapshot() {
  "$VBOXMANAGE" snapshot "$VM_NAME" showvminfo "$1" &>/dev/null 2>&1
}

# ─── Wait for Guest Additions ──────────────────────────────
# Polls VBoxManage guestcontrol until the guest OS responds.

wait_for_guest() {
  local timeout="${1:-$TIMEOUT_INSTALL}"
  local elapsed=0
  log_info "Waiting for guest OS to respond (timeout: ${timeout}s)..."
  while (( elapsed < timeout )); do
    if "$VBOXMANAGE" guestcontrol "$VM_NAME" run \
        --exe "C:\\Windows\\System32\\cmd.exe" \
        --username "$VM_USER" --password "$VM_PASS" \
        --wait-stdout --wait-stderr \
        -- /c "echo ready" &>/dev/null; then
      log_info "Guest responding after ${elapsed}s"
      return 0
    fi
    sleep "$TIMEOUT_POLL_INTERVAL"
    elapsed=$((elapsed + TIMEOUT_POLL_INTERVAL))
  done
  log_fail "Guest did not respond within ${timeout}s"
  return 1
}
