# Open-IOV Top-Level Build System
# Builds: kernel module (open-iov-vfio.ko), userspace lib (open-iov.so), examples, tests

SHELL := /bin/bash

# Directories
KERNEL_DIR := kernel
DRIVER_DIR := driver
USERSPACE_DIR := userspace
FIRMWARE_DIR := firmware/57X-GSP/570.144

# Kernel module
KERNEL_MODULE := open-iov-vfio.ko
KERNEL_MODULE_SRC := $(KERNEL_DIR)/$(KERNEL_MODULE)

# Userspace library
USERSPACE_LIB := libiov.so
USERSPACE_LIB_SRC := $(USERSPACE_DIR)/lib/$(USERSPACE_LIB)
USERSPACE_LIB_LINK := $(USERSPACE_DIR)/lib/libvgpu.so  # compat symlink

# Examples
EXAMPLES := example_vgpu

# Default target
.PHONY: all kernel userspace examples tests clean install firmware-check help

all: kernel userspace examples

help:
	@echo "Open-IOV Build System"
	@echo ""
	@echo "Targets:"
	@echo "  all           - Build kernel module, userspace library, examples"
	@echo "  kernel        - Build open-iov-vfio.ko"
	@echo "  userspace     - Build open-iov.so and libvgpu.so compat link"
	@echo "  examples      - Build example applications"
	@echo "  tests         - Build kernel and userspace tests"
	@echo "  clean         - Clean all build artifacts"
	@echo "  install       - Install kernel module and userspace library"
	@echo "  firmware-check - Verify GSP firmware exists"
	@echo ""

# Kernel module build
kernel: $(KERNEL_MODULE_SRC)

$(KERNEL_MODULE_SRC): firmware-check
	$(MAKE) -C $(KERNEL_DIR)

# Userspace library build
userspace: $(USERSPACE_LIB_SRC) $(USERSPACE_LIB_LINK)

$(USERSPACE_LIB_SRC):
	$(MAKE) -C $(USERSPACE_DIR)/lib

$(USERSPACE_LIB_LINK): $(USERSPACE_LIB_SRC)
	@ln -sf $(USERSPACE_LIB) $(USERSPACE_DIR)/lib/libvgpu.so
	@ln -sf $(USERSPACE_LIB) $(USERSPACE_DIR)/lib/libvgpu.so.1
	@ln -sf $(USERSPACE_LIB) $(USERSPACE_DIR)/lib/libvgpu.so.1.0.0

# Examples build
examples: userspace
	$(MAKE) -C $(USERSPACE_DIR)/examples

# Tests build
tests: kernel userspace
	$(MAKE) -C $(KERNEL_DIR)/tests
	$(MAKE) -C $(USERSPACE_DIR)/tests

# Firmware check
firmware-check:
	@if [ ! -f $(FIRMWARE_DIR)/gsp-570.144.fwimage.bin ]; then \
		echo "ERROR: GSP firmware not found at $(FIRMWARE_DIR)/gsp-570.144.fwimage.bin"; \
		exit 1; \
	fi
	@echo "Firmware OK: $(FIRMWARE_DIR)/gsp-570.144.fwimage.bin"

# Clean
clean:
	$(MAKE) -C $(KERNEL_DIR) clean
	$(MAKE) -C $(DRIVER_DIR) clean
	$(MAKE) -C $(USERSPACE_DIR)/lib clean
	$(MAKE) -C $(USERSPACE_DIR)/examples clean
	$(MAKE) -C $(USERSPACE_DIR)/tests clean
	$(MAKE) -C $(KERNEL_DIR)/tests clean
	@rm -f $(USERSPACE_DIR)/lib/libvgpu.so*

# Install
install: kernel userspace
	# Install kernel module
	$(MAKE) -C $(KERNEL_DIR) install
	# Install userspace library
	install -D -m 755 $(USERSPACE_DIR)/lib/$(USERSPACE_LIB) /usr/local/lib/$(USERSPACE_LIB)
	ldconfig
	# Install headers
	install -D -m 644 $(USERSPACE_DIR)/include/libvgpu.h /usr/local/include/libvgpu.h
	# Create compat symlinks
	ln -sf $(USERSPACE_LIB) /usr/local/lib/libvgpu.so
	ln -sf $(USERSPACE_LIB) /usr/local/lib/libvgpu.so.1
	ln -sf $(USERSPACE_LIB) /usr/local/lib/libvgpu.so.1.0.0
	# Install pkg-config files
	install -D -m 644 $(USERSPACE_DIR)/lib/libvgpu.pc /usr/local/lib/pkgconfig/libvgpu.pc
	install -D -m 644 $(USERSPACE_DIR)/lib/libiov.pc /usr/local/lib/pkgconfig/libiov.pc

# Load kernel module (requires root)
load: kernel firmware-check
	sudo cp $(FIRMWARE_DIR)/gsp-570.144.fwimage.bin /lib/firmware/
	sudo insmod $(KERNEL_MODULE_SRC)

# Unload kernel module
unload:
	-sudo rmmod open-iov-vfio

# Reload kernel module
reload: unload load

# Run example
run-example: examples load
	sudo LD_LIBRARY_PATH=$(USERSPACE_DIR)/lib ./$(USERSPACE_DIR)/examples/example_vgpu /dev/open-iov

# Debug kernel module
debug-kernel:
	@echo "Kernel module info:"
	@modinfo $(KERNEL_MODULE_SRC)

# Check kernel module symbols
check-symbols: kernel
	@nm $(KERNEL_MODULE_SRC) | grep -E "(vgpu|gsp|bar|wpr|migration)" | head -50

.PHONY: load unload reload run-example debug-kernel check-symbols