cmake_minimum_required (VERSION 3.15)

project (libmongoc
   LANGUAGES C
   # Inherit the version from mongo-c-driver
   VERSION "${PROJECT_VERSION}"
   DESCRIPTION "The MongoDB C Database Driver library"
)

# These values are inherited from the mongo-c-driver parent. These are named as to
# match the CMake variables generated by project().
set(libmongoc_VERSION_PRERELEASE ${mongo-c-driver_VERSION_PRERELEASE})
set(libmongoc_VERSION_FULL ${mongo-c-driver_VERSION_FULL})

set (MONGOC_API_VERSION 1.0)

include (CheckSchedGetCPU)
include (CheckStructHasMember)
include (CheckSymbolExists)
include (CheckTypeSize)
include (CMakePushCheckState)
include (InstallRequiredSystemLibraries)

message (STATUS "libmongoc version (from VERSION_CURRENT file): ${MONGOC_VERSION}")

set (MONGOC_API_VERSION 1.0)
set (MONGOC_TARGETS_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/mongoc-${MONGOC_API_VERSION}")

# Defaults.
set (MONGOC_ENABLE_COMPRESSION 0)
set (MONGOC_ENABLE_COMPRESSION_SNAPPY 0)
set (MONGOC_ENABLE_COMPRESSION_ZLIB 0)
set (MONGOC_ENABLE_COMPRESSION_ZSTD 0)

# Definition for mongoc-config.h:
mongo_pick(MONGOC_ENABLE_SRV 1 0 ENABLE_SRV)

set (MONGOC_OUTPUT_BASENAME "mongoc" CACHE STRING "Output mongoc library base name")

if (NOT ENABLE_ZLIB MATCHES "SYSTEM|AUTO|BUNDLED|OFF")
   message (FATAL_ERROR
      "ENABLE_ZLIB option must be SYSTEM, BUNDLED, AUTO, or OFF"
      )
endif ()

if (NOT ENABLE_ZSTD MATCHES "ON|AUTO|OFF")
   message (FATAL_ERROR "ENABLE_ZSTD option must be ON, AUTO, or OFF")
endif ()

set (ZLIB_INCLUDE_DIRS "")
if (ENABLE_ZLIB MATCHES "SYSTEM|AUTO")
   message (STATUS "Searching for zlib CMake packages")
   include (FindZLIB)
   if (ZLIB_FOUND)
      message (STATUS "   zlib found version \"${ZLIB_VERSION_STRING}\"")
      message (STATUS "   zlib include path \"${ZLIB_INCLUDE_DIRS}\"")
      message (STATUS "   zlib libraries \"${ZLIB_LIBRARIES}\"")
   else ()
      if (ENABLE_ZLIB STREQUAL "SYSTEM")
         message (FATAL_ERROR
            "Unable to find system zlib package. Either specify the zlib \
            location by setting ZLIB_ROOT, or else set ENABLE_ZLIB=BUNDLED or \
            set ENABLE_ZLIB=OFF."
            )
      endif ()
      set (ZLIB_LIBRARIES "")
   endif ()
endif ()

if ( (ENABLE_ZLIB STREQUAL "BUNDLED")
   OR (ENABLE_ZLIB STREQUAL "AUTO" AND NOT ZLIB_FOUND) )
   message (STATUS "Enabling zlib compression (bundled)")
   add_library (zlib_obj OBJECT
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/adler32.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/crc32.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/deflate.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/infback.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/inffast.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/inflate.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/inftrees.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/trees.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/zutil.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/compress.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/uncompr.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/gzclose.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/gzlib.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/gzread.c
      ${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1/gzwrite.c
   )
   set_property (TARGET zlib_obj PROPERTY POSITION_INDEPENDENT_CODE TRUE)
   # This tells the bundled zlib where to find its generated headers
   target_include_directories (zlib_obj
      BEFORE PUBLIC
      "${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1"
      "${CMAKE_BINARY_DIR}/src/zlib-1.3.1"
   )
   # Disable all warnings for compiling Zlib
   target_compile_options (zlib_obj PRIVATE -w)
   set (SOURCES ${SOURCES} $<TARGET_OBJECTS:zlib_obj>)
   # This tells mongoc_shared/mongoc_static where to find generated zlib headers
   set (
      ZLIB_INCLUDE_DIRS
      "${mongo-c-driver_SOURCE_DIR}/src/zlib-1.3.1"
      "${CMAKE_BINARY_DIR}/src/zlib-1.3.1"
   )
endif ()

if (NOT ENABLE_ZLIB STREQUAL "OFF")
   # At this point the system zlib was found, or the bundled library was used
   include (CheckIncludeFiles)
   check_include_files ("unistd.h" HAVE_UNISTD_H)
   check_include_files ("stdarg.h" HAVE_STDARG_H)
   if (HAVE_UNISTD_H)
      add_definitions (-DHAVE_UNISTD_H)
      list (APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_UNISTD_H)
   endif ()
   if (HAVE_STDARG_H)
      add_definitions (-DHAVE_STDARG_H)
      list (APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDARG_H)
   endif ()
   set (MONGOC_ENABLE_COMPRESSION 1)
   set (MONGOC_ENABLE_COMPRESSION_ZLIB 1)
else ()
   message (STATUS "Disabling zlib compression")
endif ()

if (NOT ENABLE_ZSTD STREQUAL OFF)
   message (STATUS "Searching for compression library zstd")
   find_package(PkgConfig)
   pkg_check_modules (ZSTD libzstd)

   if (NOT ZSTD_FOUND)
      if (ENABLE_ZSTD MATCHES "ON")
         message (FATAL_ERROR "  Not found")
      else ()
         message (STATUS "  Not found")
      endif ()
   # The compression format below this version isn't supported. See SERVER-43070
   elseif (${ZSTD_VERSION} VERSION_LESS "0.8.0")
      if (ENABLE_ZSTD MATCHES "ON")
         message (FATAL_ERROR "Detected zstd version ${ZSTD_VERSION} but version 0.8.0 required")
      else ()
         message (STATUS "Detected zstd version ${ZSTD_VERSION} but version 0.8.0 required")
      endif ()
   else ()
      message (STATUS "  Found zstd version ${ZSTD_VERSION} in ${ZSTD_INCLUDE_DIRS}")
      set (MONGOC_ENABLE_COMPRESSION 1)
      set (MONGOC_ENABLE_COMPRESSION_ZSTD 1)

      include_directories (${ZSTD_INCLUDE_DIRS})
      link_directories (${ZSTD_LIBRARY_DIRS})
      set (MONGOC_ZSTD_LIBRARIES ${ZSTD_LINK_LIBRARIES})
   endif()
endif()

add_library(_mongoc-dependencies INTERFACE)
add_library(mongo::detail::c_dependencies ALIAS _mongoc-dependencies)
target_link_libraries(_mongoc-dependencies INTERFACE mongo::detail::c_platform)
target_link_libraries(_mongoc-dependencies INTERFACE mongo::detail::c_platform $<$<PLATFORM_ID:Windows>:advapi32.lib>)
install(TARGETS _mongoc-dependencies EXPORT mongoc-targets)
set_property(TARGET _mongoc-dependencies PROPERTY EXPORT_NAME detail::c_dependencies)

# d888888b db      .d8888.
# `~~88~~' 88      88'  YP
#    88    88      `8bo.
#    88    88        `Y8b.
#    88    88booo. db   8D
#    YP    Y88888P `8888Y'

# Pick the TLS library to use.
function(_pick_which_tls_lib ssl_opt)
   # Initial value, if not later set:
   set_property(DIRECTORY PROPERTY _mongoc-tls-backend OFF)
   if(ssl_opt STREQUAL "AUTO")
      # Try to pick one automatically
      _auto_pick_tls_lib()
   elseif(ssl_opt)
      # The user named a TLS library specifically. Use that one:
      _use_named_tls_lib("${ssl_opt}")
   else()
      # User has disabled TLS selection
   endif()
endfunction()

# Attempt to automatically find and use a TLS library for the current platform
function(_auto_pick_tls_lib)
   if(WIN32)
      # Windows has SecureChannel
      _use_named_tls_lib(WINDOWS)
   elseif(APPLE)
      # Apple has SecureTransport
      _use_named_tls_lib(DARWIN)
   else()
      # Try to find one of the common open-source TLS libraries
      find_package(OpenSSL)
      if(OpenSSL_FOUND)
         _use_named_tls_lib(OPENSSL)
      else()
         # No OpenSSL. What about LibreSSL?
         find_package(LibreSSL)
         if(LibreSSL_FOUND)
            message(DEPRECATION "LibreSSL was automatically chosen as the TLS library. Support for LibreSSL is deprecated and may be removed in a future major release. Use ENABLE_SSL option to specify a different TLS library.")
            _use_named_tls_lib(LIBRESSL)
         endif()
      endif()
   endif()
endfunction()

# Per-backend link libs/options:
set(SecureTransport/LINK_LIBRARIES "-framework CoreFoundation" "-framework Security")
set(SecureTransport/pkg_config_LIBS -framework Corefoundation -framework Security)
set(SecureChannel/LINK_LIBRARIES secur32.lib crypt32.lib Bcrypt.lib)
set(SecureChannel/pkg_config_LIBS ${SecureChannel/LINK_LIBRARIES})
set(LibreSSL/LINK_LIBRARIES LibreSSL::TLS LibreSSL::Crypto)
set(LibreSSL/pkg_config_LIBS -ltls -lcrypto)
set(OpenSSL/LINK_LIBRARIES OpenSSL::SSL OpenSSL::Crypto $<$<PLATFORM_ID:Windows>:crypt32.lib>)
set(OpenSSL/pkg_config_LIBS -lssl -lcrypto $<$<PLATFORM_ID:Windows>:crypt32.lib>)
# Use *exactly* the TLS library identified by the given name, which is one of
#  `OPENSSL`, `LIBRESSL`, `DARWIN`, or `WINDOWS`.
function(_use_named_tls_lib libname)
   # Use this property to track what package we import for our TLS libraries:
   set_property(DIRECTORY PROPERTY _mongoc-tls-package NO)
   if(libname STREQUAL "OPENSSL")
      find_package(OpenSSL REQUIRED)
      set(backend OpenSSL)
      set_property(DIRECTORY PROPERTY _mongoc-tls-package OpenSSL)
   elseif(libname STREQUAL "LIBRESSL")
      find_package(LibreSSL REQUIRED)
      set(backend LibreSSL)
      install(
         FILES "${mongo-c-driver_SOURCE_DIR}/build/cmake/FindLibreSSL.cmake"
         DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mongoc-${MONGOC_API_VERSION}/3rdParty"
         )
      set_property(DIRECTORY PROPERTY _mongoc-tls-package LibreSSL)
   elseif(libname STREQUAL "DARWIN")
      set(backend SecureTransport)
   elseif(libname STREQUAL "WINDOWS")
      set(backend SecureChannel)
   else()
      message(FATAL_ERROR "Unknown TLS library requested: “${libname}”")
   endif()
   add_library(_mongoc-tls_backend INTERFACE)
   install(TARGETS _mongoc-tls_backend EXPORT mongoc-targets)
   target_link_libraries(_mongoc-dependencies INTERFACE _mongoc-tls_backend)
   set_property(TARGET _mongoc-tls_backend PROPERTY EXPORT_NAME detail::c_tls_backend)
   target_link_libraries(_mongoc-tls_backend INTERFACE ${${backend}/LINK_LIBRARIES})
   target_link_options(_mongoc-tls_backend INTERFACE ${${backend}/LINK_OPTIONS})
   set_property(DIRECTORY PROPERTY _mongoc-tls-backend "${backend}")
endfunction()

_pick_which_tls_lib("${ENABLE_SSL}")
# This property will be set by _pick_which_tls_lib:
get_directory_property(TLS_BACKEND _mongoc-tls-backend)
message(STATUS "libmongoc TLS : ${TLS_BACKEND}")
# Used by *-config.cmake to do a find_dependency():
get_directory_property(TLS_IMPORT_PACKAGE _mongoc-tls-package)
set_package_properties(
   OpenSSL PROPERTIES
   DESCRIPTION "the standard open-source implementation of TLS, X509, and more"
   TYPE OPTIONAL
   PURPOSE "Provides a cryptography and TLS backend"
)
set_package_properties(
   LibreSSL PROPERTIES
   DESCRIPTION "an alternative implementation of the OpenSSL interface, created by the OpenBSD project"
   TYPE OPTIONAL
   PURPOSE "Provides a cryptography and TLS backend"
)

mongo_bool01(MONGOC_ENABLE_SSL [[TLS_BACKEND]])
mongo_bool01(MONGOC_ENABLE_SSL_SECURE_CHANNEL [[TLS_BACKEND STREQUAL "SecureChannel"]])
mongo_bool01(MONGOC_ENABLE_SSL_SECURE_TRANSPORT [[TLS_BACKEND STREQUAL "SecureTransport"]])
mongo_bool01(MONGOC_ENABLE_SSL_OPENSSL [[TLS_BACKEND STREQUAL "OpenSSL"]])
mongo_bool01(MONGOC_ENABLE_SSL_LIBRESSL [[TLS_BACKEND STREQUAL "LibreSSL"]])

mongo_bool01(MONGOC_ENABLE_CRYPTO [[TLS_BACKEND]])
mongo_bool01(MONGOC_ENABLE_CRYPTO_LIBCRYPTO [[MONGOC_ENABLE_SSL_OPENSSL OR MONGOC_ENABLE_SSL_LIBRESSL]])
mongo_bool01(MONGOC_ENABLE_CRYPTO_CNG [[MONGOC_ENABLE_SSL_SECURE_CHANNEL]])
mongo_bool01(MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO [[MONGOC_ENABLE_SSL_SECURE_TRANSPORT]])
mongo_bool01(MONGOC_ENABLE_CRYPTO_SYSTEM_PROFILE [[ENABLE_CRYPTO_SYSTEM_PROFILE]])
add_feature_info("TLS" "${MONGOC_ENABLE_SSL}" "for secure network communication (${TLS_BACKEND})")
add_feature_info("Cryptography" "${MONGOC_ENABLE_CRYPTO}" "cryptographic primitives (${TLS_BACKEND})")

include(CMakePushCheckState)
include(CheckSymbolExists)
if(TLS_BACKEND STREQUAL "OpenSSL")
   # Check for newer OpenSSL string functions
   cmake_push_check_state()
   list(APPEND CMAKE_REQUIRED_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
   check_symbol_exists(
      ASN1_STRING_get0_data
      "openssl/asn1.h"
      HAVE_ASN1_STRING_GET0_DATA
   )
   cmake_pop_check_state()
endif()
mongo_bool01(MONGOC_HAVE_ASN1_STRING_GET0_DATA [[HAVE_ASN1_STRING_GET0_DATA]])

if(ENABLE_CRYPTO_SYSTEM_PROFILE AND NOT MONGOC_ENABLE_SSL_OPENSSL)
   message (FATAL_ERROR "ENABLE_CRYPTO_SYSTEM_PROFILE is only available with OpenSSL")
endif()

set(_aws_feature_desc "authenticate with MongoDB servers using credentials from AWS instance metadata")
if(ENABLE_MONGODB_AWS_AUTH)
   # We may want AWS auth
   if(NOT MONGOC_ENABLE_SSL)
      # No TLS libs
      if(ENABLE_MONGODB_AWS_AUTH STREQUAL "AUTO")
         # Okay: Just turn it off
         message(STATUS "Note: AWS Authentication was disabled automatically because no TLS library is found/enabled")
         set(_enable_aws_auth FALSE)
         add_feature_info("AWS Authentication" OFF "${_aws_feature_desc}. (Disabled automatically: No TLS backend available)")
      else()
         # Bad
         message(FATAL_ERROR "MongoDB AWS Authentication requires a TLS library, no TLS library was found/enabled")
      endif()
   endif()
   set(_enable_aws_auth TRUE)
   add_feature_info("AWS Authentication" ON "${_aws_feature_desc}")
else()
   # AWS Auth is explicitly disabled
   set(_enable_aws_auth FALSE)
   add_feature_info("AWS Authentication" OFF "${_aws_feature_desc}. (Manually disabled)")
endif()

# .d8888.  .d8b.  .d8888. db
# 88'  YP d8' `8b 88'  YP 88
# `8bo.   88ooo88 `8bo.   88
#   `Y8b. 88~~~88   `Y8b. 88
# db   8D 88   88 db   8D 88booo.
# `8888Y' YP   YP `8888Y' Y88888P

function(_pick_sasl sasl)
   if(sasl STREQUAL "AUTO")
      if(WIN32)
         # On Windows: Use SSPI
         _use_sasl("SSPI")
      else()
         # Other platforms: Use Cyrus (aka libsasl2)
         find_package(SASL2 2.0)
         if(SASL2_FOUND)
            # Found it
            _use_sasl("CYRUS")
         else()
            # Nope. That's okay, just turn SASL off
            set_property(DIRECTORY PROPERTY _mongoc-sasl-backend NOTFOUND)
         endif()
      endif()
   elseif(sasl)
      _use_sasl("${sasl}")
   else()
      set_property(DIRECTORY PROPERTY _mongoc-sasl-backend OFF)
   endif()
endfunction()

# Use the named SASL library. Must be either "CYRUS" or "SSPI"
function(_use_sasl libname)
   add_library(_mongoc-sasl_backend INTERFACE)
   set_property(TARGET _mongoc-sasl_backend PROPERTY EXPORT_NAME detail::c_sasl_backend)
   target_link_libraries(_mongoc-dependencies INTERFACE _mongoc-sasl_backend)
   install(TARGETS _mongoc-sasl_backend EXPORT mongoc-targets)
   if(libname STREQUAL "SSPI")
      target_link_libraries(_mongoc-sasl_backend INTERFACE secur32.lib crypt32.lib Shlwapi.lib)
      set(backend "SSPI")
   elseif(libname STREQUAL "CYRUS")
      find_package(SASL2 2.0 REQUIRED)
      target_link_libraries(_mongoc-sasl_backend INTERFACE SASL2::SASL2)
      install(FILES "${mongo-c-driver_SOURCE_DIR}/build/cmake/FindSASL2.cmake" DESTINATION "${MONGOC_TARGETS_INSTALL_DIR}/3rdParty")
      set(backend "Cyrus")
   else()
      message(FATAL_ERROR "Unknown SASL backend “${libname}”")
   endif()
   set_property(DIRECTORY PROPERTY _mongoc-sasl-backend "${backend}")
endfunction()

_pick_sasl("${ENABLE_SASL}")
# Variable is used here, as well as within the mongoc-config.cmake template:
get_directory_property(SASL_BACKEND _mongoc-sasl-backend)
message(STATUS "Using SASL backend : ${SASL_BACKEND}")
set_package_properties(SASL2 PROPERTIES
   DESCRIPTION "Cyrus implementation of SASL"
   TYPE OPTIONAL
   PURPOSE "Provides libmongoc SASL authentication support"
   )

if(SASL_BACKEND STREQUAL "Cyrus")
   cmake_push_check_state()
   list(APPEND CMAKE_REQUIRED_LIBRARIES SASL2::SASL2)
   check_symbol_exists(
      sasl_client_done
      sasl/sasl.h
      SASL2_HAVE_SASL_CLIENT_DONE
   )
   cmake_pop_check_state()
endif()

mongo_bool01(MONGOC_HAVE_SASL_CLIENT_DONE [[SASL2_HAVE_SASL_CLIENT_DONE]])
mongo_bool01(MONGOC_ENABLE_SASL_SSPI [[SASL_BACKEND STREQUAL "SSPI"]])
mongo_bool01(MONGOC_ENABLE_SASL_CYRUS [[SASL_BACKEND STREQUAL "Cyrus"]])
mongo_bool01(MONGOC_ENABLE_SASL [[MONGOC_ENABLE_SASL_SSPI OR MONGOC_ENABLE_SASL_CYRUS]])
add_feature_info(
   "SASL Authentication"
   "${MONGOC_ENABLE_SASL}"
   "authenticate with MongoDB servers using SASL: “Simple Authentication and Security Layer” (${SASL_BACKEND})"
)

if (ENABLE_AUTOMATIC_INIT_AND_CLEANUP)
   set (MONGOC_NO_AUTOMATIC_GLOBALS 0)
else ()
   set (MONGOC_NO_AUTOMATIC_GLOBALS 1)
endif ()

if (WIN32)
   SET (CMAKE_EXTRA_INCLUDE_FILES "ws2tcpip.h")
else ()
   SET (CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h")
endif ()
CHECK_TYPE_SIZE (socklen_t HAVE_SOCKLEN)
SET (CMAKE_EXTRA_INCLUDE_FILES)

if (HAVE_SOCKLEN)
   set (MONGOC_HAVE_SOCKLEN 1)
   set (MONGOC_SOCKET_ARG3 "socklen_t")
else ()
   set (MONGOC_HAVE_SOCKLEN 0)
   set (MONGOC_SOCKET_ARG3 "int")
endif ()

# Find name resolution libaries. Also sets definitions used in configure_file():
include(ResSearch)

function (mongoc_get_accept_args ARG2 ARG3)
   SET (VAR 0)
   foreach (ARG2_VAL "struct sockaddr" "void")
   foreach (ARG3_VAL "socklen_t" "size_t" "int")

   MATH (EXPR VAR "${VAR}+1")

   FILE (WRITE ${CMAKE_CURRENT_BINARY_DIR}/accept_test${VAR}.c
   "#include <sys/types.h>
    #include <sys/socket.h>

    int main ()
    {
      int a = 0;
      ${ARG2_VAL} *b = 0;
      ${ARG3_VAL} *c = 0;
      accept (a, b, c);
      return 0;
   }
   ")

   TRY_COMPILE (RES ${CMAKE_CURRENT_BINARY_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}/accept_test${VAR}.c CMAKE_FLAGS
   "-Werror -DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" OUTPUT_VARIABLE LOG2)

   if (RES)
      message (
         STATUS
         "Detected parameters: accept (int, ${ARG2_VAL} *, ${ARG3_VAL} *)")

      set (${ARG2} ${ARG2_VAL} PARENT_SCOPE)
      set (${ARG3} ${ARG3_VAL} PARENT_SCOPE)
      return ()
   endif ()

   endforeach ()
   endforeach ()

endfunction ()

# Reasonable defaults.
set (MONGOC_SOCKET_ARG2 "struct sockaddr")
set (MONGOC_SOCKET_ARG3 "socklen_t")

if (NOT WIN32)
   mongoc_get_accept_args (MONGOC_SOCKET_ARG2 MONGOC_SOCKET_ARG3)
endif ()

set (MONGOC_CC ${CMAKE_C_COMPILER})
set (MONGOC_USER_SET_CFLAGS ${CMAKE_C_FLAGS})
set (MONGOC_USER_SET_LDFLAGS ${CMAKE_EXE_LINKER_FLAGS})

if (ENABLE_TRACING)
   set (MONGOC_TRACE 1)
else ()
   set (MONGOC_TRACE 0)
endif ()

# Sets SNAPPY_LIBRARIES and SNAPPY_INCLUDE_DIRS.
include (FindSnappy)
if (SNAPPY_INCLUDE_DIRS)
   set (MONGOC_ENABLE_COMPRESSION 1)
   include_directories ("${SNAPPY_INCLUDE_DIRS}")
endif ()

mongo_bool01 (MONGOC_ENABLE_SHM_COUNTERS ENABLE_SHM_COUNTERS)

# Configure In-Use Encryption
set (MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION 0)
if (NOT ENABLE_CLIENT_SIDE_ENCRYPTION MATCHES "AUTO|ON|OFF")
   message (FATAL_ERROR, "ENABLE_CLIENT_SIDE_ENCRYPTION option must be AUTO, ON, or OFF")
endif ()

if (NOT MONGOC_ENABLE_SSL)
   if (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL ON)
      message (FATAL_ERROR "SSL disabled, but is required for In-Use Encryption support.")
   elseif (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL AUTO)
      message (STATUS "SSL disabled. Configuring without In-Use Encryption support.")
   endif ()
elseif (NOT ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL OFF)
   message (STATUS "Searching for libmongocrypt")
   if (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL ON)
      # do not suppress log output if find_package cannot find libmongocrypt
      find_package (mongocrypt)
   elseif (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL AUTO)
      find_package (mongocrypt QUIET)
   endif ()

   if (mongocrypt_FOUND AND "${mongocrypt_VERSION}" VERSION_LESS 1.12.0)
      message (STATUS "  libmongocrypt found at ${mongocrypt_DIR}")
      message (STATUS "  libmongocrypt version ${mongocrypt_VERSION} found")
      message (STATUS "  libmongocrypt version 1.12.0 is required to enable In-Use Encryption Support.")
      set (REQUIRED_MONGOCRYPT_VERSION_FOUND OFF)
   elseif (mongocrypt_FOUND)
      set (REQUIRED_MONGOCRYPT_VERSION_FOUND ON)
   else ()
      set (REQUIRED_MONGOCRYPT_VERSION_FOUND OFF)
   endif ()

   if (REQUIRED_MONGOCRYPT_VERSION_FOUND)
      set (LIBMONGOCRYPT_TARGET mongo::mongocrypt)
      get_target_property (LIBMONGOCRYPT_RUNTIME_LIBRARY mongo::mongocrypt LOCATION)
      get_filename_component(LIBMONGOCRYPT_LIBRARY_LOCATION ${LIBMONGOCRYPT_RUNTIME_LIBRARY} DIRECTORY)
      find_library (LIBMONGOCRYPT_LIBRARY NAMES mongocrypt PATHS ${LIBMONGOCRYPT_LIBRARY_LOCATION})
      get_target_property (LIBMONGOCRYPT_INCLUDE_DIRECTORIES mongo::mongocrypt INTERFACE_INCLUDE_DIRECTORIES)
      message (STATUS "  libmongocrypt found at ${LIBMONGOCRYPT_LIBRARY}")
      message (STATUS "  libmongocrypt include path ${LIBMONGOCRYPT_INCLUDE_DIRECTORIES}")
      message (STATUS "  libmongocrypt version ${mongocrypt_VERSION}")
      set (MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION 1)
   elseif (ENABLE_CLIENT_SIDE_ENCRYPTION STREQUAL ON)
      message (FATAL_ERROR "Required library (libmongocrypt) not found.")
   else ()
      message (STATUS "libmongocrypt not found. Configuring without In-Use Encryption support.")
   endif ()
endif ()

CHECK_STRUCT_HAS_MEMBER("struct sockaddr_storage" ss_family "sys/socket.h" MONGOC_HAVE_SS_FAMILY)
if (NOT MONGOC_HAVE_SS_FAMILY)
   set (MONGOC_HAVE_SS_FAMILY 0)
else ()
   set (MONGOC_HAVE_SS_FAMILY 1)
endif ()

# Check if BCryptDeriveKeyPBKDF2 is defined in bcrypt.h
if (WIN32 AND MONGOC_ENABLE_CRYPTO_CNG)
   cmake_push_check_state()
   list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_WIN32_WINNT=0x0601)
   list(APPEND CMAKE_REQUIRED_LIBRARIES Bcrypt.lib)
   check_symbol_exists (BCryptDeriveKeyPBKDF2 "windows.h;bcrypt.h" HAVE_BCRYPT_PBKDF2)
   cmake_pop_check_state()
endif ()

if (HAVE_BCRYPT_PBKDF2)
   set (MONGOC_HAVE_BCRYPT_PBKDF2 1)
else ()
   set (MONGOC_HAVE_BCRYPT_PBKDF2 0)
endif ()


set (MONGOC_SOURCES
   ${PROJECT_SOURCE_DIR}/src/mongoc/mcd-azure.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mcd-nsinfo.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mcd-rpc.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-aggregate.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-apm.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-array.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-async.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-async-cmd.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-buffer.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulk-operation.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-change-stream.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-pool.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-side-encryption.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-aws.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-sasl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-collection.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-compression.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-counters.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypt.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-array.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-cmd.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-change-stream.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-cmd-deprecated.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find-cmd.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-find-opquery.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-legacy.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor-array.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-database.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-error.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-deprioritized-servers.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-flags.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-find-and-modify.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-generation-map.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket-file.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-page.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-handshake.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-host-list.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-http.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-index.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-interrupt.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-list.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-linux-distro-scanner.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-log.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-log-and-monitor-private.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher-op.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-memcmp.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cmd.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opcode.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-optional.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opts-helpers.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opts.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-queue.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-concern.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-prefs.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rpc.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-api.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-description.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-stream.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-session.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-monitor.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-set.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-shared.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-socket.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-buffered.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-file.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs-download.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs-upload.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-socket.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-structured-log.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-timeout.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-background-monitoring.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description-apm.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-scanner.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ts-pool.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-uri.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-util.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version-functions.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-command.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-concern.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/service-gcp.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-atomic.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-b64.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-md5.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-json.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-string.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-oid.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/src/common-thread.c

   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-scram.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ssl.c

   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-libressl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-libressl.c

   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-cng.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-cng.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-secure-channel.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-secure-channel.c

   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-common-crypto.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-common-crypto.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-secure-transport.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-secure-transport.c

   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-crypto-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl-bio.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-openssl.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ocsp-cache.c
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.c
)

if (MONGOC_ENABLE_SASL)
   list (APPEND MONGOC_SOURCES ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-sasl.c)
   if (MONGOC_ENABLE_SASL_CYRUS)
      message (STATUS "Compiling against Cyrus SASL")
      list (APPEND MONGOC_SOURCES ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-cyrus.c)
      list (APPEND MONGOC_SOURCES ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cyrus.c)
   elseif (MONGOC_ENABLE_SASL_SSPI)
      message (STATUS "Compiling against Windows SSPI")
      list (APPEND MONGOC_SOURCES ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cluster-sspi.c)
      list (APPEND MONGOC_SOURCES ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-sspi.c)
   endif ()
else ()
   message (STATUS "SASL disabled")
endif ()

# Enable unconditional warnings-as-errors for our source code.
set_property(SOURCE ${MONGOC_SOURCES} APPEND PROPERTY COMPILE_OPTIONS ${mongoc-warning-options})

list (APPEND SOURCES ${MONGOC_SOURCES})

set (HEADERS
   ${PROJECT_BINARY_DIR}/src/mongoc/mongoc-config.h
   ${PROJECT_BINARY_DIR}/src/mongoc/mongoc-version.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-apm.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulk-operation.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-change-stream.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-pool.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-side-encryption.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-collection.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cursor.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-database.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-error.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-flags.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-find-and-modify.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-bucket.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-page.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-gridfs-file-list.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-handshake.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-host-list.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-init.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-index.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-iovec.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-log.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-macros.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-matcher.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-opcode.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-optional.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-prelude.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-concern.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-read-prefs.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-api.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-server-description.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-client-session.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-sleep.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-socket.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-libressl.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls-openssl.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-buffered.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-file.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-gridfs.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-socket.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-structured-log.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-topology-description.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-uri.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version-functions.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-write-concern.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-rand.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-stream-tls.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-ssl.h
   ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-bulkwrite.h
)

set (HEADERS_FORWARDING
   ${PROJECT_SOURCE_DIR}/src/mongoc/forwarding/mongoc.h
)

configure_file (
   "${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-config.h.in"
   "${PROJECT_BINARY_DIR}/src/mongoc/mongoc-config.h"
)

configure_file (
   "${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-version.h.in"
   "${PROJECT_BINARY_DIR}/src/mongoc/mongoc-version.h"
)

if (ENABLE_APPLE_FRAMEWORK)
   configure_file (
      "${PROJECT_SOURCE_DIR}/src/mongoc/modules/module.modulemap.in"
      "${PROJECT_BINARY_DIR}/src/mongoc/modules/module.modulemap"
   )
endif ()

set (LIBRARIES
   ${SNAPPY_LIBRARIES} ${ZLIB_LIBRARIES} ${MONGOC_ZSTD_LIBRARIES} ${LIBMONGOCRYPT_LIBRARY}
)
set (STATIC_LIBRARIES
   ${SNAPPY_LIBRARIES} ${ZLIB_LIBRARIES} ${MONGOC_ZSTD_LIBRARIES} ${LIBMONGOCRYPT_LIBRARY}
)

# utf8proc configuration
find_package(Utf8Proc REQUIRED)
set(UTF8PROC_INCLUDE_DIRS, "")
if (USE_BUNDLED_UTF8PROC)
   set (
      UTF8PROC_INCLUDE_DIRS
      "${mongo-c-driver_SOURCE_DIR}/src/utf8proc-2.8.0"
   )
   list(APPEND SOURCES $<TARGET_OBJECTS:utf8proc_obj>)
else()
   target_link_libraries(_mongoc-dependencies INTERFACE utf8proc)
endif()

if(ENABLE_SRV)
   # Interface target defined by ResSearch.cmake:
   if(NOT TARGET mongo::detail::c_resolve)
      message(SEND_ERROR "ENABLE_SRV is “${ENABLE_SRV}”, but we were unable to find a name resolution library")
   endif()
   target_link_libraries(_mongoc-dependencies INTERFACE mongo::detail::c_resolve)
endif()

if (MONGOC_ENABLE_MONGODB_AWS_AUTH)
   set (KMS_MSG_SOURCES
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/hexlify.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_b64.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_caller_identity_request.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_crypto_apple.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_crypto_libcrypto.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_crypto_none.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_crypto_windows.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_decrypt_request.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_encrypt_request.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_kmip_response_parser.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_kv_list.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_message.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_port.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_request.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_request_opt.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_request_str.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_response.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/kms_response_parser.c
      ${mongo-c-driver_SOURCE_DIR}/src/kms-message/src/sort.c
   )

   # Disable warnings on bundled kms_message source files.
   set_source_files_properties (${KMS_MSG_SOURCES} PROPERTIES COMPILE_FLAGS -w)
   set (SOURCES ${SOURCES} ${KMS_MSG_SOURCES})

   set (KMS_MSG_DEFINITIONS KMS_MSG_STATIC KMS_MESSAGE_ENABLE_CRYPTO)
   include (TestBigEndian)
   TEST_BIG_ENDIAN (KMS_BIG_ENDIAN)
   if (KMS_BIG_ENDIAN)
      set (KMS_MSG_DEFINITIONS ${KMS_MSG_DEFINITIONS} KMS_MESSAGE_BIG_ENDIAN)
   else ()
      set (KMS_MSG_DEFINITIONS ${KMS_MSG_DEFINITIONS} KMS_MESSAGE_LITTLE_ENDIAN)
   endif ()

   if (MONGOC_ENABLE_CRYPTO_CNG)
      set (KMS_MSG_DEFINITIONS ${KMS_MSG_DEFINITIONS} KMS_MESSAGE_ENABLE_CRYPTO_CNG)
   elseif (MONGOC_ENABLE_CRYPTO_COMMON_CRYPTO)
      set (KMS_MSG_DEFINITIONS ${KMS_MSG_DEFINITIONS} KMS_MESSAGE_ENABLE_CRYPTO_COMMON_CRYPTO)
   elseif(MONGOC_ENABLE_CRYPTO_LIBCRYPTO)
      set (KMS_MSG_DEFINITIONS ${KMS_MSG_DEFINITIONS} KMS_MESSAGE_ENABLE_CRYPTO_LIBCRYPTO)
   else ()
      message (FATAL_ERROR "MONGODB-AWS requires a crypto library")
   endif()
endif ()

if (MONGOC_ENABLE_STATIC_BUILD)
   add_library (mcd_rpc STATIC EXCLUDE_FROM_ALL ${PROJECT_SOURCE_DIR}/src/mongoc/mcd-rpc.c)
   target_include_directories (mcd_rpc PUBLIC ${PROJECT_SOURCE_DIR}/src)
   target_link_libraries (mcd_rpc PUBLIC ${BSON_STATIC_LIBRARIES})
   if (NOT WIN32 AND ENABLE_PIC)
      target_compile_options (mcd_rpc PUBLIC -fPIC)
   endif ()
   target_compile_definitions (mcd_rpc PUBLIC ${BSON_STATIC_PUBLIC_DEFINITIONS})
   set_target_properties (mcd_rpc PROPERTIES OUTPUT_NAME "mcd-rpc")
endif ()

set_property(
   SOURCE ${PROJECT_SOURCE_DIR}/src/mongoc/mongoc-cyrus.c
   APPEND PROPERTY COMPILE_DEFINITIONS
   "MONGOC_CYRUS_PLUGIN_PATH_PREFIX=$<IF:$<STREQUAL:${CYRUS_PLUGIN_PATH_PREFIX},>,NULL,\"${CYRUS_PLUGIN_PATH_PREFIX}\">"
)

set (
   UTHASH_INCLUDE_DIR
   "${mongo-c-driver_SOURCE_DIR}/src/uthash"
)

if (ENABLE_SHARED)
   add_library (mongoc_shared SHARED ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING})
   if(WIN32)
      # Add resource-definition script for Windows shared library (.dll).
      configure_file(libmongoc.rc.in libmongoc.rc)
      target_sources(mongoc_shared PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/libmongoc.rc)
   endif()
   set_target_properties (mongoc_shared PROPERTIES CMAKE_CXX_VISIBILITY_PRESET hidden)
   target_link_libraries (mongoc_shared PRIVATE ${LIBRARIES} PUBLIC ${BSON_LIBRARIES} mongo::detail::c_dependencies)
   target_include_directories (mongoc_shared PRIVATE ${ZLIB_INCLUDE_DIRS})
   target_include_directories (mongoc_shared PRIVATE ${UTF8PROC_INCLUDE_DIRS})
   target_include_directories (mongoc_shared PRIVATE ${LIBMONGOCRYPT_INCLUDE_DIRECTORIES})
   target_include_directories (mongoc_shared PRIVATE ${UTHASH_INCLUDE_DIR})
   if (MONGOC_ENABLE_MONGODB_AWS_AUTH)
      target_include_directories (mongoc_shared PRIVATE "${mongo-c-driver_SOURCE_DIR}/src/kms-message/src")
      if (APPLE)
         set_target_properties (mongoc_shared PROPERTIES LINK_FLAGS "-Wl,-unexported_symbols_list,\"${mongo-c-driver_SOURCE_DIR}/build/cmake/libmongoc-hidden-symbols.txt\"")
      elseif (UNIX)
         set_target_properties (mongoc_shared PROPERTIES LINK_FLAGS "-Wl,--version-script=\"${mongo-c-driver_SOURCE_DIR}/build/cmake/libmongoc-hidden-symbols.map\"")
      endif ()

   endif ()
   target_compile_definitions (mongoc_shared
      PRIVATE
         MONGOC_COMPILATION
         ${KMS_MSG_DEFINITIONS}
         MCOMMON_NAME_PREFIX=_mongoc_mcommon
   )

   if (USE_BUNDLED_UTF8PROC)
      target_compile_definitions (mongoc_shared PRIVATE UTF8PROC_STATIC)
   endif ()

   # Several directories in the source and build trees contain headers we would like
   # include via relative reference, but they all end up in the same install path
   target_include_directories (
      mongoc_shared
      PUBLIC
         $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>
         $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
         $<BUILD_INTERFACE:${mongo-c-driver_SOURCE_DIR}/src/common/src>
         $<BUILD_INTERFACE:${mongo-c-driver_BINARY_DIR}/src>
         $<BUILD_INTERFACE:${mongo-c-driver_BINARY_DIR}/src/common/src>
   )

   set_target_properties (mongoc_shared PROPERTIES
      OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}-${MONGOC_API_VERSION}"
      VERSION 0.0.0
      SOVERSION 0
      pkg_config_REQUIRES "libbson-1.0"
      )
   mongo_generate_pkg_config(mongoc_shared INSTALL RENAME libmongoc-${MONGOC_API_VERSION}.pc)

   if (ENABLE_APPLE_FRAMEWORK)
      set_target_properties (mongoc_shared PROPERTIES
         FRAMEWORK TRUE
         MACOSX_FRAMEWORK_BUNDLE_VERSION ${MONGOC_VERSION}
         MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${MONGOC_VERSION}
         MACOSX_FRAMEWORK_IDENTIFIER org.mongodb.mongoc
         OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}"
         PUBLIC_HEADER "${HEADERS}"
      )
   endif () # ENABLE_APPLE_FRAMEWORK

   add_executable (mongoc-stat ${mongo-c-driver_SOURCE_DIR}/src/tools/mongoc-stat.c)
   target_compile_options (mongoc-stat PRIVATE ${mongoc-warning-options})
   target_link_libraries (mongoc-stat mongoc_shared ${LIBRARIES})

   # mongoc-stat works if shared memory performance counters are enabled.
   if (ENABLE_SHM_COUNTERS)
      install (TARGETS mongoc-stat
               EXPORT mongoc_targets
               RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
   endif () # ENABLE_SHM_COUNTERS

endif () # ENABLE_SHARED

if (MONGOC_ENABLE_STATIC_BUILD)
   add_library (mongoc_static STATIC ${SOURCES} ${HEADERS} ${HEADERS_FORWARDING})
   target_link_libraries (mongoc_static PUBLIC ${STATIC_LIBRARIES} ${BSON_STATIC_LIBRARIES} mongo::detail::c_dependencies)
   if (NOT WIN32 AND ENABLE_PIC)
      target_compile_options (mongoc_static PUBLIC -fPIC)
      message (STATUS "Adding -fPIC to compilation of mongoc_static components")
   endif ()
   if(ENABLE_SRV AND RESOLVE_LIB_NAME)
      # The static library needs to link to the resolver in pkg-config:
      set_property(TARGET mongoc_static APPEND PROPERTY pkg_config_LIBS "-l${RESOLVE_LIB_NAME}")
   endif()
   if(SASL_BACKEND STREQUAL "Cyrus")
      set_property(TARGET mongoc_static APPEND PROPERTY pkg_config_LIBS "-lsasl2")
   endif()

   set_property(TARGET mongoc_static APPEND PROPERTY pkg_config_LIBS ${${TLS_BACKEND}/pkg_config_LIBS})
   target_include_directories (mongoc_static PRIVATE ${ZLIB_INCLUDE_DIRS})
   target_include_directories (mongoc_static PRIVATE ${UTF8PROC_INCLUDE_DIRS})
   target_include_directories (mongoc_static PRIVATE ${LIBMONGOCRYPT_INCLUDE_DIRECTORIES})
   target_include_directories (mongoc_static PRIVATE ${UTHASH_INCLUDE_DIR})
   if (MONGOC_ENABLE_MONGODB_AWS_AUTH)
      target_include_directories (mongoc_static PRIVATE "${mongo-c-driver_SOURCE_DIR}/src/kms-message/src")
   endif ()
   target_compile_definitions (mongoc_static
      PUBLIC
         MONGOC_STATIC
         ${BSON_STATIC_PUBLIC_DEFINITIONS}
      PRIVATE
         MONGOC_COMPILATION
         ${KMS_MSG_DEFINITIONS}
         MCOMMON_NAME_PREFIX=_mongoc_mcommon
   )
   if (USE_BUNDLED_UTF8PROC)
      target_compile_definitions (mongoc_static PRIVATE UTF8PROC_STATIC)
   endif ()
   # Several directories in the source and build trees contain headers we would like
   # include via relative reference, but they all end up in the same install path
   target_include_directories (
      mongoc_static
      PUBLIC
         $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/src>
         $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
         $<BUILD_INTERFACE:${mongo-c-driver_SOURCE_DIR}/src/common/src>
         $<BUILD_INTERFACE:${mongo-c-driver_BINARY_DIR}/src>
         $<BUILD_INTERFACE:${mongo-c-driver_BINARY_DIR}/src/common/src>
   )
   set_target_properties (mongoc_static PROPERTIES
      VERSION 0.0.0
      OUTPUT_NAME "${MONGOC_OUTPUT_BASENAME}-static-${MONGOC_API_VERSION}"
      pkg_config_REQUIRES "libbson-static-1.0"
      )
   if(MONGOC_ENABLE_STATIC_INSTALL)
      mongo_generate_pkg_config (mongoc_static FILENAME libmongoc-static-${MONGOC_API_VERSION}.pc INSTALL)
   endif()
endif ()


set (test-libmongoc-sources
   ${mongo-c-driver_SOURCE_DIR}/src/common/tests/test-common-atomic.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/tests/test-common-cmp.c
   ${mongo-c-driver_SOURCE_DIR}/src/common/tests/test-common-oid.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/corpus-test.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/corpus-test.h
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-atomic.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-b64.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bcon-basic.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bcon-extract.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson-cmp.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson-corpus.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson-error.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson-sync.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson-version.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-bson.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-clock.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-decimal128.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-endian.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-iso8601.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-iter.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-json.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-oid.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-reader.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-string.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-utf8.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-value.c
   ${mongo-c-driver_SOURCE_DIR}/src/libbson/tests/test-writer.c
   ${PROJECT_SOURCE_DIR}/tests/bsonutil/bson-match.c
   ${PROJECT_SOURCE_DIR}/tests/bsonutil/bson-parser.c
   ${PROJECT_SOURCE_DIR}/tests/bsonutil/bson-val.c
   ${PROJECT_SOURCE_DIR}/tests/debug-stream.c
   ${PROJECT_SOURCE_DIR}/tests/json-test-monitoring.c
   ${PROJECT_SOURCE_DIR}/tests/json-test-operations.c
   ${PROJECT_SOURCE_DIR}/tests/json-test.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/future-functions.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/future-value.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/future.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/mock-rs.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/mock-server.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/request.c
   ${PROJECT_SOURCE_DIR}/tests/mock_server/sync-queue.c
   ${PROJECT_SOURCE_DIR}/tests/test-conveniences.c
   ${PROJECT_SOURCE_DIR}/tests/test-happy-eyeballs.c
   ${PROJECT_SOURCE_DIR}/tests/test-libmongoc.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-aggregate.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-array.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-async.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-aws.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-background-monitoring.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-buffer.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-bulk.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-bulkwrite.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-change-stream.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-pool.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-session.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cluster.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cmd.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection-find-with-opts.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection-find.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-collection.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-command-logging-and-monitoring.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-command-monitoring.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-connection-uri.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-counters.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-crud.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cursor.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-database.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-dns.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-error.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-exhaust.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-find-and-modify.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-generation-map.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs-bucket.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs-file-page.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gridfs.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-handshake.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-hedged-reads.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-http.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-interrupt.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-linux-distro-scanner.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-list.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-loadbalanced.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-log.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-long-namespace.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-matcher.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-max-staleness.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-mongohouse.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-mongos-pinning.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-opts.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-primary-stepdown.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-queue.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-concern.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-prefs.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-read-write-concern.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-retryability-helpers.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-retryable-reads.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-retryable-writes.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sample-commands.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-scram.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sdam-monitoring.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-sdam.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-description.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection-errors.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-selection.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-server-stream.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-set.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-shared.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-socket.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-speculative-auth.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-ssl.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-streamable-hello.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-structured-log.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-thread.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-timeout.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-description.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-reconcile.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology-scanner.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-topology.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-transactions.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-ts-pool.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-uri.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-usleep.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-util.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-version.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-versioned-api.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-with-transaction.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-write-commands.c
   ${PROJECT_SOURCE_DIR}/tests/test-mongoc-write-concern.c
   ${PROJECT_SOURCE_DIR}/tests/test-mcd-azure-imds.c
   ${PROJECT_SOURCE_DIR}/tests/test-service-gcp.c
   ${PROJECT_SOURCE_DIR}/tests/test-mcd-integer.c
   ${PROJECT_SOURCE_DIR}/tests/test-mcd-nsinfo.c
   ${PROJECT_SOURCE_DIR}/tests/test-mcd-rpc.c
   ${PROJECT_SOURCE_DIR}/tests/TestSuite.c
   ${PROJECT_SOURCE_DIR}/tests/unified/operation.c
   ${PROJECT_SOURCE_DIR}/tests/unified/entity-map.c
   ${PROJECT_SOURCE_DIR}/tests/unified/result.c
   ${PROJECT_SOURCE_DIR}/tests/unified/runner.c
   ${PROJECT_SOURCE_DIR}/tests/unified/test-diagnostics.c
   ${PROJECT_SOURCE_DIR}/tests/unified/util.c
)

if (MONGOC_ENABLE_SSL)
   set (test-libmongoc-sources ${test-libmongoc-sources}
      ${PROJECT_SOURCE_DIR}/tests/ssl-test.c
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-client-side-encryption.c
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream-tls-error.c
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-stream-tls.c
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-x509.c
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-ocsp-cache.c
   )
endif ()

if (MONGOC_ENABLE_SASL_CYRUS)
   set (test-libmongoc-sources ${test-libmongoc-sources}
      ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cyrus.c
   )
endif ()

if (ENABLE_TESTS)
   add_library (test-libmongoc-lib STATIC EXCLUDE_FROM_ALL ${test-libmongoc-sources})
   if (MSVC AND MSVC_VERSION VERSION_LESS 1900)
      message (STATUS "Disabling warning C4756 for VS 2013 and older")
      # Macro constant INFINITY triggers constant arithmetic overflow warnings in
      # VS 2013, but VS 2013 doesn't support inline warning suppression.
      # Remove once support for VS 2013 is dropped.
      target_compile_options(test-libmongoc-lib PRIVATE /wd4756)
   endif ()
   target_link_libraries (test-libmongoc-lib PUBLIC mongoc_static)
   # We have tests that test our deprecated api.
   target_compile_options (test-libmongoc-lib
      PRIVATE $<$<NOT:$<C_COMPILER_ID:MSVC>>:-Wno-deprecated-declarations>
   )
   # Enable unconditional warnings-as-errors for our source code.
   target_compile_options (test-libmongoc-lib PRIVATE ${mongoc-warning-options})
   target_include_directories (test-libmongoc-lib
      PRIVATE
         ${PROJECT_SOURCE_DIR}/tests
         ${BSON_STATIC_INCLUDE_DIRS}
         ${UTHASH_INCLUDE_DIR}
   )
   target_compile_definitions (test-libmongoc-lib
      PUBLIC
         "MONGOC_COMPILATION"
         "BSON_COMPILATION"
         "MCOMMON_NAME_PREFIX=_mongoc_mcommon"
   )

   function (mongoc_add_test test)
      add_executable (${test} EXCLUDE_FROM_ALL ${ARGN})
      add_dependencies (mongo_c_driver_tests ${test})

      target_link_libraries (${test}
         PUBLIC
            $<$<PLATFORM_ID:Windows>:DbgHelp.lib>
            mongoc_static
      )
      # We have tests that test our deprecated api.
      target_compile_options (${test}
         PRIVATE $<$<NOT:$<C_COMPILER_ID:MSVC>>:-Wno-deprecated-declarations>
      )
      # Enable unconditional warnings-as-errors for our source code.
      target_compile_options (${test} PRIVATE ${mongoc-warning-options})
      target_include_directories (${test}
         PRIVATE
            ${PROJECT_SOURCE_DIR}/tests
            ${BSON_STATIC_INCLUDE_DIRS}
      )
      target_compile_definitions (${test}
         PUBLIC
            "MONGOC_COMPILATION"
            "BSON_COMPILATION"
            "MCOMMON_NAME_PREFIX=_mongoc_mcommon"
      )
   endfunction ()

   mongoc_add_test (test-libmongoc ${PROJECT_SOURCE_DIR}/tests/test-libmongoc-main.c)
   target_link_libraries (test-libmongoc PUBLIC test-libmongoc-lib)

   mongoc_add_test (test-atlas-executor ${PROJECT_SOURCE_DIR}/tests/test-atlas-executor.c)
   target_link_libraries (test-atlas-executor PUBLIC test-libmongoc-lib)

   mongoc_add_test (test-mongoc-gssapi ${PROJECT_SOURCE_DIR}/tests/test-mongoc-gssapi.c)
   mongoc_add_test (test-mongoc-cache ${PROJECT_SOURCE_DIR}/tests/test-mongoc-cache.c)
   mongoc_add_test (test-azurekms ${PROJECT_SOURCE_DIR}/tests/test-azurekms.c)
   mongoc_add_test (test-gcpkms ${PROJECT_SOURCE_DIR}/tests/test-gcpkms.c)
   mongoc_add_test (test-awsauth ${PROJECT_SOURCE_DIR}/tests/test-awsauth.c)

   # "make test" doesn't compile tests, so we create "make check" which compiles
   # and runs tests: https://gitlab.kitware.com/cmake/cmake/issues/8774
   add_custom_target (check COMMAND ${CMAKE_CTEST_COMMAND} -V
      DEPENDS test-libmongoc
   )
endif ()

if (ENABLE_EXAMPLES AND ENABLE_SHARED)
   function (mongoc_add_example example)
      add_executable (${example} EXCLUDE_FROM_ALL ${ARGN})
      add_dependencies (mongo_c_driver_examples ${example})

      # Enable unconditional warnings-as-errors for our source code.
      target_compile_options (${example} PRIVATE ${mongoc-warning-options})

      target_link_libraries (${example} mongoc_shared ${LIBRARIES})
      if (WIN32)
         target_link_libraries (${example} shlwapi)
      endif ()
   endfunction ()

   # examples/
   mongoc_add_example (example-client ${PROJECT_SOURCE_DIR}/examples/example-client.c)
   mongoc_add_example (example-collection-watch ${PROJECT_SOURCE_DIR}/examples/example-collection-watch.c)
   if (NOT WIN32)
      mongoc_add_example (example-resume ${PROJECT_SOURCE_DIR}/examples/example-resume.c)
   endif()
   mongoc_add_example (example-start-at-optime ${PROJECT_SOURCE_DIR}/examples/example-start-at-optime.c)
   mongoc_add_example (example-command-monitoring ${PROJECT_SOURCE_DIR}/examples/example-command-monitoring.c)
   mongoc_add_example (example-command-with-opts ${PROJECT_SOURCE_DIR}/examples/example-command-with-opts.c)
   mongoc_add_example (example-manage-collection-indexes ${PROJECT_SOURCE_DIR}/examples/example-manage-collection-indexes.c)
   mongoc_add_example (example-manage-search-indexes ${PROJECT_SOURCE_DIR}/examples/example-manage-search-indexes.c)
   mongoc_add_example (example-gridfs ${PROJECT_SOURCE_DIR}/examples/example-gridfs.c)
   mongoc_add_example (example-gridfs-bucket ${PROJECT_SOURCE_DIR}/examples/example-gridfs-bucket.c)
   if (NOT WIN32 AND ENABLE_EXAMPLES)
      # Examples that use pthreads
      mongoc_add_example (example-pool ${PROJECT_SOURCE_DIR}/examples/example-pool.c)
      mongoc_add_example (example-structured-log ${PROJECT_SOURCE_DIR}/examples/example-structured-log.c)
   endif ()
   mongoc_add_example (example-scram ${PROJECT_SOURCE_DIR}/examples/example-scram.c)
   mongoc_add_example (example-sdam-monitoring ${PROJECT_SOURCE_DIR}/examples/example-sdam-monitoring.c)
   mongoc_add_example (example-session ${PROJECT_SOURCE_DIR}/examples/example-session.c)
   mongoc_add_example (example-transaction ${PROJECT_SOURCE_DIR}/examples/example-transaction.c)
   mongoc_add_example (example-update ${PROJECT_SOURCE_DIR}/examples/example-update.c)
   mongoc_add_example (find-and-modify ${PROJECT_SOURCE_DIR}/examples/find-and-modify.c)
   mongoc_add_example (hello_mongoc ${PROJECT_SOURCE_DIR}/examples/hello_mongoc.c)
   mongoc_add_example (mongoc-dump ${PROJECT_SOURCE_DIR}/examples/mongoc-dump.c)
   mongoc_add_example (mongoc-ping ${PROJECT_SOURCE_DIR}/examples/mongoc-ping.c)
   mongoc_add_example (mongoc-tail ${PROJECT_SOURCE_DIR}/examples/mongoc-tail.c)
   mongoc_add_example (example-collection-command ${PROJECT_SOURCE_DIR}/examples/example-collection-command.c)
   mongoc_add_example (example-bulkwrite ${PROJECT_SOURCE_DIR}/examples/example-bulkwrite.c)

   # examples/aggregation/
   mongoc_add_example (aggregation1 ${PROJECT_SOURCE_DIR}/examples/aggregation/aggregation1.c)

   # examples/basic_aggregation/
   mongoc_add_example (basic-aggregation ${PROJECT_SOURCE_DIR}/examples/basic_aggregation/basic-aggregation.c)

   # examples/bulk/
   mongoc_add_example (bulk-collation ${PROJECT_SOURCE_DIR}/examples/bulk/bulk-collation.c)
   mongoc_add_example (bulk1 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk1.c)
   mongoc_add_example (bulk2 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk2.c)
   mongoc_add_example (bulk3 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk3.c)
   mongoc_add_example (bulk4 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk4.c)
   mongoc_add_example (bulk5 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk5.c)
   mongoc_add_example (bulk6 ${PROJECT_SOURCE_DIR}/examples/bulk/bulk6.c)

   # examples/common_operations/
   mongoc_add_example (common-operations ${PROJECT_SOURCE_DIR}/examples/common_operations/common-operations.c)

   # examples/find_and_modify_with_opts/
   mongoc_add_example (fam ${PROJECT_SOURCE_DIR}/examples/find_and_modify_with_opts/fam.c)

   if (MONGOC_ENABLE_CLIENT_SIDE_ENCRYPTION)
      mongoc_add_example (client-side-encryption-schema-map ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-schema-map.c ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-helpers.c)
      mongoc_add_example (client-side-encryption-server-schema ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-server-schema.c ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-helpers.c)
      mongoc_add_example (client-side-encryption-explicit ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-explicit.c ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-helpers.c)
      mongoc_add_example (client-side-encryption-auto-decryption ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-auto-decryption.c ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-helpers.c)
      mongoc_add_example (client-side-encryption-doc-snippets ${PROJECT_SOURCE_DIR}/examples/client-side-encryption-doc-snippets.c)
   endif ()

   # examples/tutorial
   mongoc_add_example (executing ${PROJECT_SOURCE_DIR}/examples/tutorial/executing.c)
   mongoc_add_example (appending ${PROJECT_SOURCE_DIR}/examples/tutorial/appending.c)
   mongoc_add_example (migrating ${PROJECT_SOURCE_DIR}/examples/migrating.c)
   # Ignore deprecation warnings in migrating examples. Migrating examples deliberately call deprecated API to show how to migrate.
   target_compile_options (migrating
      PRIVATE $<$<NOT:$<C_COMPILER_ID:MSVC>>:-Wno-deprecated-declarations>
   )
endif ()

if (ENABLE_TESTS AND ENABLE_SHARED AND MONGOC_ENABLE_SSL AND NOT WIN32)
   # Add benchmarks to measure opening many TLS connections.
   # Benchmarks require SSL, and do not build on Windows.
   add_executable (benchmark-tls-pooled ${PROJECT_SOURCE_DIR}/tests/benchmark-tls-pooled.c)
   target_compile_options (benchmark-tls-pooled PRIVATE ${mongoc-warning-options})
   target_link_libraries (benchmark-tls-pooled mongoc_shared ${LIBRARIES})
endif ()

file (COPY ${PROJECT_SOURCE_DIR}/tests/binary DESTINATION ${PROJECT_BINARY_DIR}/tests)
file (COPY ${PROJECT_SOURCE_DIR}/tests/json DESTINATION ${PROJECT_BINARY_DIR}/tests)
file (COPY ${PROJECT_SOURCE_DIR}/tests/x509gen DESTINATION ${PROJECT_BINARY_DIR}/tests)
file (COPY ${PROJECT_SOURCE_DIR}/tests/release_files DESTINATION ${PROJECT_BINARY_DIR}/tests)

set (TARGETS_TO_INSTALL)

if (MONGOC_ENABLE_STATIC_INSTALL)
   list (APPEND TARGETS_TO_INSTALL mongoc_static)
endif ()

if (ENABLE_SHARED)
   list (APPEND TARGETS_TO_INSTALL mongoc_shared)
endif ()

set (MONGOC_HEADER_INSTALL_DIR
   "${CMAKE_INSTALL_INCLUDEDIR}/libmongoc-${MONGOC_API_VERSION}"
)

install (
   TARGETS ${TARGETS_TO_INSTALL}
   EXPORT mongoc-targets
   LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
   ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
   RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
   INCLUDES DESTINATION ${MONGOC_HEADER_INSTALL_DIR}
   FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR}
)

install (
   FILES ${HEADERS}
   DESTINATION "${MONGOC_HEADER_INSTALL_DIR}/mongoc"
)

install (
   FILES ${HEADERS_FORWARDING}
   DESTINATION "${MONGOC_HEADER_INSTALL_DIR}"
)

if (ENABLE_APPLE_FRAMEWORK)
   install (
      FILES "${PROJECT_BINARY_DIR}/src/mongoc/modules/module.modulemap"
      DESTINATION "${CMAKE_INSTALL_BINDIR}/mongoc.framework/Modules/"
   )
endif ()

# Collect link items for the static library to be inserted into the pkg-config
if(TARGET mongoc_static)
   set(link_options ${ZLIB_LIBRARIES}
      ${SNAPPY_LIBRARIES} ${MONGOC_ZSTD_LIBRARIES} ${LIBMONGOCRYPT_LIBRARY})
   # Replace all absolute paths with search-dir link-file options:
   list(TRANSFORM link_options
        REPLACE "^(.+)/lib([^/\\.]+)\\..+$"
                "-L\\1;-l\\2"
        REGEX "^/")
   # Prepend "-l" to all bare names:
   list(TRANSFORM link_options PREPEND "-l" REGEX "^[^-]")
   list(REMOVE_DUPLICATES link_options)
   message(DEBUG "Computed static library link options: ${link_options}")
   set_property(TARGET mongoc_static APPEND PROPERTY pkg_config_LIBS ${link_options})
endif()

# Relative include-path will be given the install prefix:
set_property(TARGET ${TARGETS_TO_INSTALL} APPEND PROPERTY pkg_config_INCLUDE_DIRECTORIES "${MONGOC_HEADER_INSTALL_DIR}")

# Deprecated alias for libmongoc-1.0.pc, see CDRIVER-2086.
if (MONGOC_ENABLE_SSL)
   configure_file (
      ${CMAKE_CURRENT_SOURCE_DIR}/src/libmongoc-ssl-1.0.pc.in
      ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-ssl-1.0.pc
   @ONLY)
   install (
      FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmongoc-ssl-1.0.pc
      DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
   )
endif ()

include (CMakePackageConfigHelpers)

write_basic_package_version_file (
   "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config-version.cmake"
   VERSION ${MONGOC_VERSION}
   COMPATIBILITY AnyNewerVersion
)

configure_file (src/mongoc-config.cmake
   "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config.cmake"
   @ONLY
)

install (EXPORT mongoc-targets
   NAMESPACE mongo::
   FILE mongoc-targets.cmake
   DESTINATION ${MONGOC_TARGETS_INSTALL_DIR}
)

install (
   FILES
      "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config.cmake"
      "${CMAKE_CURRENT_BINARY_DIR}/mongoc/mongoc-${MONGOC_API_VERSION}-config-version.cmake"
   DESTINATION
      ${MONGOC_TARGETS_INSTALL_DIR}
   COMPONENT
      Devel
)

set(mongoc_cmake_prefix "${MONGO_C_DRIVER_INSTALL_CMAKEDIR}/mongoc-${PROJECT_VERSION}")
configure_file(
   ${mongo-c-driver_SOURCE_DIR}/build/cmake/packageConfigVersion.cmake.in
   mongocConfigVersion.cmake
   @ONLY
)
install(
   FILES etc/mongocConfig.cmake "${CMAKE_CURRENT_BINARY_DIR}/mongocConfigVersion.cmake"
   DESTINATION "${mongoc_cmake_prefix}"
)

include (LegacyPackage)

if (ENABLE_MAN_PAGES STREQUAL ON OR ENABLE_HTML_DOCS STREQUAL ON)
   find_package (Sphinx REQUIRED)
   add_subdirectory (doc)
   add_custom_target (mongoc-doc
      ALL
      DEPENDS
      $<$<STREQUAL:"${ENABLE_MAN_PAGES}","ON">:mongoc-man>
      $<$<STREQUAL:"${ENABLE_HTML_DOCS}","ON">:mongoc-html>
   )
endif ()
