# Copyright 2009-present MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

include(FetchCatch2)

if(NOT BUILD_TESTING)
    set_property(DIRECTORY PROPERTY EXCLUDE_FROM_ALL TRUE)
endif()

if(BSONCXX_BUILD_SHARED)
    bsoncxx_add_library(bsoncxx_testing "bsoncxx-testing" SHARED)
else()
    bsoncxx_add_library(bsoncxx_testing "bsoncxx-testing" STATIC)
endif()

target_compile_definitions(bsoncxx_testing PUBLIC BSONCXX_TESTING)

add_executable(test_bson
    array.cpp
    bson_b_date.cpp
    bson_builder.cpp
    bson_get_values.cpp
    bson_serialization.cpp
    bson_types.cpp
    bson_util_itoa.cpp
    bson_validate.cpp
    bson_value.cpp
    catch.cpp
    exception_guard.cpp
    json.cpp
    oid.cpp
    optional.test.cpp
    view_or_value.cpp
    make_unique.test.cpp
    string_view.test.cpp
    type_traits.test.cpp
)

# Common target properties for test executables.
add_library(bsoncxx_test_properties INTERFACE)

target_link_libraries(bsoncxx_test_properties INTERFACE Catch2::Catch2)
target_compile_features(bsoncxx_test_properties INTERFACE cxx_std_14)

target_link_libraries(bsoncxx_test_properties INTERFACE bsoncxx_testing ${libbson_target})
target_include_directories(bsoncxx_test_properties INTERFACE

    # Allow `#include <bson/bson.h>`
    ${libbson_include_directories}

    # Allow `#include <bsoncxx/test/...>`.
    ${CMAKE_CURRENT_SOURCE_DIR}/../..
)
target_compile_definitions(bsoncxx_test_properties INTERFACE ${libbson_definitions})
# Use `__vectorcall` by default with MSVC to catch missing `__cdecl`.
target_compile_options(bsoncxx_test_properties INTERFACE "$<$<CXX_COMPILER_ID:MSVC>:/Gv>")
add_library(bsoncxx::test_properties ALIAS bsoncxx_test_properties)

# Avoid redundant recompilation of catch/main.cpp.
add_library(bsoncxx_test_properties_with_main INTERFACE)
target_link_libraries(bsoncxx_test_properties_with_main INTERFACE bsoncxx::test_properties)
target_sources(bsoncxx_test_properties INTERFACE catch.cpp)
add_library(bsoncxx::test_properties_with_main ALIAS bsoncxx_test_properties_with_main)

target_link_libraries (test_bson PRIVATE bsoncxx::test_properties_with_main)

add_test(NAME bson COMMAND test_bson --reporter compact --allow-running-no-tests)

# Generate test to ensure macro guards behave properly.
if(ENABLE_MACRO_GUARD_TESTS)
    include(MacroGuardTest)

    add_macro_guard_test(
        PROJECT_NAME bsoncxx
        PROJECT_TEST_PROPERTIES_TARGET bsoncxx::test_properties
        GUARDED_MACROS
            # config.hpp (generated by CMake)
            BSONCXX_POLY_USE_IMPLS
            BSONCXX_POLY_USE_STD

            # version.hpp (generated by CMake)
            BSONCXX_VERSION_EXTRA
            BSONCXX_VERSION_MAJOR
            BSONCXX_VERSION_MINOR
            BSONCXX_VERSION_PATCH

            # export.hpp (generated by CMake)
            BSONCXX_ABI_CDECL
            BSONCXX_ABI_EXPORT
            BSONCXX_ABI_EXPORT_TESTING
            BSONCXX_ABI_NO_EXPORT
            BSONCXX_ABI_EXPORT_CDECL
            BSONCXX_ABI_EXPORT_CDECL_TESTING
            BSONCXX_DEPRECATED

            # prelude.hpp
            BSONCXX_UNREACHABLE

            # util.hpp
            _bsoncxxDisableWarningImpl_for_GCC
            _bsoncxxDisableWarningImpl_for_GNU
            _bsoncxxDisableWarningImpl_for_MSVC
            _bsoncxxDisableWarningImpl_for_Clang
            BSONCXX_PUSH_WARNINGS
            BSONCXX_POP_WARNINGS
            BSONCXX_DISABLE_WARNING
            BSONCXX_CONCAT
            BSONCXX_CONCAT_IMPL
            bsoncxx_cxx14_constexpr
            BSONCXX_FORCE_SEMICOLON
            BSONCXX_FWD
            BSONCXX_PRAGMA
            _bsoncxxPragma
            BSONCXX_STRINGIFY
            BSONCXX_STRINGIFY_IMPL
            BSONCXX_IF_MSVC
            BSONCXX_IF_GCC
            BSONCXX_IF_CLANG
            BSONCXX_IF_GNU_LIKE
            BSONCXX_RETURNS
        INCLUDE_PATTERNS
            "include/*.hpp" # Public headers.
        EXCLUDE_REGEXES
            "include/bsoncxx/doc\.hpp" # Doc header.
            "include/.*/(prelude|postlude)\.hpp" # Macro guard headers.
            "include/bsoncxx/v_noabi/bsoncxx/config/.*\.hpp" # v_noabi config headers.
            "include/bsoncxx/v_noabi/bsoncxx/enums/.*\.hpp" # v_noabi X-macro headers.
    )
endif()

set_dist_list(src_bsoncxx_test_DIST
    CMakeLists.txt
    array.cpp
    bson_b_date.cpp
    bson_builder.cpp
    bson_get_values.cpp
    bson_serialization.cpp
    bson_types.cpp
    bson_util_itoa.cpp
    bson_validate.cpp
    bson_value.cpp
    catch.cpp
    catch.hh
    exception_guard.cpp
    exception_guard.hh
    json.cpp
    oid.cpp
    optional.test.cpp
    test_macro_guards.cpp.in
    to_string.hh
    view_or_value.cpp
    make_unique.test.cpp
    string_view.test.cpp
    type_traits.test.cpp
)
