include(GoogleTest)

set(INSTALL_GTEST OFF)

FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        v1.14.0
)
Message(STATUS "Getting external dependency (googletest)...")
FetchContent_MakeAvailable(googletest)
Message(STATUS "Getting external dependency (googletest)... Done")

function(add_gtest
    test
    raw_flavor)
  set(test_full "${test}_${raw_flavor}")
  set(aevol_flavor "aevol_${raw_flavor}")
  # Setup optional WORKING_DIRECTORY argument
  set(options "")
  set(oneValueArgs WORKING_DIRECTORY)
  set(multiValueArgs "")
  cmake_parse_arguments(PARSE_ARGV 2 arg
      "${options}" "${oneValueArgs}" "${multiValueArgs}"
  )

  # Add test binary and link it to libaevol and gtest_main
  add_executable(${test_full} ${test}.cpp)
  target_link_libraries(${test_full} PRIVATE GTest::gtest_main lib${aevol_flavor})

  # Add test (optionally setting work_dir)
  if(arg_WORKING_DIRECTORY)
    gtest_add_tests(
        TARGET ${test_full}
        WORKING_DIRECTORY ${arg_WORKING_DIRECTORY}
        TEST_PREFIX "[GTEST] "
        TEST_SUFFIX "_${raw_flavor}"
        TEST_LIST ${test}_TESTS
    )
  else ()
    gtest_add_tests(
        TARGET ${test_full}
        TEST_PREFIX "[GTEST] "
        TEST_SUFFIX "_${raw_flavor}"
        TEST_LIST ${test}_TESTS
    )
  endif ()

  # Add labels
  set_tests_properties(${${test}_TESTS}
      PROPERTIES
      LABELS "TEST;gtest;${aevol_flavor}")

  # Add test binary to target all-with-gtests
  add_dependencies(all-with-gtests ${test_full})

  # Tell caller about added tests and add to ALL_GTESTS
  set(${test}_TESTS ${${test}_TESTS} PARENT_SCOPE)
  set(ALL_GTESTS ${ALL_GTESTS} ${${test}_TESTS} PARENT_SCOPE)
endfunction()
##################################################

# Copy test data
file(
    COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_data
    DESTINATION ${CMAKE_BINARY_DIR}/test/gtest)
set(TEST_DATA_DIR ${CMAKE_BINARY_DIR}/test/gtest/test_data)

# Add custom target to compile all flavors of aevol and all the gtests that will be added with function add_gtest
add_custom_target(all-with-gtests DEPENDS ${AEVOL_FLAVORS})

add_gtest(DnaTest                 2b)
add_gtest(JumpingMTTest           2b)
add_gtest(DiscreteDoubleFuzzyTest 2b)
add_gtest(ParamReaderTest         eukaryote_2b    WORKING_DIRECTORY ${TEST_DATA_DIR})
add_gtest(CheckpointExplorerTest  2b              WORKING_DIRECTORY ${TEST_DATA_DIR}/mini_run)
add_gtest(EvolutionRunnerTest     2b              WORKING_DIRECTORY ${TEST_DATA_DIR}/mini_run)
add_gtest(SelectionTest           2b)
add_gtest(Dna_4bTest              4b)
add_gtest(FastaTest               4b)
add_gtest(Folding4bTest           4b)
add_gtest(GFF3Test                4b)
add_gtest(GFF3Test                eukaryote_2b)
add_gtest(EukIndividualTest       eukaryote_2b)
add_gtest(EukTest_mutations       eukaryote_2b)
add_gtest(EukTest_nornas          eukaryote_2b)
add_gtest(EukTest_withrnas        eukaryote_2b)

# Add pseudo-test to be used as a dependency to force the build of all-with-gtests before tests are run
add_test(build_all-with-gtests
    "${CMAKE_COMMAND}"
    --build "${CMAKE_BINARY_DIR}"
    --config "$<CONFIG>"
    --target all-with-gtests
)
set_tests_properties(${ALL_GTESTS}
    PROPERTIES
    DEPENDS build_all-with-gtests
)

# Add pseudo-test to be used as a dependency to generate test data
add_test(NAME generate_gtest_test_data
    COMMAND ./generate_data.sh $<TARGET_FILE:aevol_create_2b> $<TARGET_FILE:aevol_run_2b>
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test_data
)
set_tests_properties(generate_gtest_test_data
    PROPERTIES
    DEPENDS build_all-with-gtests
    LABELS "TEST;gtest")

if(NOT DEFINED CheckpointExplorerTest_TESTS OR NOT DEFINED EvolutionRunnerTest_TESTS)
  message(FATAL_ERROR "GTest dependencies broken")
endif ()
set_tests_properties(${CheckpointExplorerTest_TESTS} ${EvolutionRunnerTest_TESTS}
    PROPERTIES
    DEPENDS generate_gtest_test_data
)
