# ==============================================================================
# 1. PROJECT CONFIGURATION
# ==============================================================================
BIN_TARGET := CometOS.bin
TARGET     := CometOS.iso
BUILD_DIR  := build
LDSCRIPT   := linker.ld

# Toolchain definitions
CXX        := g++
ASM        := as
LD         := ld

# Compiler and Linker Flags
ASMFLAGS   := --32
CXXFLAGS   := -Wall -Wextra -O3 -m32 -fno-use-cxa-atexit -nostdlib -fno-builtin -fno-rtti -fno-exceptions -fno-leading-underscore
LDFLAGS    := -T $(LDSCRIPT) -melf_i386

# ==============================================================================
# 2. FILE SEARCH AND COMPONENT SETUP
# ==============================================================================
# Find all source files recursively in the current folder and subfolders
SRCS      := $(wildcard src/**/*.cpp src/**/*.S)

# Strip paths and convert extensions to .o (e.g., "src/main.cpp" -> "main.o")
RAW_OBJS  := $(patsubst %.cpp,%.o,$(patsubst %.S,%.o,$(notdir $(SRCS))))

# Place all object files into the build directory
OBJS      := $(addprefix $(BUILD_DIR)/, $(RAW_OBJS))

# Automagically tell Make where to find the original source files
VPATH     := $(sort $(dir $(SRCS)))

# ==============================================================================
# 3. BUILD RULES
# ==============================================================================
.PHONY: all clean run

# Default rule
all: $(TARGET)

run: $(TARGET)
	qemu-system-i386 -cdrom $(TARGET) -m 1024

# Link rule: Combines all objects using the linker script
$(BIN_TARGET): $(OBJS) $(LDSCRIPT)
	$(LD) $(OBJS) $(LDFLAGS) -o $@
	@echo "Build successful: $(BIN_TARGET)"

$(TARGET): $(BIN_TARGET)
	@mkdir iso/boot/grub -p
	@cp $< iso/boot/
	@echo 'set default=0' > iso/boot/grub/grub.cfg
	@echo 'set timeout=0' >> iso/boot/grub/grub.cfg
	@echo '' >> iso/boot/grub/grub.cfg
	@echo 'menuentry "CometOS" {' >> iso/boot/grub/grub.cfg
	@echo '    multiboot /boot/CometOS.bin' >> iso/boot/grub/grub.cfg
	@echo '    boot' >> iso/boot/grub/grub.cfg
	@echo '}' >> iso/boot/grub/grub.cfg
	grub-mkrescue --output=$@ iso

# Compilation rule for C++ files
$(BUILD_DIR)/%.o: %.cpp | $(BUILD_DIR)
	$(CXX) $(CXXFLAGS) -c $< -o $@

# Compilation rule for Assembly files
$(BUILD_DIR)/%.o: %.S | $(BUILD_DIR)
	$(ASM) $(ASMFLAGS) -c $< -o $@

# Safely create the build directory if it doesn't exist
$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)

# Cleanup rule
clean:
	rm -rf $(BUILD_DIR) $(BIN_TARGET) $(TARGET)
	@echo "Cleaned up build files."
