CC       := gcc
CFLAGS   := -O3 -fPIC -Wall -Wextra
LDFLAGS  := -shared

# ---- paths ----
SRCDIRS  := engine/src engine/src/ai
INCDIRS  := engine/include
BUILDDIR := build
LIBNAME  := libchess
LIB      := $(BUILDDIR)/$(LIBNAME).so

# ---- sources/objects ----
EXCLUDE  := engine/src/test.c
SRCS     := $(foreach d,$(SRCDIRS),$(wildcard $(d)/*.c))
SRCS     := $(filter-out $(EXCLUDE),$(SRCS))
OBJS     := $(patsubst %.c,$(BUILDDIR)/%.o,$(SRCS))

# ---- includes ----
INCLUDES := $(addprefix -I,$(INCDIRS))

# ---- test executable (engine/src/test.c) ----
TESTSRC  := engine/src/test.c
TESTOBJ  := $(BUILDDIR)/engine/src/test.o
TESTBIN  := $(BUILDDIR)/print_board

# ---- runner (python) ----
PYTHON     := python3
RUN_SCRIPT := scripts/simulation.py
ARGS       ?=

.PHONY: all clean test test-exe run-c-test run-engine

all: $(LIB)

# generic object rule: build/<path>/file.o from <path>/file.c
$(BUILDDIR)/%.o: %.c
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(LIB): $(OBJS)
	@mkdir -p $(dir $@)
	$(CC) $(LDFLAGS) -o $@ $^

# ---- test exe rules ----
test-exe: $(TESTBIN)

$(TESTOBJ): $(TESTSRC)
	@mkdir -p $(dir $@)
	$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@

$(TESTBIN): $(TESTOBJ) $(LIB)
	$(CC) -O2 -o $@ $(TESTOBJ) -L$(BUILDDIR) -lchess -Wl,-rpath,'$$ORIGIN'

run-c-test: $(TESTBIN)
	LD_LIBRARY_PATH=$(BUILDDIR) $(TESTBIN) $(FEN)

# ---- run engine (Python) ----
# Usage: make run-engine ARGS="--fen '...' --depth 5"
run-engine: $(LIB)
	@echo "Running engine via $(RUN_SCRIPT)"
	LD_LIBRARY_PATH=$(BUILDDIR) $(PYTHON) $(RUN_SCRIPT) $(ARGS)

clean:
	@echo "Cleaning build and Python caches..."
	@rm -rf $(BUILDDIR)
	@find . -type d -name "__pycache__"    -exec rm -rf {} +
	@find . -type d -name ".pytest_cache"  -exec rm -rf {} +
	@find . -type f \( -name "*.pyc" -o -name "*.pyo" \) -delete

test:
	@$(MAKE) clean
	@$(MAKE) all
	@python3 -m unittest -v; \
	status=$$?; \
	$(MAKE) clean; \
	exit $$status
