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

include_directories(".")
include_directories(${CMAKE_SOURCE_DIR}/third_party/cpp-httplib)

# List to collect all common test targets
set(COMMON_TEST_TARGETS)

macro(add_common_test TEST_NAME TEST_SOURCE)
    # Create a separate test executable per test source.
    add_executable(common_${TEST_NAME} ${TEST_SOURCE} buildboxcommontest_utils.cpp)
    target_precompile_headers(common_${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 common_${TEST_NAME} COMMAND common_${TEST_NAME} WORKING_DIRECTORY ${TEST_WORKING_DIRECTORY})
    target_link_libraries(common_${TEST_NAME} PUBLIC common ${GTEST_MAIN_TARGET} ${GMOCK_TARGET})

    list(APPEND COMMON_TEST_TARGETS common_${TEST_NAME})
    set(COMMON_TEST_TARGETS "${COMMON_TEST_TARGETS}" PARENT_SCOPE)
endmacro()

add_common_test(assetclient_test buildboxcommon_assetclient.t.cpp)
add_common_test(casclient_test buildboxcommon_casclient.t.cpp)
add_common_test(stageddirectory_tests buildboxcommon_stageddirectory.t.cpp)
add_common_test(localcasstageddirectory_tests buildboxcommon_localcasstageddirectory.t.cpp)
add_common_test(fileutils_tests buildboxcommon_fileutils.t.cpp)
add_common_test(notify_tests buildboxcommon_notify.t.cpp)
add_common_test(timeutils_tests buildboxcommon_timeutils.t.cpp)
add_common_test(systemutils_tests buildboxcommon_systemutils.t.cpp)
add_common_test(logging_tests buildboxcommon_logging.t.cpp)
add_common_test(runner_tests buildboxcommon_runner.t.cpp)
add_common_test(temporarydirectory_tests buildboxcommon_temporarydirectory.t.cpp)
add_common_test(temporaryfile_tests buildboxcommon_temporaryfile.t.cpp)
add_common_test(grpcretrier_tests buildboxcommon_grpcretrier.t.cpp)
add_common_test(protos_tests buildboxcommon_protos.t.cpp)
add_common_test(protobuf_json_tests buildboxcommon_protojsonutils.t.cpp)
add_common_test(requestmetadata_tests buildboxcommon_requestmetadata.t.cpp)
add_common_test(mergeutil_tests buildboxcommon_mergeutil.t.cpp)
add_common_test(direntwrapper_tests buildboxcommon_direntwrapper.t.cpp)
add_common_test(grpc_error_tests buildboxcommon_grpcerror.t.cpp)
add_common_test(logstreamwriter_tests buildboxcommon_logstreamwriter.t.cpp)
add_common_test(logstreamreader_tests buildboxcommon_logstreamreader.t.cpp)
add_common_test(commandline_test buildboxcommon_commandline.t.cpp)
add_common_test(streamingstandardoutputifstreamfilemonitor buildboxcommon_streamingstandardoutputifstreamfilemonitor.t.cpp)
add_common_test(connectionoptions_commandline_test buildboxcommon_connectionoptions_commandline.t.cpp)
add_common_test(connectionoptions_toml_test buildboxcommon_connectionoptions_toml.t.cpp)
add_common_test(scopeguard_tests buildboxcommon_scopeguard.t.cpp)
add_common_test(stringutils_tests buildboxcommon_stringutils.t.cpp)
add_common_test(reloadtokenauthenticator_tests buildboxcommon_reloadtokenauthenticator.t.cpp)
add_common_test(executionstatsutils_tests buildboxcommon_executionstatsutils.t.cpp)
add_common_test(remoteexecutionclient_test buildboxcommon_remoteexecutionclient.t.cpp)
add_common_test(tomlutil_test buildboxcommon_tomlutils.t.cpp)
add_common_test(fs_local_tests buildboxcommon_fslocalcas.t.cpp)
add_common_test(lru_local_tests buildboxcommon_lrulocalcas.t.cpp)
add_common_test(hardlink_stager_tests buildboxcommon_hardlinkstager.t.cpp)

if(OCI)
    add_common_test(httpclient_tests buildboxcommon_httpclient.t.cpp)
    add_common_test(ocimanifest_tests buildboxcommon_ocimanifest.t.cpp)
    # This test uses a different cwd.
    add_common_test(ociclient_tests buildboxcommon_ociclient.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)
    
    # Find tar executable and add preprocessor definition for OCI TAR extraction tests if available
      find_program(tar_EXECUTABLE tar)
      if(tar_EXECUTABLE)
          message(STATUS "OCI_TAR_EXTRACTION_TESTS enabled; 'tar' executable found: ${tar_EXECUTABLE}")
          target_compile_definitions(common_ociclient_tests PRIVATE BUILDBOX_OCI_TAR_EXTRACTION_TESTS=1)
      else()
          message(WARNING "OCI_TAR_EXTRACTION_TESTS requested but 'tar' executable not found; disabling related tests.")
      endif()
    
    # Add casd dependency for OCI client integration tests
    target_link_libraries(common_ociclient_tests PRIVATE casd)
    add_dependencies(common_ociclient_tests casd)
endif()

# These tests use a different cwd.
add_common_test(digestgenerator_tests buildboxcommon_digestgenerator.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/)
add_common_test(fallbackstageddirectory_tests buildboxcommon_fallbackstageddirectory.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/buildboxcommon_fallbackstageddirectory)
add_common_test(merklize_tests buildboxcommon_merklize.t.cpp ${CMAKE_CURRENT_SOURCE_DIR}/data/merklize)

# These tests need some additional environment variables to be set (to test underlying libraries) in addition to different cwd
add_common_test(connectionoptions_tests buildboxcommon_connectionoptions.t.cpp ${CMAKE_CURRENT_SOURCE_DIR})
set_tests_properties(common_connectionoptions_tests  PROPERTIES ENVIRONMENT GOOGLE_APPLICATION_CREDENTIALS=data/mock_google_token.json)

add_executable(testrunner buildboxcommon_testrunner.m.cpp)
target_precompile_headers(testrunner REUSE_FROM common)
target_link_libraries(testrunner common)
add_common_test(localexecutionclient_test buildboxcommon_localexecutionclient.t.cpp)
set_tests_properties(common_localexecutionclient_test PROPERTIES ENVIRONMENT
                     "BUILDBOX_RUN=${CMAKE_CURRENT_BINARY_DIR}/testrunner")

# Meta target to build all common test executables
add_custom_target(common_tests DEPENDS ${COMMON_TEST_TARGETS})
