CXX      ?= g++
CXXSTD   := -std=c++20
WARN     := -Wall -Wextra -Wshadow
INC      := -I.

BUILD    := build

RELEASE_FLAGS := -O3 -march=native -DNDEBUG -flto
DEBUG_FLAGS   := -O0 -g3 -fsanitize=address,undefined -fno-omit-frame-pointer

ENGINE_LIB_SRC := $(filter-out engine/main.cpp,$(wildcard engine/*.cpp))
TEST_SRC       := $(wildcard tests/*.cpp)
ENGINE_MAIN    := $(wildcard engine/main.cpp)

.PHONY: all test debug-test engine benchmark arena pgo debug-engine clean

all: engine

# ---------- Release ----------
$(BUILD)/release/%.o: %.cpp
	@mkdir -p $(dir $@)
	$(CXX) $(CXXSTD) $(RELEASE_FLAGS) $(WARN) $(INC) -c $< -o $@

$(BUILD)/gomoku_tests: $(ENGINE_LIB_SRC) $(TEST_SRC)
	@mkdir -p $(BUILD)
	$(CXX) $(CXXSTD) $(RELEASE_FLAGS) $(WARN) $(INC) $^ -o $@

engine: $(BUILD)/gomoku_engine

$(BUILD)/gomoku_engine: $(ENGINE_LIB_SRC) $(ENGINE_MAIN)
	@mkdir -p $(BUILD)
	$(CXX) $(CXXSTD) $(RELEASE_FLAGS) $(WARN) $(INC) $^ -o $@
	@echo "built $@"

benchmark: engine
	@$(BUILD)/gomoku_engine benchmark

# Profile-guided build (no source change -> identical results, just faster).
PGO_DIR := $(BUILD)/pgo
pgo:
	@mkdir -p $(PGO_DIR)
	$(CXX) $(CXXSTD) -O3 -march=native -DNDEBUG -fprofile-generate=$(PGO_DIR) $(WARN) $(INC) \
	    $(ENGINE_LIB_SRC) $(ENGINE_MAIN) -o $(PGO_DIR)/gomoku_engine
	@echo "training pgo profile..."
	@$(PGO_DIR)/gomoku_engine benchmark --threads=1 >/dev/null 2>&1 || true
	@$(PGO_DIR)/gomoku_engine benchmark --threads=2 >/dev/null 2>&1 || true
	@$(PGO_DIR)/gomoku_engine benchmark >/dev/null 2>&1 || true
	$(CXX) $(CXXSTD) -O3 -march=native -DNDEBUG -fprofile-use=$(PGO_DIR) -fprofile-correction \
	    -Wno-missing-profile $(WARN) $(INC) $(ENGINE_LIB_SRC) $(ENGINE_MAIN) -o $(BUILD)/gomoku_engine
	@echo "built PGO engine -> $(BUILD)/gomoku_engine"

test: $(BUILD)/gomoku_tests
	@$(BUILD)/gomoku_tests

arena: $(BUILD)/gomoku_arena

$(BUILD)/gomoku_arena: $(ENGINE_LIB_SRC) tools/arena.cpp
	@mkdir -p $(BUILD)
	$(CXX) $(CXXSTD) $(RELEASE_FLAGS) $(WARN) $(INC) $^ -o $@
	@echo "built $@"

# ---------- Debug (ASan + UBSan) ----------
$(BUILD)/debug/gomoku_tests: $(ENGINE_LIB_SRC) $(TEST_SRC)
	@mkdir -p $(dir $@)
	$(CXX) $(CXXSTD) $(DEBUG_FLAGS) $(WARN) $(INC) $^ -o $@

debug-test: $(BUILD)/debug/gomoku_tests
	@$(BUILD)/debug/gomoku_tests

debug-engine: $(ENGINE_LIB_SRC) $(ENGINE_MAIN)
	@mkdir -p $(BUILD)/debug
	$(CXX) $(CXXSTD) $(DEBUG_FLAGS) $(WARN) $(INC) $^ -o $(BUILD)/debug/gomoku_engine
	@echo "built $(BUILD)/debug/gomoku_engine"

dist:
	@mkdir -p downloads
	cd .. && tar --exclude='gomoku-bot/build' --exclude='gomoku-bot/.venv' \
	    --exclude='__pycache__' --exclude='gomoku-bot/downloads' \
	    -czf gomoku-bot/downloads/gomoku-bot.tar.gz gomoku-bot
	@ls -lh downloads/gomoku-bot.tar.gz

clean:
	rm -rf $(BUILD)
