# ──────────────────────────────────────────────────────────────
#  Makefile  —  opencoreRS build system
# ──────────────────────────────────────────────────────────────

ARCH        := x86_64
TARGET      := x86_64-unknown-none
PROFILE     := debug
KERNEL_ELF  := target/$(TARGET)/$(PROFILE)/kernel
INIT_ELF    := target/$(TARGET)/$(PROFILE)/init
VFS_ELF     := target/$(TARGET)/$(PROFILE)/vfs
SH_ELF      := target/$(TARGET)/$(PROFILE)/sh

QEMU        := qemu-system-x86_64
QEMU_FLAGS  := \
	-machine q35,i8042=on \
	-m 256M \
	-smp 2 \
	-netdev user,id=net0 \
	-device e1000,netdev=net0 \
	-device ahci,id=ahci0 \
	-serial mon:stdio \
	-display none \
	-no-reboot \
	-no-shutdown

# Limine bootloader paths
LIMINE_DIR  := limine
LIMINE_BIN  := $(LIMINE_DIR)/limine
HDD_IMAGE   := opencoreRS.hdd
ISO_DIR     := iso_root
ISO_IMAGE   := opencoreRS.iso

.PHONY: all kernel init-server vfs-server sh-server check check-all clean run hdd iso limine-install help

## Сборка ядра и userspace серверов
all: hdd

kernel:
	@echo "  BUILD   kernel ($(PROFILE))"
	cargo rustc -p kernel --target $(TARGET) \
		$(if $(filter release,$(PROFILE)),--release,) \
		-- -C link-arg=-Tkernel/linker.ld -C code-model=kernel -C relocation-model=static

init-server:
	@echo "  BUILD   init server ($(PROFILE))"
	cargo rustc -p init --target $(TARGET) \
		$(if $(filter release,$(PROFILE)),--release,) \
		-- -C link-arg=-Tservers/init/user.ld -C code-model=small -C relocation-model=static

vfs-server:
	@echo "  BUILD   vfs server ($(PROFILE))"
	cargo rustc -p vfs --target $(TARGET) \
		$(if $(filter release,$(PROFILE)),--release,) \
		-- -C link-arg=-Tservers/vfs/user.ld -C code-model=small -C relocation-model=static

sh-server:
	@echo "  BUILD   sh server ($(PROFILE))"
	cargo rustc -p sh --target $(TARGET) \
		$(if $(filter release,$(PROFILE)),--release,) \
		-- -C link-arg=-Tservers/sh/user.ld -C code-model=small -C relocation-model=static

## Проверка без сборки бинарника
check:
	@echo "  CHECK   kernel"
	cargo check -p kernel --target $(TARGET)

## Проверка всего workspace (серверы, libs)
check-all:
	@echo "  CHECK   workspace (servers / libs)"
	cargo check --target $(TARGET) \
		-p syscall-abi -p ipc-client -p init -p vfs -p sh

## Клонирование / сборка Limine
limine-install:
	@if [ ! -d "$(LIMINE_DIR)" ]; then \
		git clone https://github.com/limine-bootloader/limine.git \
			--branch=v8.x-binary --depth=1 $(LIMINE_DIR); \
	fi
	$(MAKE) -C $(LIMINE_DIR)

## Создание bootable HDD образа (MBR + FAT32 + Limine)
hdd: kernel init-server vfs-server sh-server limine-install
	@echo "  IMAGE   $(HDD_IMAGE)"
	@rm -f $(HDD_IMAGE)
	dd if=/dev/zero of=$(HDD_IMAGE) bs=1M count=64 status=none
	parted -s $(HDD_IMAGE) mklabel msdos
	parted -s $(HDD_IMAGE) mkpart primary fat32 2048s 100%
	parted -s $(HDD_IMAGE) set 1 boot on
	mformat -i $(HDD_IMAGE)@@1M -F
	mmd -i $(HDD_IMAGE)@@1M ::/boot ::/boot/limine ::/limine ::/EFI ::/EFI/BOOT
	mcopy -i $(HDD_IMAGE)@@1M $(KERNEL_ELF) ::/boot/kernel.elf
	mcopy -i $(HDD_IMAGE)@@1M $(INIT_ELF) ::/boot/init.elf
	mcopy -i $(HDD_IMAGE)@@1M $(VFS_ELF) ::/boot/vfs.elf
	mcopy -i $(HDD_IMAGE)@@1M $(SH_ELF) ::/boot/sh.elf
	mcopy -i $(HDD_IMAGE)@@1M config/limine.conf ::/boot/limine/limine.conf
	mcopy -i $(HDD_IMAGE)@@1M config/limine.conf ::/limine.conf
	mcopy -i $(HDD_IMAGE)@@1M config/limine.cfg ::/boot/limine/limine.cfg
	mcopy -i $(HDD_IMAGE)@@1M config/limine.cfg ::/limine.cfg
	mcopy -i $(HDD_IMAGE)@@1M $(LIMINE_DIR)/limine-bios.sys ::/boot/limine/limine-bios.sys
	mcopy -i $(HDD_IMAGE)@@1M $(LIMINE_DIR)/limine-bios.sys ::/limine-bios.sys
	mcopy -i $(HDD_IMAGE)@@1M $(LIMINE_DIR)/BOOTX64.EFI ::/EFI/BOOT/BOOTX64.EFI
	$(LIMINE_BIN) bios-install $(HDD_IMAGE)

## Запуск в QEMU (интерактивная консоль прямо в терминале)
run: hdd
	@echo "  QEMU    $(HDD_IMAGE) (Выход: Ctrl+A затем X)"
	$(QEMU) -machine pc -m 256M -smp 2 -netdev user,id=net0 -device e1000,netdev=net0 -device ahci,id=ahci0 -drive file=$(HDD_IMAGE),format=raw -serial mon:stdio -display none -no-reboot -no-shutdown

## Запуск в QEMU с графическим дисплеем (GUI + Framebuffer)
run-gui: hdd
	@echo "  QEMU GUI $(HDD_IMAGE) (Кликните в окно или Ctrl+Alt+G для захвата клавиатуры)"
	$(QEMU) -machine pc -m 256M -smp 2 -netdev user,id=net0 -device e1000,netdev=net0 -device ahci,id=ahci0 -drive file=$(HDD_IMAGE),format=raw -serial mon:stdio -k en-us

## Запуск в Bochs эмуляторе
run-bochs: hdd
	@echo "  BOCHS   $(HDD_IMAGE)"
	@rm -f $(HDD_IMAGE).lock
	bochs -q -unlock -f bochsrc.txt

clean:
	cargo clean
	rm -rf $(ISO_DIR) $(ISO_IMAGE) $(HDD_IMAGE)

help:
	@echo "opencoreRS build targets:"
	@echo "  make hdd           — собрать bootable HDD образ"
	@echo "  make run           — запустить в QEMU"
	@echo "  make kernel        — собрать ELF ядра"
	@echo "  make init-server   — собрать ELF init сервера"
	@echo "  make vfs-server    — собрать ELF vfs сервера"
	@echo "  make sh-server     — собрать ELF userspace shell"
	@echo "  make check         — cargo check ядра"
	@echo "  make clean         — очистить артефакты"
