# shellcheck shell=sh disable=SC2046,SC2091,SC2086,SC2155
# NOTE: $(VAR) in this file is MAKE syntax, not shell substitution.
export TARGET=x86_64-unknown-uefi
export PROFILE=debug
export OUT_DIR=target/$(TARGET)/$(PROFILE)
export ESP_DIR=esp
export KERNEL=$(OUT_DIR)/rsdos.efi
export BZIMAGE=$(ESP_DIR)/bzImage
export INITRD=$(ESP_DIR)/initramfs.cpio.gz
export BOOTLOADER=rsboot/rsboot.efi
export OVMF=/usr/share/edk2/x64/OVMF.4m.fd
export BOOT_EFI=$(ESP_DIR)/EFI/BOOT/BOOTX64.EFI
# Attach a raw disk image as the SATA drive (disk.img -> ide.0, ESP -> ide.1).
# Create one with: make disk   (or: ./scripts/mkdisk.sh)
export DISK_IMG ?= /tmp/disk.img

.PHONY: all run run-gui clean image debug release fmt bootloader boot-image disk disk-fresh inspect test-disk test-mouse test-gfx test-fault test-msg

# ---- Build ---------------------------------------------------------------

all: $(BZIMAGE) $(INITRD)

release: PROFILE=release
release: export PROFILE=release
release: export OUT_DIR=target/$(TARGET)/release
release: CARGO_FLAGS=--release
release: all

# shellcheck disable=SC2034
CARGO_FLAGS=

$(OUT_DIR)/rsdos.efi: $(shell find rsnix shell rsdos -name '*.rs') Cargo.toml rsnix/Cargo.toml shell/Cargo.toml rsdos/Cargo.toml
	cargo build --package rsdos --target $(TARGET) $(CARGO_FLAGS)

$(BZIMAGE): $(KERNEL) | $(ESP_DIR)
	cp "$<" "$@"

$(ESP_DIR):
	mkdir -p $(ESP_DIR)

$(INITRD): | $(ESP_DIR)
	printf '' | gzip > "$@"

# ---- QEMU runners --------------------------------------------------------

run: all disk
	qemu-system-x86_64 \
	  -bios $(OVMF) \
	  -drive file=$(DISK_IMG),format=raw,if=none,id=disk \
	  -device ide-hd,drive=disk,bus=ide.0 \
	  -drive file=fat:rw:$(ESP_DIR),format=raw,if=none,id=esp \
	  -device ide-hd,drive=esp,bus=ide.1 \
	  -serial stdio \
	  -m 256M \
	  -machine q35 \
	  -cpu qemu64 \
	  -no-reboot \
	  -display none

run-gui: all disk
	qemu-system-x86_64 \
	  -bios $(OVMF) \
	  -drive file=$(DISK_IMG),format=raw,if=none,id=disk \
	  -device ide-hd,drive=disk,bus=ide.0 \
	  -drive file=fat:rw:$(ESP_DIR),format=raw,if=none,id=esp \
	  -device ide-hd,drive=esp,bus=ide.1 \
	  -serial stdio \
	  -m 256M \
	  -machine q35 \
	  -cpu qemu64 \
	  -no-reboot \
	  -vga std

# GDB stub on :1234
debug: all disk
	qemu-system-x86_64 \
	  -bios $(OVMF) \
	  -drive file=$(DISK_IMG),format=raw,if=none,id=disk \
	  -device ide-hd,drive=disk,bus=ide.0 \
	  -drive file=fat:rw:$(ESP_DIR),format=raw,if=none,id=esp \
	  -device ide-hd,drive=esp,bus=ide.1 \
	  -serial stdio \
	  -m 256M \
	  -machine q35 \
	  -cpu qemu64 \
	  -no-reboot \
	  -display none \
	  -s -S

# Boot from a raw disk image (delegates to boot-image.sh which builds the
# full chain if the image doesn't exist yet)
run-image: all
	./scripts/boot-image.sh rs-dos.img

# ---- Data disk -----------------------------------------------------------

# Create the FAT32 data disk if it doesn't exist.  Uses mkfs.fat -C (the
# flag that actually creates the file) and seeds it from seed/.
disk:
	./scripts/mkdisk.sh "$(DISK_IMG)"

# Re-format the data disk from scratch (wipes it, then re-seeds).
disk-fresh:
	./scripts/mkdisk.sh --fresh "$(DISK_IMG)"

# List the data disk contents with mtools (requires mtools).
inspect:
	@command -v mdir >/dev/null 2>&1 || (echo "inspect needs mtools: sudo apt install mtools"; exit 1)
	@mdir -i "$(DISK_IMG)"

# Full automated round trip: build -> boot -> shell commands -> poweroff
# -> fsck + mtools verification.
test-disk:
	./scripts/test-disk.sh

# Automated PS/2 mouse round trip: boot -> inject mouse_move/mouse_button
# via the monitor -> verify /dev/mouse + the `mouse` stream -> poweroff.
test-mouse:
	./scripts/test-mouse.sh

test-gfx:
	./scripts/test-gfx.sh

# Fault-diagnostics round trip: boot -> `fault` (deliberate page fault) ->
# verify the full dump (vec/err/rip/cr2/task) hits serial + screen -> halt.
test-fault:
	./scripts/test-fault.sh

# Automated scheduler message-queue round trip: msgrecv/send, real-input
# routing into a task's queue, queue-full boundary.
test-msg:
	./scripts/test-msg.sh

# ---- Full boot chain -----------------------------------------------------

# Build bootloader only (rsboot submodule)
bootloader:
	./scripts/build-bootloader.sh

# Build the full boot chain disk image (kernel + bootloader)
image: all
	./scripts/build-image.sh rs-dos.img

# Boot the full chain disk image (builds it first if needed)
boot-image: all
	./scripts/boot-image.sh rs-dos.img

# ---- Utilities -----------------------------------------------------------

fmt:
	cargo fmt

clean:
	cargo clean
	rm -rf $(ESP_DIR) rs-dos.img

help:
	@echo "rs-dos — Make targets"
	@echo ""
	@echo "  make                build kernel + ESP (default)"
	@echo "  make release        build with --release (smaller binary)"
	@echo "  make bootloader     build rsboot from source"
	@echo "  make image          build full chain disk image (bootloader + kernel)"
	@echo "  make boot-image     build + boot full chain via QEMU"
	@echo "  make run            QEMU serial console (direct boot, no bootloader)"
	@echo "  make run-gui        QEMU with graphical window (GOP/PS2)"
	@echo "  make debug          QEMU + GDB stub on :1234"
	@echo "  make disk           create the data disk if missing (default /tmp/disk.img)"
	@echo "  make disk-fresh     re-format the data disk (wipes it)"
	@echo "  make inspect        list data disk contents (mtools)"
	@echo "  make test-disk      automated disk round trip (build->boot->fsck)"
	@echo "  make clean          remove build artifacts"
	@echo "  make fmt            format Rust source"
	@echo ""
	@echo "Scripts:"
	@echo "  ./scripts/boot.sh              quick direct boot (dev loop)"
	@echo "  ./scripts/mkdisk.sh            create/re-format the data disk"
	@echo "  ./scripts/test-disk.sh         automated disk round trip"
	@echo "  ./scripts/sendkeys.py          type into QEMU via the monitor"
	@echo "  ./scripts/boot-image.sh        boot full chain (builds if needed)"
	@echo "  ./scripts/build-image.sh       build full chain disk image"
	@echo "  ./scripts/build-bootloader.sh  build rsboot from source"
	@echo "  ./scripts/qemu.sh              flexible QEMU launcher"
	@echo "  ./scripts/debug-kernel.py      GDB plugin (attach after 'make debug')"
