#!/usr/bin/env bash
# investigate-parallel - Parallel IncusOS boot investigation with smart phase detection
#
# Runs N VMs simultaneously, monitors each independently, probes API on success.
# Uses aggressive port polling + screenshot capture for phase detection.
#
# Usage:
#   ./investigate-parallel --count 4 --iso old --label baseline
#   ./investigate-parallel --count 4 --iso new --label version-mismatch
#   ./investigate-parallel --count 4 --iso /tmp/IncusOS-oc.iso --label oc-iso

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SEED_TOOL="${SCRIPT_DIR}/incusos-seed"
PVE_API="${SCRIPT_DIR}/pve-api"

# Defaults
COUNT=4
START_VMID=850
ISO_MODE="old"    # old, new, or file path
LABEL=""
DRY_RUN=false
BOOT_TIMEOUT=240  # longer for version-mismatch OS update path

# Proxmox config
PVE_HOST=""
PVE_NODE=""
PVE_STORAGE=""
PVE_ISO_STORAGE=""
PVE_BRIDGE=""
PVE_POOL=""

# ISO
ISO_FILENAME=""
ISO_VERSION=""

# Results
RESULTS_DIR=""

# ---------------------------------------------------------------------------
# Colors
# ---------------------------------------------------------------------------

if [[ -t 1 ]] && [[ "${NO_COLOR:-}" != "1" ]] && [[ "${TERM:-}" != "dumb" ]]; then
    RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m'
    CYAN='\033[0;36m' BOLD='\033[1m' DIM='\033[2m' RESET='\033[0m'
else
    RED='' GREEN='' YELLOW='' CYAN='' BOLD='' DIM='' RESET=''
fi

step()    { echo -e "${CYAN}[step]${RESET}    ${BOLD}$*${RESET}"; }
success() { echo -e "${GREEN}[ok]${RESET}      $*"; }
warn()    { echo -e "${YELLOW}[warn]${RESET}    $*" >&2; }
error()   { echo -e "${RED}[error]${RESET}   $*" >&2; }
info()    { echo -e "${DIM}[info]${RESET}    $*"; }

# ---------------------------------------------------------------------------
# Argument parsing
# ---------------------------------------------------------------------------

while [[ $# -gt 0 ]]; do
    case "$1" in
        --count)   COUNT="${2:?'--count requires N'}"; shift 2 ;;
        --iso)     ISO_MODE="${2:?'--iso requires old|new|path'}"; shift 2 ;;
        --label)   LABEL="${2:?'--label requires string'}"; shift 2 ;;
        --start-vmid) START_VMID="${2:?'--start-vmid requires N'}"; shift 2 ;;
        --dry-run) DRY_RUN=true; shift ;;
        --timeout) BOOT_TIMEOUT="${2:?'--timeout requires seconds'}"; shift 2 ;;
        -h|--help)
            echo "Usage: investigate-parallel [OPTIONS]"
            echo "  --count N       Parallel VMs (default: 4, max 8)"
            echo "  --iso MODE      old (202602200553), new (latest CDN), or file path"
            echo "  --label NAME    Results label"
            echo "  --start-vmid N  First VMID (default: 850)"
            echo "  --timeout N     Boot timeout seconds (default: 240)"
            echo "  --dry-run       Preview only"
            exit 0
            ;;
        *) error "Unknown: $1"; exit 1 ;;
    esac
done

# ---------------------------------------------------------------------------
# Load environment & config
# ---------------------------------------------------------------------------

load_env() {
    local dir="$SCRIPT_DIR"
    while [[ "$dir" != "/" ]]; do
        [[ -f "${dir}/env" ]] && { source "${dir}/env"; return; }
        dir="$(dirname "$dir")"
    done
}
load_env

[[ -z "${PROXMOX_TOKEN_SECRET:-}" ]] && { error "PROXMOX_TOKEN_SECRET not set"; exit 1; }
[[ -z "${PROXMOX_ROOT_PASSWORD:-}" ]] && { error "PROXMOX_ROOT_PASSWORD not set"; exit 1; }

yaml_get() {
    local val
    val=$(awk -F': ' -v k="$1" '$1 == k {print $2; exit}' "${SCRIPT_DIR}/proxmox.yaml" 2>/dev/null) || val=""
    val="${val#\"}" ; val="${val%\"}" ; val="${val#\'}" ; val="${val%\'}"
    echo "${val:-${2:-}}"
}

PVE_HOST=$(yaml_get host)
PVE_NODE=$(yaml_get node pve)
PVE_STORAGE=$(yaml_get storage local-lvm)
PVE_ISO_STORAGE=$(yaml_get iso_storage local)
PVE_BRIDGE=$(yaml_get bridge vmbr0)
PVE_POOL=$(yaml_get pool)

# ---------------------------------------------------------------------------
# Screenshot helpers
# ---------------------------------------------------------------------------

SSH_OPTS=(-o StrictHostKeyChecking=no -o ConnectTimeout=5 -o LogLevel=ERROR)

take_screenshot() {
    local vmid="$1" output="$2"
    local rppm="/tmp/vm-${vmid}-screen.ppm"
    sshpass -p "$PROXMOX_ROOT_PASSWORD" ssh "${SSH_OPTS[@]}" "root@${PVE_HOST}" \
        "echo 'screendump ${rppm}' | qm monitor ${vmid}" &>/dev/null || return 1
    sshpass -p "$PROXMOX_ROOT_PASSWORD" scp "${SSH_OPTS[@]}" \
        "root@${PVE_HOST}:${rppm}" "/tmp/vm-${vmid}-screen.ppm" &>/dev/null || return 1
    sshpass -p "$PROXMOX_ROOT_PASSWORD" ssh "${SSH_OPTS[@]}" "root@${PVE_HOST}" \
        "rm -f ${rppm}" &>/dev/null || true
    python3 -c "from PIL import Image; Image.open('/tmp/vm-${vmid}-screen.ppm').save('${output}')" 2>/dev/null || {
        mv "/tmp/vm-${vmid}-screen.ppm" "${output%.png}.ppm" 2>/dev/null || true
    }
    rm -f "/tmp/vm-${vmid}-screen.ppm" 2>/dev/null || true
}

# ---------------------------------------------------------------------------
# ISO resolution
# ---------------------------------------------------------------------------

resolve_iso() {
    case "$ISO_MODE" in
        old)
            ISO_FILENAME="IncusOS_202602200553.iso"
            ISO_VERSION="202602200553"
            ;;
        new)
            # Find latest on Proxmox
            local latest
            latest=$("$PVE_API" "/nodes/${PVE_NODE}/storage/${PVE_ISO_STORAGE}/content?content=iso" 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin).get('data', [])
isos = [d['volid'].split('/')[-1] for d in data if 'IncusOS_' in d.get('volid','') and '-oc' not in d['volid'].split('/')[-1].lower()]
isos.sort(reverse=True)
print(isos[0] if isos else '')
" 2>/dev/null)
            if [[ -z "$latest" ]]; then
                error "No IncusOS ISO found on Proxmox"; exit 1
            fi
            ISO_FILENAME="$latest"
            ISO_VERSION=$(echo "$latest" | sed -n 's/IncusOS_\([0-9]*\)\..*/\1/p')
            ;;
        *)
            # File path — must already be uploaded
            ISO_FILENAME="$(basename "$ISO_MODE")"
            ISO_VERSION=$(echo "$ISO_FILENAME" | sed -n 's/.*_\([0-9]*\)\..*/\1/p')
            [[ -z "$ISO_VERSION" ]] && ISO_VERSION="custom"
            ;;
    esac
    success "ISO: ${ISO_FILENAME} (version ${ISO_VERSION})"
}

# ---------------------------------------------------------------------------
# Single VM lifecycle (called as background job)
# ---------------------------------------------------------------------------

deploy_single_vm() {
    local vmid="$1"
    local vm_name="$2"
    local run_dir="$3"
    local seed_iso="$4"
    local result_file="${run_dir}/result.txt"
    local log_file="${run_dir}/deploy.log"

    _log() { echo "[$(date '+%H:%M:%S.%3N')] $*" >> "$log_file"; }

    # Error trap: write FAIL result on any uncaught error
    trap '_log "ERROR at line $LINENO: exit code $?"; echo "ERROR|line_${LINENO}|0|N/A|N/A|N/A" > "$result_file"' ERR

    _log "=== VM ${vmid} (${vm_name}) ==="
    _log "ISO: ${ISO_FILENAME}, seed: ${seed_iso}"

    # Create VM
    local json_payload
    json_payload=$(python3 -c "
import json
p = {
    'vmid': ${vmid}, 'name': '${vm_name}',
    'description': '[incusos-lab:managed] investigate-parallel',
    'ostype': 'l26', 'bios': 'ovmf', 'machine': 'q35',
    'efidisk0': '${PVE_STORAGE}:0,efitype=4m,pre-enrolled-keys=0',
    'tpmstate0': '${PVE_STORAGE}:1,version=v2.0',
    'cpu': 'host', 'cores': 4, 'memory': 4096, 'balloon': 0,
    'scsihw': 'virtio-scsi-pci', 'scsi0': '${PVE_STORAGE}:50,iothread=1',
    'ide2': '${PVE_ISO_STORAGE}:iso/${ISO_FILENAME},media=cdrom',
    'ide3': '${PVE_ISO_STORAGE}:iso/${seed_iso},media=cdrom',
    'net0': 'virtio,bridge=${PVE_BRIDGE}',
    'boot': 'order=ide2;scsi0', 'agent': 1,
}
pool = '${PVE_POOL}'
if pool: p['pool'] = pool
print(json.dumps(p))
")

    "$PVE_API" "/nodes/${PVE_NODE}/qemu" POST "$json_payload" >/dev/null 2>&1 || {
        echo "ERROR|create_failed|0|N/A|N/A|N/A" > "$result_file"; return
    }
    sleep 15  # Wait for create task (allocating EFI, TPM, 50G disk)
    _log "VM created"

    # Start VM (ISO boot)
    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/start" POST '{}' >/dev/null 2>&1 || {
        _log "ERROR: Failed to start VM"; echo "ERROR|start_failed|0|N/A|N/A|N/A" > "$result_file"; return
    }
    _log "VM started"

    local frame=0

    # Monitor install via blockstat (screenshots every 15s to avoid SSH contention)
    local elapsed=0 prev_wr=0 writes_started=false stable=0
    while [[ $elapsed -lt 300 ]]; do
        sleep 5; elapsed=$((elapsed + 5))
        # Screenshot every 15s during install
        if [[ $((elapsed % 15)) -lt 6 ]]; then
            take_screenshot "$vmid" "${run_dir}/frame-$(printf '%03d' $((++frame))).png" 2>/dev/null || true
        fi

        local wr
        wr=$("$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/current" 2>/dev/null | python3 -c "
import json,sys; d=json.load(sys.stdin).get('data',{}); print(d.get('blockstat',{}).get('scsi0',{}).get('wr_bytes',0))" 2>/dev/null) || wr=0

        if [[ $wr -gt $prev_wr ]]; then
            [[ "$writes_started" != true ]] && { writes_started=true; _log "Install writes started"; }
            stable=0
        elif [[ "$writes_started" == true ]]; then
            stable=$((stable + 1))
            [[ $stable -ge 3 ]] && { _log "Install complete ($(( wr / 1048576 )) MiB)"; break; }
        fi
        prev_wr=$wr

        # Check if VM stopped
        local st
        st=$("$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/current" 2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['status'])" 2>/dev/null) || st="unknown"
        [[ "$st" == "stopped" ]] && { _log "VM stopped during install"; break; }
    done

    # Take screenshot showing install-complete/media-error state
    take_screenshot "$vmid" "${run_dir}/frame-$(printf '%03d' $((++frame))).png" 2>/dev/null || true

    # Transition: stop, remove media, boot from disk
    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/stop" POST '{}' >/dev/null 2>&1 || true
    sleep 8
    # Wait for stop to complete
    for _ in 1 2 3 4 5; do
        local vm_st
        vm_st=$("$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/current" 2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin)['data']['status'])" 2>/dev/null) || vm_st="unknown"
        [[ "$vm_st" == "stopped" ]] && break
        sleep 3
    done
    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/config" "PUT" '{"delete":"ide2,ide3","boot":"order=scsi0"}' >/dev/null 2>&1 || {
        _log "ERROR: Failed to remove media"; echo "ERROR|media_remove|0|N/A|N/A|N/A" > "$result_file"; return
    }
    _log "Media removed"

    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/start" POST '{}' >/dev/null 2>&1 || {
        _log "ERROR: Failed to start from disk"; echo "ERROR|disk_start|0|N/A|N/A|N/A" > "$result_file"; return
    }
    _log "Disk boot started"
    local boot_start
    boot_start=$(date +%s)

    # Poll for port 8443 with periodic screenshots
    local ip="" boot_elapsed=0 port_up=false
    while [[ $boot_elapsed -lt $BOOT_TIMEOUT ]]; do
        sleep 5; boot_elapsed=$(( $(date +%s) - boot_start ))
        # Screenshot every 15s during boot
        if [[ $((boot_elapsed % 15)) -lt 6 ]]; then
            take_screenshot "$vmid" "${run_dir}/frame-$(printf '%03d' $((++frame))).png" 2>/dev/null || true
        fi

        # Try to find IP (after 15s)
        if [[ $boot_elapsed -ge 15 ]] && [[ -z "$ip" ]]; then
            # Get MAC from Proxmox config (only once)
            if [[ -z "${mac:-}" ]]; then
                mac=$("$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/config" 2>/dev/null | python3 -c "
import json, sys, re
net0 = json.load(sys.stdin).get('data',{}).get('net0','')
m = re.search(r'([0-9A-Fa-f:]{17})', net0)
print(m.group(1).lower() if m else '')
" 2>/dev/null) || mac=""
                [[ -n "$mac" ]] && _log "MAC: ${mac}"
            fi
            if [[ -n "${mac:-}" ]]; then
                # Check ARP table (don't flush — other VMs are using it)
                ip=$(ip neigh show | awk -v mac="$mac" 'tolower($0) ~ tolower(mac) {print $1; exit}') || ip=""
                # If not found, do a targeted ARP probe: ping a range of likely DHCP IPs
                if [[ -z "$ip" ]]; then
                    # Only sweep every 30 seconds to avoid overload
                    local now_s
                    now_s=$(date +%s)
                    if [[ $(( now_s - ${_last_sweep:-0} )) -ge 25 ]]; then
                        _last_sweep=$now_s
                        _log "Running ARP sweep"
                        # Sweep in smaller batches to avoid overwhelming
                        for octet in $(seq 1 254); do
                            ping -c 1 -W 1 "192.168.1.${octet}" &>/dev/null &
                        done
                        wait 2>/dev/null || true
                        sleep 2
                    fi
                    ip=$(ip neigh show | awk -v mac="$mac" 'tolower($0) ~ tolower(mac) {print $1; exit}') || ip=""
                fi
                if [[ -n "$ip" ]]; then
                    if ping -c 1 -W 2 "$ip" &>/dev/null; then
                        _log "IP detected: ${ip}"
                    else
                        _log "IP ${ip} not responding, retrying"
                        ip=""
                    fi
                fi
            fi
        fi

        # Check port 8443
        if [[ -n "$ip" ]]; then
            if curl -sk --connect-timeout 3 "https://${ip}:8443" &>/dev/null; then
                port_up=true
                _log "Port 8443 UP at ${ip} (${boot_elapsed}s)"
                break
            fi
        fi

        [[ $((boot_elapsed % 30)) -lt 6 ]] && _log "Disk boot: ${boot_elapsed}s, ip=${ip:-none}"
    done

    # Take final screenshot
    take_screenshot "$vmid" "${run_dir}/frame-$(printf '%03d' $((++frame))).png" 2>/dev/null || true

    # Probe API if successful
    local scrub="N/A" freq="N/A" osver="N/A"
    if [[ "$port_up" == true ]] && [[ -n "$ip" ]]; then
        # Add incus remote and probe
        incus remote add "$vm_name" "https://${ip}:8443" --accept-certificate 2>/dev/null || true
        local storage_json update_json system_json
        storage_json=$(incus query "${vm_name}:/os/1.0/system/storage" 2>/dev/null) || storage_json='{}'
        update_json=$(incus query "${vm_name}:/os/1.0/system/update" 2>/dev/null) || update_json='{}'
        system_json=$(incus query "${vm_name}:/os/1.0" 2>/dev/null) || system_json='{}'

        scrub=$(echo "$storage_json" | python3 -c "import json,sys; print(json.load(sys.stdin).get('config',{}).get('scrub_schedule','EMPTY'))" 2>/dev/null) || scrub="error"
        freq=$(echo "$update_json" | python3 -c "import json,sys; print(json.load(sys.stdin).get('config',{}).get('check_frequency','EMPTY'))" 2>/dev/null) || freq="error"
        osver=$(echo "$system_json" | python3 -c "import json,sys; print(json.load(sys.stdin).get('environment',{}).get('os_version','EMPTY'))" 2>/dev/null) || osver="error"

        _log "API: scrub='${scrub}' freq='${freq}' os=${osver}"

        # Save full probe data
        echo "$storage_json" > "${run_dir}/api-storage.json" 2>/dev/null || true
        echo "$update_json" > "${run_dir}/api-update.json" 2>/dev/null || true
        echo "$system_json" > "${run_dir}/api-system.json" 2>/dev/null || true

        # Cleanup remote
        local cur_remote
        cur_remote=$(incus remote get-default 2>/dev/null) || true
        [[ "$cur_remote" == "$vm_name" ]] && incus remote switch local 2>/dev/null || true
        incus remote remove "$vm_name" 2>/dev/null || true
    fi

    # Determine outcome:
    # - PASS = port up AND scrub_schedule is set (genuine success)
    # - CRONTAB_BUG = port up but scrub_schedule empty (detected during error window)
    # - FAIL = port never came up (could be bug + bad timing, or IP detection failure)
    local outcome="FAIL"
    if [[ "$port_up" == true ]]; then
        if [[ -n "$scrub" ]] && [[ "$scrub" != "" ]] && [[ "$scrub" != "EMPTY" ]] && [[ "$scrub" != "N/A" ]]; then
            outcome="PASS"
        else
            outcome="CRONTAB_BUG"
        fi
    fi

    echo "${outcome}|${boot_elapsed}|${scrub}|${freq}|${osver}|${ip:-none}" > "$result_file"
    _log "RESULT: ${outcome} boot=${boot_elapsed}s scrub='${scrub}' freq='${freq}' os=${osver}"
}

# ---------------------------------------------------------------------------
# Cleanup single VM
# ---------------------------------------------------------------------------

cleanup_vm() {
    local vmid="$1"
    local seed_iso="$2"
    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/stop" POST >/dev/null 2>&1 || true
    sleep 3
    "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}?purge=1&destroy-unreferenced-disks=1" DELETE >/dev/null 2>&1 || true
    "$PVE_API" "/nodes/${PVE_NODE}/storage/${PVE_ISO_STORAGE}/content/${PVE_ISO_STORAGE}:iso/${seed_iso}" DELETE >/dev/null 2>&1 || true
}

# ---------------------------------------------------------------------------
# Main
# ---------------------------------------------------------------------------

echo -e "${BOLD}investigate-parallel${RESET} — Parallel IncusOS boot investigation"
echo ""

[[ -z "$LABEL" ]] && LABEL="${ISO_MODE}"

if [[ "$DRY_RUN" == true ]]; then
    echo "  Count: ${COUNT}, ISO: ${ISO_MODE}, VMIDs: ${START_VMID}-$((START_VMID + COUNT - 1))"
    exit 0
fi

step "Resolving ISO"
resolve_iso

RESULTS_DIR="${SCRIPT_DIR}/observe-runs/parallel_$(date '+%Y-%m-%d_%H-%M-%S')_${LABEL}"
mkdir -p "$RESULTS_DIR"
success "Output: ${RESULTS_DIR}/"

# Generate seeds and create run dirs
step "Generating ${COUNT} seeds"
declare -a VM_NAMES=() VM_SEEDS=() VM_DIRS=()
for ((i=0; i<COUNT; i++)); do
    vmid=$((START_VMID + i))
    vm_name="inv-${vmid}"
    seed_name="seed-inv-${vmid}.iso"
    run_dir="${RESULTS_DIR}/vm-${vmid}"
    mkdir -p "$run_dir"

    VM_NAMES+=("$vm_name")
    VM_SEEDS+=("$seed_name")
    VM_DIRS+=("$run_dir")

    local_seed="/tmp/${seed_name}"
    "$SEED_TOOL" --format iso --app incus --output "$local_seed" \
        --force-install --force-reboot --hostname "$vm_name" \
        --defaults --quiet &>/dev/null

    # Upload seed (use Python to avoid bash ! quoting issues with API token)
    url="https://${PVE_HOST}:8006/api2/json/nodes/${PVE_NODE}/storage/${PVE_ISO_STORAGE}/upload"
    python3 -c "
import subprocess, os, sys
# Read token_id from proxmox.yaml
token_id = ''
yaml_file = '${SCRIPT_DIR}/proxmox.yaml'
for line in open(yaml_file):
    line = line.strip()
    if line.startswith('api_token_id:'):
        token_id = line.split(': ', 1)[1].strip().strip(\"'\\\"\")
secret = os.environ.get('PROXMOX_TOKEN_SECRET', '')
if not token_id or not secret:
    sys.exit(1)
r = subprocess.run([
    'curl', '-fsSk',
    '-H', 'Authorization: PVEAPIToken=' + token_id + '=' + secret,
    '-F', 'content=iso',
    '-F', 'filename=@${local_seed};filename=${seed_name}',
    '${url}'
], capture_output=True)
sys.exit(r.returncode)
" 2>/dev/null
    rm -f "$local_seed"
    info "Seed $((i+1))/${COUNT}: ${seed_name}"
done
success "All seeds uploaded"

# Check VMIDs are free
step "Checking VMIDs"
for ((i=0; i<COUNT; i++)); do
    vmid=$((START_VMID + i))
    if "$PVE_API" "/nodes/${PVE_NODE}/qemu/${vmid}/status/current" >/dev/null 2>&1; then
        error "VMID ${vmid} already in use"; exit 1
    fi
done
success "VMIDs ${START_VMID}-$((START_VMID + COUNT - 1)) available"

echo ""
echo -e "${BOLD}Launching ${COUNT} VMs in parallel${RESET}"
echo "  ISO: ${ISO_FILENAME} (${ISO_VERSION})"
echo "  VMIDs: ${START_VMID}-$((START_VMID + COUNT - 1))"
echo "  Boot timeout: ${BOOT_TIMEOUT}s"
echo ""

# Trap for cleanup
trap_cleanup() {
    echo ""
    warn "Interrupted — cleaning up all VMs"
    for ((i=0; i<COUNT; i++)); do
        cleanup_vm "$((START_VMID + i))" "${VM_SEEDS[$i]}" &
    done
    wait
    exit 130
}
trap trap_cleanup INT TERM

# Launch all VMs in parallel
pids=()
for ((i=0; i<COUNT; i++)); do
    vmid=$((START_VMID + i))
    ( set +e; deploy_single_vm "$vmid" "${VM_NAMES[$i]}" "${VM_DIRS[$i]}" "${VM_SEEDS[$i]}" 2>"${VM_DIRS[$i]}/stderr.log" ) &
    pids+=($!)
    info "Started VM ${vmid} (PID $!)"
done

# Wait for all to complete
for pid in "${pids[@]}"; do
    wait "$pid" || true
done

echo ""
echo -e "${BOLD}════════════════════════════════════════════════${RESET}"
echo -e "${BOLD}  Results (ISO: ${ISO_FILENAME})${RESET}"
echo -e "${BOLD}════════════════════════════════════════════════${RESET}"
echo ""

pass=0 fail=0 crontab_bug=0
for ((i=0; i<COUNT; i++)); do
    vmid=$((START_VMID + i))
    rfile="${VM_DIRS[$i]}/result.txt"
    if [[ -f "$rfile" ]]; then
        IFS='|' read -r outcome boot_s scrub freq osver vm_ip < "$rfile"
        if [[ "$outcome" == "PASS" ]]; then
            marker="${GREEN}PASS${RESET}"; pass=$((pass + 1))
        elif [[ "$outcome" == "CRONTAB_BUG" ]]; then
            marker="${YELLOW}CRONTAB_BUG${RESET}"; crontab_bug=$((crontab_bug + 1))
        else
            marker="${RED}FAIL${RESET}"; fail=$((fail + 1))
        fi
        echo -e "  ${vmid}: ${marker}  boot=${boot_s}s  scrub='${scrub}'  freq='${freq}'  os=${osver}  ip=${vm_ip}"
    else
        echo -e "  ${vmid}: ${RED}NO RESULT${RESET}"
        fail=$((fail + 1))
    fi
done

echo ""
echo -e "  Total: ${GREEN}${pass} PASS${RESET}, ${YELLOW}${crontab_bug} CRONTAB_BUG${RESET}, ${RED}${fail} FAIL/NO_IP${RESET} (of ${COUNT})"
total_bad=$((crontab_bug + fail))
[[ $total_bad -gt 0 ]] && echo -e "  Bug rate: ${YELLOW}$(( crontab_bug * 100 / COUNT ))%${RESET} confirmed, ${RED}$(( fail * 100 / COUNT ))%${RESET} unknown (IP detection failure)"

# Write summary
{
    echo "# investigate-parallel results"
    echo "# $(date -Iseconds)"
    echo "# ISO: ${ISO_FILENAME} (${ISO_VERSION})"
    echo "# Count: ${COUNT}, VMIDs: ${START_VMID}-$((START_VMID + COUNT - 1))"
    echo "#"
    echo "# vmid|outcome|boot_s|scrub_schedule|check_frequency|os_version|ip"
    for ((i=0; i<COUNT; i++)); do
        vmid=$((START_VMID + i))
        rfile="${VM_DIRS[$i]}/result.txt"
        [[ -f "$rfile" ]] && echo "${vmid}|$(cat "$rfile")"
    done
} > "${RESULTS_DIR}/results.txt"

echo ""

# Cleanup all VMs
step "Cleaning up"
for ((i=0; i<COUNT; i++)); do
    cleanup_vm "$((START_VMID + i))" "${VM_SEEDS[$i]}" &
done
wait
sleep 3
success "All cleaned up"

echo ""
echo "Screenshots: ${RESULTS_DIR}/vm-*/frame-*.png"
echo "Results:     ${RESULTS_DIR}/results.txt"
echo ""

exit $fail
