USER_PROGRAMS := pedicel.raw apex.raw doom.raw
USER_FILES := wow.txt doom1.wad

BUILDDIR := build
ELFFILE := pepperk
SRC := src

CC_PROBLEMATIC_FLAGS:=-Wno-unused-parameter -Wno-unused-variable

ifeq ($(UBSAN),true)
SOURCES := $(shell find src -name '*.c')
CC_PROBLEMATIC_FLAGS:= -fsanitize=undefined
else
SOURCES := $(shell find src -name '*.c')
SOURCES := $(filter-out src/security/ubsan.c, $(SOURCES))
endif

OBJFILES := $(patsubst $(SRC)/%.c, $(BUILDDIR)/%.o, $(SOURCES))

CC := x86_64-elf-gcc
CC_FLAGS=-Wall -Wextra -std=gnu99 -nostdlib -ffreestanding -fstack-protector -fno-omit-frame-pointer -fno-stack-check -fno-PIC -ffunction-sections -fdata-sections -mcmodel=kernel -mno-red-zone

LD := x86_64-elf-ld

$(ELFFILE): $(BUILDDIR) $(OBJFILES)
	nasm -f elf64 src/arch/x86/idt.S -o $(BUILDDIR)/idt_stub.o
	$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o
	# Get the symbols for debugging
	nm -n $(ELFFILE) | awk '$$2 ~ /[TtDdBbRr]/ {print $$1, $$3}' > symbols.map
	python3 symbols.py
	nasm -f elf64 symbols.S -o $(BUILDDIR)/symbols.o
	$(LD) -o $(ELFFILE) -T linker.ld $(OBJFILES) $(BUILDDIR)/idt_stub.o $(BUILDDIR)/symbols.o

$(BUILDDIR):
	@mkdir -p $(BUILDDIR)

$(BUILDDIR)/%.o: $(SRC)/%.c
	mkdir -p $(dir $@)
	$(CC) -g -c -Iinclude $< $(CC_PROBLEMATIC_FLAGS) $(CC_FLAGS) -o $@

limine/limine:
	rm -rf limine
	git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1
	$(MAKE) -C limine

.PHONY: user
user:
	$(MAKE) -C user
	tar cvf $(BUILDDIR)/initfs.tar -C $(BUILDDIR) $(USER_PROGRAMS) -C ../user $(USER_FILES)

build-iso: limine/limine $(ELFFILE)
	rm -rf iso_root
	mkdir -p iso_root/boot
	cp -v $(ELFFILE) iso_root/boot
	mkdir -p iso_root/boot/limine
	cp -v limine.conf iso_root/boot/limine
	cp $(BUILDDIR)/initfs.tar iso_root/boot/
	mkdir -p iso_root/EFI/BOOT
	cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/
	cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/
	cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/
	xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \
		-no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \
		-apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \
		-efi-boot-part --efi-boot-image --protective-msdos-label \
		iso_root -o pepper.iso
	./limine/limine bios-install pepper.iso

.PHONY: debug
debug:
	/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -D qemu.log -no-reboot -no-shutdown &
	gdb $(ELFFILE) --command=debug.gdb

.PHONY: debug2
debug2:
	/usr/bin/qemu-system-x86_64 -drive file=pepper.iso -s -S -d int -no-reboot -no-shutdown &
	pwndbg $(ELFFILE) --command=debug.gdb

.PHONY: run
run: build-iso
	/usr/bin/qemu-system-x86_64 -cdrom pepper.iso -serial stdio

.PHONY: clean
clean:
	rm -rf $(BUILDDIR) symbols.map symbols.S $(ELFFILE) iso_root pepper.iso limine
