##
# 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) $(shell find stan/example-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 $(LIBGTEST)
	@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 bin/libstan.a
	@mkdir -p $(dir $@)
	$(LINK.c) -O$O $(GTEST_MAIN) $< $(CFLAGS_GTEST) $(OUTPUT_OPTION) $(LIBGTEST) $(LDLIBS)
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

##
# Model tests. Adding built model as a depedency.
##
$(patsubst src/test/models/%_test.cpp,test/models/%_test.o,$(filter src/test/models/%,$(ALL_TESTS))) : test/models/%_test.o : $(STANAPI_HOME)example-models/%$(EXE)


##
# 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/fixed_param_sampler_test.o: $(addsuffix $(EXE),$(addprefix src/test/test-models/, empty proper))
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/gm/argument_configuration_test.o: src/test/test-models/test_model$(EXE)
test/interface/elapsed_time_test.o: src/test/test-models/test_model$(EXE)
