message("\n${BoldGreen}Now configuring tests for ${CMAKE_PROJECT_NAME}${ColourReset}")
message("")
message("To make the tests and then perform the coverage analysis:")
message("cmake ../../development -DBUILD_TESTS=On -DCODE_COVERAGE=On -DCMAKE_BUILD_TYPE=Debug")
message("make")
message("make coverage")
message("And the coverage results will be output (HTML) in ${CMAKE_CURRENT_BINARY_DIR}/coverage")

# This export will allow using the flags to be used by the Clang-based code
# analyzer.
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)

if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json")
    execute_process(
        COMMAND cmake -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
                ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json
    )
endif()

# This file is included if BUILD_TESTS option is set to ON

configure_file(${CMAKE_UTILS_PATH}/tests-config.h.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/tests-config.h @ONLY)

find_package(Catch2 3 REQUIRED)

# Whatever the platform, this always works.
find_package(
    Qt6 REQUIRED
    COMPONENTS Core
               Svg
               Xml
               Network
               Qml
)

message("Using the local XPERTMASS tree libraries and includes to build the tests")
message("")

set(XpertMass_FOUND 1)
set(XpertMass_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/source/XpertMassCore/includes")
set(XpertMass_LIBRARIES "${CMAKE_BINARY_DIR}/source/XpertMassCore/libXpertMassCore.so")

if(NOT TARGET XpertMass::Core)

    add_library(XpertMass::Core UNKNOWN IMPORTED GLOBAL)
    set_target_properties(
        XpertMass::Core PROPERTIES IMPORTED_LOCATION ${XpertMass_LIBRARIES} INTERFACE_INCLUDE_DIRECTORIES
                                                                            ${XpertMass_INCLUDE_DIRS}
    )

endif()

message("")

set(tests_SRCS
    catch2-test-main.cpp
    TestUtils.cpp
    test_CalcOptions.cpp
    test_Isotope.cpp
    test_IsotopicData.cpp
    test_IsotopicDataLibraryHandler.cpp
    test_IsotopicDataUserConfigHandler.cpp
    test_IsotopicDataManualConfigHandler.cpp
    test_Formula.cpp
    test_Ionizer.cpp
    test_ChemicalGroupRule.cpp
    test_ChemicalGroup.cpp
    test_IndexRange.cpp
    test_IndexRangeCollection.cpp
    test_Modif.cpp
    test_Monomer.cpp
    test_Sequence.cpp
    test_CrossLinker.cpp
    test_CrossLinkedRegion.cpp
    test_CrossLink.cpp
    test_CleavageAgent.cpp
    test_CleavageMotif.cpp
    test_CleavageRule.cpp
    test_CleavageConfig.cpp
    test_FragmentationRule.cpp
    test_FragmentationPathway.cpp
    test_FragmentationConfig.cpp
    test_PolChemDef.cpp
    test_PolChemDefSpec.cpp
    test_Polymer.cpp
    test_Oligomer.cpp
    test_Cleaver.cpp
    test_Fragmenter.cpp
    test_MassCollection.cpp
)

add_executable(
    testRunner
    ${tests_SRCS} ${${TARGET}_QRC_CPP}
)

# We set the target link libraries this way to reuse them later.
set(TARGET_LINK_LIBRARIES
    -Wl,--whole-archive
    XpertMass::Core
    -Wl,--no-whole-archive
    -Wl,--no-as-needed
    PappsoMSpp::Core
    -Wl,--as-needed
    IsoSpec++::IsoSpec++
    Qt6::Core
    Qt6::Xml
    Qt6::Network
    Qt6::Qml
    Catch2::Catch2WithMain
)

# Finally actually set the linking dependencies to the executable.
target_link_libraries(
    testRunner ${TARGET_LINK_LIBRARIES}
)

# For the tests-config.h file
target_include_directories(
    testRunner
    PUBLIC ${CMAKE_CURRENT_BINARY_DIR}
)

set_property(TARGET testRunner PROPERTY CXX_STANDARD 17) # we want C++17
add_dependencies(testRunner XpertMass::Core)

# Enable testing
# enable_testing()

include(Catch)
catch_discover_tests(testRunner)

# Add the Catch2-based single binary test file to the CMake's test suite so that
# it gets called using 'make test'. To see the output, add "ARGS=-V" to the
# call.

add_test(NAME CoreTests COMMAND testRunner)

# add_custom_target(runtests ALL
add_custom_target(
    runtests
    COMMAND testRunner --success
    DEPENDS testRunner XpertMass::Core
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    COMMENT "Now running the tests"
)

set(core_includes_dir "${CMAKE_SOURCE_DIR}/source/XpertMassCore/includes/MsXpS/libXpertMassCore")
# message("core_includes_dir: ${core_includes_dir}")
set(gui_includes_dir "${CMAKE_SOURCE_DIR}/source/XpertMassGui/includes/MsXpS/libXpertMassGui/")
# message("gui_includes_dir: ${gui_includes_dir}")

set(tests_dir ${CMAKE_CURRENT_LIST_DIR})

if(CMAKE_COMPILER_IS_GNUCXX AND CODE_COVERAGE)

    file(GLOB CORE_HEADER_FILES "${core_includes_dir}/*.hpp" "${core_includes_dir}/*.h")
    # message("CORE_HEADER_FILES: ${CORE_HEADER_FILES}")

    file(GLOB GUI_HEADER_FILES "${gui_includes_dir}/*.hpp" "${Cgui_includes_dir}/*.h")
    # message("GUI_HEADER_FILES: ${GUI_HEADER_FILES}")

    file(GLOB TEST_SOURCE_FILES "${tests_dir}/*.cpp")

    set(COVERAGE_EXCLUDES ${CORE_HEADER_FILES} ${GUI_HEADER_FILES} ${TEST_SOURCE_FILES})

    message("COVERAGE_EXCLUDES: ${COVERAGE_EXCLUDES}")

    include(CodeCoverage)

    append_coverage_compiler_flags()
    # Added to change the theme, by looking into the code
    set(GCOVR_ADDITIONAL_ARGS ${GCOVR_ADDITIONAL_ARGS} --html-theme github.blue)
    # Added to ouput the gcovr command to the terminal, by looking into the code
    set(CODE_COVERAGE_VERBOSE On)
    setup_target_for_coverage_gcovr_html(
        NAME
        code_coverage
        EXECUTABLE
        ${CMAKE_CURRENT_BINARY_DIR}/testRunner
        ||
        /dev/true
        BASE_DIRECTORY
        ${CMAKE_SOURCE_DIR}
    )

    add_dependencies(code_coverage testRunner XpertMass::Core)
endif()
