#!/usr/bin/env bash
# ============================================================================
# Rumpk QEMU Runner — Boot, Test, or Interactive Shell
# ============================================================================
# Usage:
#   ./run.sh                    # Interactive RISC-V session
#   ./run.sh test               # Automated boot test (10s timeout, check output)
#   ./run.sh [riscv64|aarch64]  # Architecture selection (future)
#
# Exit codes:
#   0 = Boot successful (test mode: all checks passed)
#   1 = Boot failed or timeout
# ============================================================================
set -euo pipefail
cd "$(dirname "$0")"

MODE="${1:-interactive}"
ARCH="${2:-riscv64}"
TIMEOUT=25

KERNEL="zig-out/bin/rumpk.elf"
DISK="build/disk.img"

# Fallback to build/ location if zig-out doesn't have it
if [ ! -f "$KERNEL" ]; then
    KERNEL="build/rumpk-riscv64.elf"
fi

if [ ! -f "$KERNEL" ]; then
    echo "ERROR: No kernel binary found. Run: ./build_nim.sh && zig build -Dtarget=riscv64-freestanding-none -Dcpu=sifive_u54"
    exit 1
fi

case "$ARCH" in
    riscv64)
        QEMU_CMD=(
            qemu-system-riscv64
            -M virt -m 512M -nographic
            -kernel "$KERNEL"
        )
        # Add disk if it exists
        if [ -f "$DISK" ]; then
            QEMU_CMD+=(
                -drive "if=none,format=raw,file=$DISK,id=blk0"
                -device virtio-blk-pci,drive=blk0
            )
        fi
        QEMU_CMD+=(
            -device virtio-net-pci,netdev=net0
            -netdev user,id=net0
        )
        ;;
    *)
        echo "ERROR: Architecture '$ARCH' not yet supported"
        echo "Supported: riscv64"
        exit 1
        ;;
esac

if [ "$MODE" = "test" ]; then
    echo "=== Rumpk Boot Test ($ARCH, ${TIMEOUT}s timeout) ==="

    LOGFILE=$(mktemp /tmp/rumpk-boot-XXXXXX.log)
    trap "rm -f $LOGFILE" EXIT

    timeout "$TIMEOUT" "${QEMU_CMD[@]}" > "$LOGFILE" 2>&1 || true

    # Boot verification checks
    PASS=0
    FAIL=0
    TOTAL=0

    check() {
        local name="$1"
        local pattern="$2"
        TOTAL=$((TOTAL + 1))
        if grep -q "$pattern" "$LOGFILE"; then
            echo "  PASS: $name"
            PASS=$((PASS + 1))
        else
            echo "  FAIL: $name"
            FAIL=$((FAIL + 1))
        fi
    }

    check "OpenSBI handoff"        "Boot HART ID"
    check "UART proof-of-life"     "UART.*Loopback Test: PASS"
    check "Zig HAL entry"          "zig_entry reached"
    check "Nim L1 handoff"         "Handing off to Nim L1"
    check "ION pool ready"         "ION.*Pool Ready"
    check "VirtIO-Net init"        "VirtIO.*Initialization Complete"
    check "CSpace init"            "Capability system initialized"
    check "Truth Ledger init"      "System Truth Ledger initialized"
    check "Fiber dispatcher"       "Multi-Fiber Dispatcher starting"
    check "NetSwitch online"       "Traffic Engine Online"
    check "LFS mounted"            "Sovereign filesystem mounted"
    check "Init loaded"            "NIPBOX.*Entry point reached"
    check "Shell spawned"          "SOVEREIGN SUPERVISOR"
    check "DHCP IP acquired"       "IP STATUS CHANGE"

    echo ""
    echo "=== Result: $PASS/$TOTAL passed, $FAIL failed ==="

    if [ "$FAIL" -gt 0 ]; then
        echo ""
        echo "Boot log saved: $LOGFILE"
        trap - EXIT  # Don't delete on failure
        exit 1
    fi

    exit 0

elif [ "$MODE" = "interactive" ]; then
    echo "=== Rumpk Interactive Session ($ARCH) ==="
    echo "    Kernel: $KERNEL"
    echo "    Exit:   Ctrl-A X"
    echo ""
    exec "${QEMU_CMD[@]}"
else
    echo "Usage: ./run.sh [interactive|test] [riscv64]"
    exit 1
fi
