target_dir := "target/x86_64-lancer-none/debug"
kernel_bin := target_dir / "lancer-kernel"
kernel_release := "target/x86_64-lancer-none/release/lancer-kernel"
iso_dir := "target/iso"
iso_file := "target/lancer.iso"
limine_dir := "target/limine"
ovmf_code := "/usr/share/OVMF/OVMF_CODE_4M.fd"
ovmf_vars_src := "/usr/share/OVMF/OVMF_VARS_4M.fd"
ovmf_vars := "target/ovmf/OVMF_VARS_4M.fd"

boot_modules := "lancer-init:init lancer-serial-driver:serial lancer-fbconsole-driver:fbconsole lancer-ps2kbd-driver:ps2kbd lancer-virtio-net-driver:virtio-net lancer-nvme-driver:nvme lancer-lancerfs:lancerfs lancer-vfs:vfs lancer-ramfs:ramfs lancer-netstack:netstack lancer-remote-shell:remote-shell lancer-hello:hello lancer-ping:ping lancer-udp:udp lancer-resolve:resolve lancer-help:help lancer-echo:echo lancer-uptime:uptime lancer-ifconfig:ifconfig lancer-arp:arp lancer-netstat:netstat lancer-fstest:fstest lancer-ls:ls lancer-cat:cat lancer-mkdir:mkdir lancer-rm:rm lancer-write:write lancer-stat:stat lancer-tree:tree lancer-cp:cp lancer-mv:mv lancer-touch:touch lancer-df:df lancer-cd:cd lancer-shell:shell lancer-dmesg:dmesg lancer-thread-test:thread-test"
nvme_disk := "target/nvme-disk.img"

build:
    cargo build --workspace

build-kernel:
    cargo build -p lancer-kernel

build-init:
    cargo build -p lancer-init

build-serial:
    cargo build -p lancer-serial-driver

build-fbconsole:
    cargo build -p lancer-fbconsole-driver

build-ps2kbd:
    cargo build -p lancer-ps2kbd-driver

build-virtio-net:
    cargo build -p lancer-virtio-net-driver

build-nvme:
    cargo build -p lancer-nvme-driver

build-netstack:
    cargo build -p lancer-netstack

build-remote-shell:
    cargo build -p lancer-remote-shell

build-hello:
    cargo build -p lancer-hello

build-ping:
    cargo build -p lancer-ping

build-udp:
    cargo build -p lancer-udp

build-resolve:
    cargo build -p lancer-resolve

build-help:
    cargo build -p lancer-help

build-echo:
    cargo build -p lancer-echo

build-uptime:
    cargo build -p lancer-uptime

build-ifconfig:
    cargo build -p lancer-ifconfig

build-arp:
    cargo build -p lancer-arp

build-netstat:
    cargo build -p lancer-netstat

build-lancerfs:
    cargo build -p lancer-lancerfs

build-vfs:
    cargo build -p lancer-vfs

build-ramfs:
    cargo build -p lancer-ramfs

build-fstest:
    cargo build -p lancer-fstest

build-thread-test:
    cargo build -p lancer-thread-test

release:
    cargo build --workspace --release

clippy:
    cargo clippy --workspace -- -W clippy::all

fmt:
    cargo fmt --check

fmt-fix:
    cargo fmt

clean:
    cargo clean
    rm -rf {{iso_dir}} {{iso_file}}

limine-fetch:
    #!/usr/bin/env bash
    if [ ! -d "{{limine_dir}}" ]; then
        git clone --depth 1 --branch v9.x-binary https://github.com/limine-bootloader/limine.git {{limine_dir}}
        make -C {{limine_dir}}
    fi

create-nvme-disk:
    #!/usr/bin/env bash
    if [ ! -f "{{nvme_disk}}" ]; then
        ROOT="$(pwd)"
        cd /tmp
        cargo run --manifest-path "$ROOT/Cargo.toml" -p lancer-lancerfs --no-default-features --features host --target x86_64-unknown-linux-gnu --bin mkfs_host -- "$ROOT/{{nvme_disk}}" 64M
    fi

format-nvme-disk:
    #!/usr/bin/env bash
    ROOT="$(pwd)"
    rm -f "{{nvme_disk}}"
    cd /tmp
    cargo run --manifest-path "$ROOT/Cargo.toml" -p lancer-lancerfs --no-default-features --features host --target x86_64-unknown-linux-gnu --bin mkfs_host -- "$ROOT/{{nvme_disk}}" 64M

ovmf-setup:
    #!/usr/bin/env bash
    mkdir -p "$(dirname "{{ovmf_vars}}")"
    cp "{{ovmf_vars_src}}" "{{ovmf_vars}}"

iso: build limine-fetch
    #!/usr/bin/env bash
    set -euo pipefail
    rm -rf {{iso_dir}}
    mkdir -p {{iso_dir}}/boot/limine {{iso_dir}}/EFI/BOOT
    cp {{kernel_bin}} {{iso_dir}}/boot/kernel
    for entry in {{boot_modules}}; do
        bin="${entry%%:*}"
        name="${entry##*:}"
        src="{{target_dir}}/${bin}"
        if [ -f "$src" ]; then
            cp "$src" "{{iso_dir}}/boot/${name}"
        fi
    done
    cp limine.conf {{iso_dir}}/boot/limine/limine.conf
    cp {{limine_dir}}/limine-bios.sys {{iso_dir}}/boot/limine/
    cp {{limine_dir}}/limine-bios-cd.bin {{iso_dir}}/boot/limine/
    cp {{limine_dir}}/limine-uefi-cd.bin {{iso_dir}}/boot/limine/
    cp {{limine_dir}}/BOOTX64.EFI {{iso_dir}}/EFI/BOOT/
    cp {{limine_dir}}/BOOTIA32.EFI {{iso_dir}}/EFI/BOOT/
    xorriso -as mkisofs \
        -b boot/limine/limine-bios-cd.bin \
        -no-emul-boot -boot-load-size 4 -boot-info-table \
        --efi-boot boot/limine/limine-uefi-cd.bin \
        -efi-boot-part --efi-boot-image --protective-msdos-label \
        {{iso_dir}} -o {{iso_file}}
    {{limine_dir}}/limine bios-install {{iso_file}}

run: iso ovmf-setup create-nvme-disk
    qemu-system-x86_64 \
        -M q35,accel=kvm:tcg,kernel-irqchip=split \
        -cpu host \
        -m 1G \
        -drive if=pflash,format=raw,readonly=on,file={{ovmf_code}} \
        -drive if=pflash,format=raw,file={{ovmf_vars}} \
        -cdrom {{iso_file}} \
        -device intel-iommu,intremap=on,caching-mode=on \
        -device virtio-net-pci,netdev=net0,iommu_platform=on,disable-legacy=on \
        -netdev user,id=net0,hostfwd=tcp::2222-:7,hostfwd=tcp::2323-:22,hostfwd=udp::5001-:5001 \
        -drive file={{nvme_disk}},if=none,id=nvm,format=raw \
        -device nvme,serial=lancernvme,drive=nvm \
        -serial stdio \
        -display gtk \
        -no-reboot \
        -no-shutdown

run-tap: iso ovmf-setup create-nvme-disk
    qemu-system-x86_64 \
        -M q35,accel=kvm:tcg,kernel-irqchip=split \
        -cpu host \
        -m 1G \
        -drive if=pflash,format=raw,readonly=on,file={{ovmf_code}} \
        -drive if=pflash,format=raw,file={{ovmf_vars}} \
        -cdrom {{iso_file}} \
        -device intel-iommu,intremap=on,caching-mode=on \
        -device virtio-net-pci,netdev=net0,iommu_platform=on,disable-legacy=on \
        -netdev tap,id=net0,ifname=tap-lancer,script=no,downscript=no \
        -drive file={{nvme_disk}},if=none,id=nvm,format=raw \
        -device nvme,serial=lancernvme,drive=nvm \
        -serial stdio \
        -display gtk \
        -no-reboot \
        -no-shutdown

run-bios: iso
    qemu-system-x86_64 \
        -M q35,accel=kvm:tcg \
        -cpu host \
        -m 1G \
        -cdrom {{iso_file}} \
        -serial stdio \
        -display none \
        -no-reboot \
        -no-shutdown

debug: iso ovmf-setup create-nvme-disk
    qemu-system-x86_64 \
        -M q35,accel=kvm:tcg,kernel-irqchip=split \
        -cpu host \
        -m 1G \
        -drive if=pflash,format=raw,readonly=on,file={{ovmf_code}} \
        -drive if=pflash,format=raw,file={{ovmf_vars}} \
        -cdrom {{iso_file}} \
        -device intel-iommu,intremap=on,caching-mode=on \
        -device virtio-net-pci,netdev=net0,iommu_platform=on,disable-legacy=on \
        -netdev user,id=net0 \
        -drive file={{nvme_disk}},if=none,id=nvm,format=raw \
        -device nvme,serial=lancernvme,drive=nvm \
        -serial stdio \
        -display none \
        -no-reboot \
        -no-shutdown \
        -s -S

test-kernel: limine-fetch
    ./scripts/run-kernel-tests.sh

test-host:
    #!/usr/bin/env bash
    set -euo pipefail
    ROOT="$(pwd)"
    cd /tmp
    cargo test --manifest-path "$ROOT/Cargo.toml" -p lancer-core --target x86_64-unknown-linux-gnu
    cargo test --manifest-path "$ROOT/Cargo.toml" -p lancer-lancerfs --target x86_64-unknown-linux-gnu --no-default-features

test-host-lancerfs:
    #!/usr/bin/env bash
    set -euo pipefail
    ROOT="$(pwd)"
    cd /tmp
    cargo test --manifest-path "$ROOT/Cargo.toml" -p lancer-lancerfs --target x86_64-unknown-linux-gnu --no-default-features

test: test-host test-kernel

prove-kani:
    #!/usr/bin/env bash
    set -euo pipefail
    ROOT="$(pwd)"
    cd /tmp
    cargo kani --manifest-path "$ROOT/lib/lancer-core/Cargo.toml"

prove-verus:
    #!/usr/bin/env bash
    set -euo pipefail
    ROOT="$(pwd)"
    export PATH="/tmp/verus-x86-linux:$PATH"
    cd /tmp
    cargo verus verify --manifest-path "$ROOT/lib/lancer-proofs/Cargo.toml"

prove: prove-kani prove-verus

test-integration: limine-fetch
    ./scripts/run-integration-tests.sh
