include(${CMAKE_SOURCE_DIR}/cmake/BuildboxGTestSetup.cmake)

# Every directory containing a source file needed by the tests, must be added here.
include_directories(fixtures/ env/ ..)

# This macro creates the specific test executable, linking against defined above, google test and google mock.
# Current limitation is the TEST_SOURCE must only be one file.
# If more than 1 file is needed, combine the sources into a list.
macro(add_recc_test TEST_NAME TEST_SOURCE)
    # Create a separate test executable per test source.
    add_executable(recc_${TEST_NAME} ${TEST_SOURCE})
    target_precompile_headers(recc_${TEST_NAME} REUSE_FROM common)

    # This allows us to pass an optional argument if the cwd for the test is not the default.
    set(ExtraMacroArgs ${ARGN})
    list(LENGTH ExtraMacroArgs NumExtraArgs)
    if(${NumExtraArgs} GREATER 0)
      list(GET ExtraMacroArgs 0 TEST_WORKING_DIRECTORY)
    else()
      set(TEST_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
    endif()

    add_test(NAME recc_${TEST_NAME} COMMAND recc_${TEST_NAME} WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
    target_link_libraries(recc_${TEST_NAME} PUBLIC remoteexecution ${GTEST_MAIN_TARGET} ${GMOCK_TARGET})
endmacro()

add_recc_test(subprocess_tests subprocess.t.cpp)
add_recc_test(remoteexecutionclient_tests remoteexecutionclient.t.cpp)
add_recc_test(fileutils_tests fileutils.t.cpp)
add_recc_test(parsed_command_factory_tests parsedcommandfactory.t.cpp)
add_recc_test(shellutils_tests shellutils.t.cpp)
add_recc_test(metrictagging_tests metrictagging.t.cpp)
add_recc_test(regexutils_tests regexutils.t.cpp)


add_recc_test(env_set_test env/env_set.t.cpp)
add_recc_test(env_default_cas_test env/env_default_cas.t.cpp)
add_recc_test(env_default_action_cache_test env/env_default_action_cache.t.cpp)
add_recc_test(env_different_cas_test env/env_different_cas.t.cpp)
add_recc_test(env_different_action_cache_test env/env_different_action_cache.t.cpp)
add_recc_test(env_file_advertised_order_test env/env_file_advertised_order.t.cpp)
add_recc_test(env_check_order_test env/env_check_order.t.cpp)
add_recc_test(env_utils_test env/env_utils.t.cpp)
add_recc_test(env_path_vector_test env/env_path_vector.t.cpp)
add_recc_test(env_reapi_version_test env/env_reapi_version.t.cpp)
add_recc_test(env_parse_config_test env/env_parse_config.t.cpp)
add_recc_test(env_mtls_test env/env_mtls.t.cpp)

# These tests include an extra arg, containing the working directory of the test.
add_recc_test(actionbuilder_tests actionbuilder.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/actionbuilder)

# actionbuilder_tests depend on a system header (/usr/include/ctype.h), which
# lives under the toolchain's sysroot rather than the host's root on some
# platforms. TEST_SYSROOT is only used by these tests.
# On MacOS (Mojave onwards) /usr/include is deprecated, so use
# CMAKE_OSX_SYSROOT or the default SDK. On other platforms use CMAKE_SYSROOT
# or the compiler's default sysroot.
set(TEST_SYSROOT "${CMAKE_OSX_SYSROOT}")
if(APPLE AND NOT TEST_SYSROOT)
  # For a native build CMake leaves CMAKE_OSX_SYSROOT empty and lets the
  # compiler use its default SDK, so ask for that SDK's path directly.
  execute_process(
    COMMAND xcrun --show-sdk-path
    OUTPUT_VARIABLE TEST_SYSROOT
    OUTPUT_STRIP_TRAILING_WHITESPACE
    ERROR_QUIET)
  if(NOT IS_DIRECTORY "${TEST_SYSROOT}")
    set(TEST_SYSROOT "")
  endif()
elseif(NOT APPLE)
  # Sysroot-based toolchains (e.g. crosstool-ng) resolve /usr/include
  # relative to their sysroot rather than the host's root.
  set(TEST_SYSROOT "${CMAKE_SYSROOT}")
  if(NOT TEST_SYSROOT AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
    # Pass CMAKE_CXX_FLAGS so a --sysroot given there is honoured
    separate_arguments(SYSROOT_CXX_FLAGS NATIVE_COMMAND "${CMAKE_CXX_FLAGS}")
    execute_process(
      COMMAND ${CMAKE_CXX_COMPILER} ${SYSROOT_CXX_FLAGS} -print-sysroot
      OUTPUT_VARIABLE TEST_SYSROOT
      OUTPUT_STRIP_TRAILING_WHITESPACE
      ERROR_QUIET)
  endif()
  # Strip trailing slashes so "${TEST_SYSROOT}/usr/include" stays well-formed
  string(REGEX REPLACE "/+$" "" TEST_SYSROOT "${TEST_SYSROOT}")
  if(NOT IS_DIRECTORY "${TEST_SYSROOT}")
    set(TEST_SYSROOT "")
  endif()
endif()
message(STATUS "recc: using TEST_SYSROOT '${TEST_SYSROOT}'")
target_compile_definitions(recc_actionbuilder_tests PRIVATE TEST_SYSROOT="${TEST_SYSROOT}")

add_recc_test(deps_tests deps.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/deps)
add_recc_test(env_from_file_override_test env/env_from_file_override.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_recc_test(env_multiple_configs_test env/env_multiple_configs.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_recc_test(env_from_file_test env/env_from_file.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_recc_test(parsedcommand_tests parsedcommand.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)

add_recc_test(datautils_test datautils.t.cpp)
