##
# LIBGTEST is the google test library
# GTEST_MAIN is the file that contains the google test
##
LIBGTEST = test/libgtest.a
GTEST_MAIN = $(GTEST)/src/gtest_main.cc
CFLAGS_GTEST += -I $(GTEST)/include -I $(GTEST)

##
# target path_separator for use in some tests that need to
# call executables.
##
.PHONY: path_separator
path_separator :
	@echo $(PATH_SEPARATOR)

##
# PERCENT used for secondary expansion
# $$(PERCENT) turns into %.
##
PERCENT = %

TEST_MODELS := $(shell find src/test/test-models -name '*.stan' -type f)

##
# Target to verify header files are coherent
##
HEADER_TESTS := $(addsuffix -test,$(shell find src/cmdstan -name '*.hpp' -type f))
ifeq ($(OS),win)
  DEV_NULL = nul
else
  DEV_NULL = /dev/null
endif

test/dummy.cpp:
	@mkdir -p test
	@touch $@
	@echo "int main() {return 0;}" >> $@

%.hpp-test : %.hpp test/dummy.cpp
	$(COMPILE.c) -O0 -include $< -o $(DEV_NULL) test/dummy.cpp

##
# Build the google test library.
##
$(LIBGTEST): $(LIBGTEST)(test/gtest.o)

test/gtest.o: $(GTEST)/src/gtest-all.cc
	@mkdir -p test
	$(COMPILE.c) -O$O $(CFLAGS_GTEST) $< $(OUTPUT_OPTION)

test/%.o : src/test/%.cpp 
	@mkdir -p $(dir $@)
	$(COMPILE.c) -O$O $(CFLAGS_GTEST) $< $(OUTPUT_OPTION)

##
# TEST_TARGETS is the set of all src/test subdirectories excluding src/test.
##
TEST_TARGETS := $(shell find src/test ! -path src/test -type d)

##
# ALL_TESTS is the set of all test files
#   This needs to be an '=' assignment and not a ':='.
##
ALL_TESTS = $(shell find src/test -type f -name '*_test.cpp')

ALL_TEST_EXECUTABLES = $(patsubst src/%.cpp,%$(EXE),$(ALL_TESTS))

.PRECIOUS: test/%.o
test/%$(EXE) : test/%.o $(LIBGTEST) $(LIBCVODES)
	@mkdir -p $(dir $@)
	$(LINK.c) -O$O $(GTEST_MAIN) $< $(CFLAGS_GTEST) $(OUTPUT_OPTION) $(LIBGTEST) $(LDLIBS) $(LIBCVODES)
ifeq ($(strip $(findstring src/test/,$(MAKECMDGOALS))), )
	$(WINE) $@ --gtest_output="xml:$(basename $@).xml"
endif

####
## These make rules apply if SECONDEXPANSION is available
## in make.
####
ifneq ($(filter second-expansion,$(.FEATURES)),)
##
# Defining the test target implicit static rule.
#
# Each src/test/* depends on each executable that's generated
# by the test file.
##

## n is used to add line breaks (necessary for windows)
define n


endef

.SECONDEXPANSION:
.PHONY: $(TEST_TARGETS)
$(TEST_TARGETS): src/test/%: $$(filter $$(patsubst src/$$(PERCENT),$$(PERCENT),$$@)/$$(PERCENT),$$(ALL_TEST_EXECUTABLES))
	$(foreach test,$^,$(WINE) $(test) --gtest_output="xml:$(basename $(test)).xml"; $n)
	@echo ''
	@echo 'Ran '$(words $(filter test/%,$^))' tests for '$@
else
####
## Warning for developers that don't have a
## current enough version of make (3.81 or higher).
####
.PHONY: $(TEST_TARGETS)
$(TEST_TARGETS):
	@echo ''
	@echo '------------------------------------------------------------'
	@echo 'The current version of make does not satisfy the developer  '
	@echo 'requirements. Please install make 3.81 or higher.           '
	@echo '------------------------------------------------------------'
endif


##
# Tests that depend on compiled models
##
test/interface/command_test.o: $(addsuffix $(EXE),$(addprefix src/test/test-models/, printer domain_fail proper value_fail))
test/interface/csv_header_consistency_test.o: src/test/test-models/csv_header_consistency$(EXE)
test/interface/elapsed_time_test.o: src/test/test-models/test_model$(EXE)
test/interface/fixed_param_sampler_test.o: $(addsuffix $(EXE),$(addprefix src/test/test-models/, empty proper))
test/interface/model_output_test.o: src/test/test-models/printer$(EXE)
test/interface/optimization_output_test.o: src/test/test-models/optimization_output$(EXE)
test/interface/print_test.o: src/test/interface/matrix_output.csv bin/print$(EXE)
test/interface/print_uninitialized_test.o: src/test/test-models/print_uninitialized$(EXE)
test/interface/services/argument_configuration_test.o: src/test/test-models/test_model$(EXE)
test/interface/stansummary_test.o: src/test/interface/matrix_output.csv bin/stansummary$(EXE)
test/interface/variational_output_test.o: src/test/test-models/variational_output$(EXE)
