BIN_DIR=bin
EXTRAS_DIR=$(TESTGEN_DIR)/extras
TESTS_DIR=tests
TESTGEN_DIR=testgen
SYSTEM_DIR=system
CONTESTANT_DIR=contestant
SOLUTIONS_DIR=author
STATEMENT_DIR=statement
CHECKER_DIR=checker

TASK_NAME=matrix
TASK_NUMBERING=A3
OUTPUT_ZIP=../$(TASK_NUMBERING)_$(TASK_NAME).zip

CXX_FLAGS=-std=c++23 -O2 \
	-Wformat=2 -Wlogical-op -Wshift-overflow=2 \
	-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wduplicated-branches -Wcast-qual -Wcast-align \
	-Wshadow -Wnull-dereference -Wuseless-cast -Wundef -fstack-protector-strong \
	-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 \
	-fsanitize=undefined,address -fsanitize-trap=undefined -fno-omit-frame-pointer \
	-pie -fPIE -Wl,-z,relro,-z,now

SYSTEM_FLAGS=-std=c++11 -O2

SAFE_FLAGS=-std=c++23 -O2 -Wall -Wextra -pedantic -Wformat=2 \
	-Wlogical-op -Wshift-overflow=2 -Wduplicated-cond -Wduplicated-branches -Wcast-qual -Wcast-align \
	-Wshadow -Wnull-dereference -Wuseless-cast -Wundef -fstack-protector-strong \
	-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC -D_FORTIFY_SOURCE=2 \
	-fsanitize=undefined,address -fsanitize-trap=undefined -fno-omit-frame-pointer \
	-pie -fPIE -Wl,-z,relro,-z,now

SOLUTION_SOURCES=$(wildcard $(SOLUTIONS_DIR)/*.cpp)
SOLUTION_BINARIES=$(patsubst $(SOLUTIONS_DIR)/%.cpp,$(BIN_DIR)/%, $(SOLUTION_SOURCES))

FORMATTER = clang-format
FORMAT_FLAGS = -i
FORMAT_SOURCES = \
	$(wildcard $(SOLUTIONS_DIR)/*.cpp) \
	$(wildcard $(TESTGEN_DIR)/*.cpp) \
	$(wildcard $(TESTGEN_DIR)/*.h) \
	$(wildcard $(SYSTEM_DIR)/*.cpp) \
	$(wildcard $(CHECKER_DIR)/*.cpp)

.PHONY: default build_testgen build_solutions run_testgen package package-clean

default: format build_testgen build_solutions run_testgen package

format:
	$(FORMATTER) $(FORMAT_FLAGS) $(FORMAT_SOURCES)

$(BIN_DIR)/testgen: $(TESTGEN_DIR)/testgen.cpp $(TESTGEN_DIR)/common.h
	$(CXX) $< $(CXX_FLAGS) -o $@

$(BIN_DIR)/%: $(SOLUTIONS_DIR)/%.cpp # $(SYSTEM_DIR)/grader.cpp
	$(CXX) $^ -I$(SYSTEM_DIR) -o $@ $(SYSTEM_FLAGS)

build_testgen: $(BIN_DIR)/testgen

build_solutions: $(SOLUTION_BINARIES)

run_testgen: $(BIN_DIR)/testgen
	rm -rf $(TESTS_DIR)
	mkdir $(TESTS_DIR)
	./$(BIN_DIR)/testgen
	cat grade.properties

package-clean:
	rm -f $(OUTPUT_ZIP)

package:
	zip -ur $(OUTPUT_ZIP) $(SOLUTIONS_DIR) $(EXTRAS_DIR) $(STATEMENT_DIR) \
		Makefile $(TESTGEN_DIR) $(TESTS_DIR)/*.in $(TESTS_DIR)/*.out \
		$(SYSTEM_DIR) $(CONTESTANT_DIR) $(CHECKER_DIR) grade.properties
