include(DownloadProject/DownloadProject.cmake)

download_project(PROJ                googletest
                 GIT_REPOSITORY      https://github.com/google/googletest.git
                 GIT_TAG             master
                 UPDATE_DISCONNECTED 1
)

# Prevent GoogleTest from overriding our compiler/linker options
# when building with Visual Studio
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})


# Hide the many cmake variables defined by google test
mark_as_advanced(
    BUILD_GMOCK BUILD_GTEST BUILD_SHARED_LIBS
    gmock_build_tests gtest_build_samples gtest_build_tests
    gtest_disable_pthreads gtest_force_shared_crt gtest_hide_internal_symbols
)

# Don't install GoogleTest
set(INSTALL_GTEST OFF CACHE BOOL "Install GTest and GMock" FORCE)


# clean up the "folders" generated in any IDEs
set_target_properties(gtest PROPERTIES FOLDER extern)
set_target_properties(gtest_main PROPERTIES FOLDER extern)
set_target_properties(gmock PROPERTIES FOLDER extern)
set_target_properties(gmock_main PROPERTIES FOLDER extern)

#MACRO add_googletest(
#    TESTNAME 
#        The name of the test target you are adding. You can use this name later to configure the target with
#        target_* commands
#    PRIVATE_INCLUDES 
#        Any private header files required by the test target. This would probably include and private
#        headers that are apart of the target under test, and would also include any mocks or test specific headers
#    LIBRARIES
#        Any libraries the test target should link against. This should probably include the target under test
#    ARGN
#        The remaining unnamed parameters are considered the source files for the target eg.
#        add_googletest(MyTest "${MYTEST_INCLUDES}" MyLibrary MyTest.cpp MyOtherTest.cpp)
#
#    Note: If you pass any lists as arguments to the macro, wrap them in quotes to ensure they are expanded properly
#    eg:
#        set(PRIVATE_INCLUDES myLibInclude test/mocks)
#        add_googletest(MyTestTarget "${PRIVATE_INCLUDES}" myLib myTest.cpp)
#
#    Note2: Given a directory structure like this
#    -test/
#    --CMakeLists.txt <--
#    --Mocks/
#    ---myMock.h
#    --myTest.cpp
#
#    a call to add_googletest(...) inside the indicated CMakeLists.txt will automatically include the "test" directory
#    on any test target generated by the command
macro(add_googletest TESTNAME PRIVATE_INCLUDES LIBRARIES)
    # create an exectuable in which the tests will be stored
    add_executable(${TESTNAME} ${ARGN})
    # link the Google test infrastructure, mocking library, and a default main fuction to
    # the test executable.  Remove g_test_main if writing your own main function.
    target_link_libraries(${TESTNAME} PRIVATE gtest gmock gtest_main)
    # link to any libraries required for the test
    target_link_libraries(${TESTNAME} PRIVATE ${LIBRARIES})
    # include any private includes
    target_include_directories(${TESTNAME} PRIVATE ${PRIVATE_INCLUDES})
    # include the current source dir to include any mocks or headers local to the test files
    target_include_directories(${TESTNAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
    # gtest_discover_tests replaces gtest_add_tests,
    # see https://cmake.org/cmake/help/v3.10/module/GoogleTest.html for more options to pass to it
    gtest_discover_tests(${TESTNAME}
        # set a working directory so your project root so that you can find test data via paths relative to the project root
        WORKING_DIRECTORY ${PROJECT_DIR}
        PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_DIR}"
    )
    # clean up the folders generated in ides
    set_target_properties(${TESTNAME} PROPERTIES FOLDER tests)
endmacro()
