##
# Build test executables
##

test/%$(EXE) : CXXFLAGS += $(CXXFLAGS_GTEST)
test/%$(EXE) : CPPFLAGS += $(CPPFLAGS_GTEST)
test/%$(EXE) : INC += $(INC_GTEST) -I $(RAPIDJSON)
test/%$(EXE) : test/%.o $(GTEST)/src/gtest_main.cc $(GTEST)/src/gtest-all.o $(SUNDIALS_TARGETS) $(MPI_TARGETS) $(TBB_TARGETS)
	$(LINK.cpp) $(filter-out src/test/test-models/% src/%.csv bin/% test/%.hpp %.hpp-test,$^) $(LDLIBS) $(OUTPUT_OPTION)

# generates .d files as a side effect
test/%.o : src/test/%.cpp src/test/utility.hpp
	@mkdir -p $(dir $@)
	$(COMPILE.cpp) -MT $@ -MMD -MP -MF test/$*.d $(OUTPUT_OPTION) $<


############################################################
#
# Target to verify header files within CmdStan has
# enough include calls
##
HEADER_TESTS := $(addsuffix -test,$(call findfiles,src/cmdstan,*.hpp))

ifeq ($(OS),Windows_NT)
  DEV_NULL = nul
else
  DEV_NULL = /dev/null
endif

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

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

.PHONY: test-headers
test-headers: $(HEADER_TESTS)

ifneq ($(filter test/%,$(MAKECMDGOALS)),)

include src/cmdstan/main.d

TEST_SRCS = $(wildcard src/test/interface/*.cpp)
TEST_DEPFILES := $(TEST_SRCS:src/test/%.cpp=test/%.d)
$(TEST_DEPFILES):
include $(wildcard $(TEST_DEPFILES))
endif

##
# Tests that depend on compiled models
##
define depends_on_test_models
   | $(addsuffix $(EXE),$(addprefix src/test/test-models/,$(1)))
endef

test/interface/command_test$(EXE):                $(call depends_on_test_models, printer domain_fail proper value_fail transformed_data_rng_test ndim_array)
test/interface/config_json_test$(EXE):            $(call depends_on_test_models, multi_normal_model)
test/interface/csv_header_consistency_test$(EXE): $(call depends_on_test_models, csv_header_consistency)
test/interface/datetime_test$(EXE):               $(call depends_on_test_models, test_model)
test/interface/elapsed_time_test$(EXE):           $(call depends_on_test_models, test_model)
test/interface/fixed_param_sampler_test$(EXE):    $(call depends_on_test_models, empty proper)
test/interface/generated_quantities_test$(EXE):   $(call depends_on_test_models, bern_gq_model bern_extra_model gq_non_scalar test_model)
test/interface/laplace_test$(EXE):                $(call depends_on_test_models, multi_normal_model simple_jacobian_model simplex_model)
test/interface/log_prob_test$(EXE):               $(call depends_on_test_models, bern_log_prob_model bern_gq_model simplex_model)
test/interface/metric_test$(EXE):                 $(call depends_on_test_models, test_model proper)
test/interface/model_output_test$(EXE):           $(call depends_on_test_models, printer)
test/interface/multi_chain_init_test$(EXE):       $(call depends_on_test_models, bern_gq_model)
test/interface/multi_chain_test$(EXE):            $(call depends_on_test_models, test_model)
test/interface/optimization_output_test$(EXE):    $(call depends_on_test_models, optimization_output simple_jacobian_model)
test/interface/output_sig_figs_test$(EXE):        $(call depends_on_test_models, proper_sig_figs)
test/interface/pathfinder_test$(EXE):             $(call depends_on_test_models, multi_normal_model eight_schools empty)
test/interface/permissions_test$(EXE):            $(call depends_on_test_models, test_model)
test/interface/print_uninitialized_test$(EXE):    $(call depends_on_test_models, print_uninitialized)
test/interface/save_metric_json_test$(EXE):       $(call depends_on_test_models, simplex_model multi_normal_model)
test/interface/variational_output_test$(EXE):     $(call depends_on_test_models, variational_output)

# these tests depend only on the bin/ executables, not any models
test/interface/stansummary_test$(EXE):         bin/stansummary$(EXE)
test/interface/diagnose_test$(EXE):            bin/diagnose$(EXE)
test/interface/print_test$(EXE):               bin/print$(EXE)


TEST_MODELS := $(wildcard src/test/test-models/*.stan)
.PHONY: clean-tests
clean-tests:
	$(RM) -r test
	$(RM) $(wildcard $(patsubst %.stan,%.d,$(TEST_MODELS)))
	$(RM) $(wildcard $(patsubst %.stan,%.hpp,$(TEST_MODELS)))
	$(RM) $(wildcard $(patsubst %.stan,%.o,$(TEST_MODELS)))
	$(RM) $(wildcard $(patsubst %.stan,%$(EXE),$(TEST_MODELS)))
