#!/bin/bash

# Script originally written by zxq5, I added separate scripts to remove `jq` dependency.

script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)

source $script_dir/build.sh

# Error handling
set -e
trap 'echo -e "${RED}${BOLD}error${NC}: build failed" >&2' ERR

echo -e "${GREEN}${BOLD} Running kernel in debug mode."

# Check if KVM is available
if [ "${KVM_FLAG:-enable}" = "disable" ]; then
    warning "KVM acceleration disabled by user"
    kvm_flag=""
elif [ -c "/dev/kvm" ] && [ -w "/dev/kvm" ]; then
    info "KVM acceleration enabled"
    kvm_flag="-enable-kvm"
else
    warning "KVM acceleration not available (is kvm module loaded?)"
    kvm_flag=""
fi

# Enable using GDB with $USE_GDB.
if [ $USE_GDB ]; then
    debug_flags="-s -S"
else
    debug_flags=""
fi

# Set up test-specific flags
if [ $is_test -eq 1 ]; then
    test_flags="-device isa-debug-exit,iobase=0xf4,iosize=0x04 -display none"
    serial_flags="-serial stdio"
else
    test_flags=""
    # serial_flags="-serial tcp:127.0.0.1:1234,server -monitor telnet:127.0.0.1:1235,server"
    serial_flags="-serial stdio"
fi

# Set up VM memory
if [ $VM_MEMORY ]; then
    vm_memory_flag="-m $VM_MEMORY"
else
    vm_memory_flag="-m 2G"
fi

# Set up boot flags
if [ $USE_LEGACY_BIOS ]; then
    boot_flags=""
else
#   Check for the presence of the OVMF firmware.
    if [ ! -f $build_dir/RELEASEX64_OVMF_CODE.fd ]; then
        info "Downloading OVMF UEFI firmware for QEMU"
        info "To disable this, set USE_LEGACY_BIOS=1."
        pushd $build_dir
        curl https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF_CODE.fd -LO || error "failed to download OVMF firmware for UEFI"
        curl https://retrage.github.io/edk2-nightly/bin/RELEASEX64_OVMF_VARS.fd -LO || error "failed to download OVMF firmware for UEFI"
        popd
    fi

    boot_flags="-drive if=pflash,format=raw,readonly=on,file=$build_dir/RELEASEX64_OVMF_CODE.fd \
                -drive if=pflash,format=raw,file=$build_dir/RELEASEX64_OVMF_VARS.fd"
fi

# Run in QEMU
if [[ ${QEMU_FLAGS} == *-S* ]]; then
    info "Running OS in QEMU with GDB debugging enabled"
    info "To connect GDB, run: gdb"
    info "At the GDB prompt, type: target remote localhost:1234"
else
    info "Running OS in QEMU..."
fi

check_test_res() {
    qemu_exit_code=$?
    if [ $qemu_exit_code -eq 33 ]; then
        # Success case (0x10 << 1) | 1 = 33
        info "All tests passed"
        exit 0
    elif [ $qemu_exit_code -eq 35 ]; then
        # Failure case (0x11 << 1) | 1 = 35
        warning "Some tests failed"
        exit 1
    else
        # Any other exit code is treated as a failure
        warning "Some tests failed"
        exit 1
    fi
}

trap 'check_test_res "tests completed"' ERR
 

# NOTE(ali): For some reason the values in `boot_flags` were causing issues
# 	     on WSL, so they've been eradicated.
systemInfo=$(uname -r)
if [[ $systemInfo == *"WSL"* ]]; then
    echo "Running on WSL2"
    boot_flags=""
fi

cd "$project_root"
qemu-system-x86_64 -M q35 \
    -cdrom "$build_dir/image.iso" \
    ${kvm_flag} \
    -boot d \
    ${vm_memory_flag} \
    ${serial_flags} \
    -no-reboot \
    ${test_flags} \
    ${debug_flags} \
    ${boot_flags} \
    ${QEMU_FLAGS:-}

