# -*- mode: python -*-

Import('env')
Import("get_option")
Import('wiredtiger')

env = env.Clone()

env.SConscript(
    dirs=['sdam'],
    exports=['env'],
)


def shouldBuildGRPC(myEnv):
    return myEnv.TargetOSIs('linux') and myEnv['ENABLE_GRPC_BUILD']


# Contains only the core ConnectionString functionality, *not* the ability to call connect() and
# return a DBClientBase* back. For that you need to link against the 'clientdriver_network' library.
env.Library(
    target='connection_string',
    source=[
        'connection_string.cpp',
        'mongo_uri.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/util/net/network',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/util/dns_query',
        '$BUILD_DIR/mongo/util/options_parser/options_parser',
    ],
)

env.Library(
    target=[
        'read_preference',
    ],
    source=[
        'read_preference.cpp',
        'read_preference_setting.idl',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/bson/util/bson_extract',
        '$BUILD_DIR/mongo/db/server_base',
        '$BUILD_DIR/mongo/db/service_context',
    ],
)

if get_option('ssl') == 'on':
    env.Library(
        target=[
            'sasl_aws_common',
        ],
        source=[
            'sasl_aws_protocol_common.idl',
        ],
        LIBDEPS_PRIVATE=[
            '$BUILD_DIR/mongo/db/server_base',
        ],
    )

    kmsEnv = env.Clone()

    kmsEnv.InjectThirdParty(libraries=['libmongocrypt'])

    kmsEnv.Library(
        target=[
            'sasl_aws_client',
        ],
        source=[
            'sasl_aws_client_protocol.cpp',
            'sasl_aws_client_protocol.idl',
        ],
        LIBDEPS_PRIVATE=[
            '$BUILD_DIR/mongo/bson/bson_validate',
            '$BUILD_DIR/mongo/db/server_base',
            '$BUILD_DIR/third_party/shim_libmongocrypt',
            'sasl_aws_common',
        ],
    )

# Client-side SASL source necessary for native client SASL session.
# Includes base types and OIDC, PLAIN, SCRAM, and AWS (only if TLS configured)
# client mechs.
nativeSaslClientEnv = env.Clone()
nativeSaslClientSource = [
    'native_sasl_client_session.cpp',
    'sasl_client_authenticate.cpp',
    'sasl_client_authenticate_impl.cpp',
    'sasl_client_conversation.cpp',
    'sasl_client_session.cpp',
    'sasl_oidc_client_conversation.cpp',
    'sasl_oidc_client_types.idl',
    'sasl_plain_client_conversation.cpp',
    'sasl_scram_client_conversation.cpp',
]

if get_option('ssl') == 'on':
    nativeSaslClientSource.extend([
        'sasl_aws_client_conversation.cpp',
        'sasl_aws_client_options.idl',
    ])

nativeSaslClientEnv.Library(
    target='native_sasl_client',
    source=nativeSaslClientSource,
    LIBDEPS=[
        '$BUILD_DIR/mongo/base/secure_allocator',
        '$BUILD_DIR/mongo/bson/util/bson_extract',
        '$BUILD_DIR/mongo/executor/remote_command',
        '$BUILD_DIR/mongo/rpc/command_status',
        '$BUILD_DIR/mongo/rpc/metadata',
        '$BUILD_DIR/mongo/util/icu',
        '$BUILD_DIR/mongo/util/md5',
        '$BUILD_DIR/mongo/util/net/network',
        '$BUILD_DIR/mongo/util/options_parser/options_parser',
        "sasl_aws_client" if get_option('ssl') == 'on' else '',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/auth/oidc_protocol',
        '$BUILD_DIR/mongo/db/commands/server_status_core',
        '$BUILD_DIR/mongo/db/server_base',
        '$BUILD_DIR/mongo/shell/program_runner',
        '$BUILD_DIR/mongo/util/net/http_client',
        'connection_string',
    ],
)

if env["MONGO_BUILD_SASL_CLIENT"]:
    # Client-side SASL source necessary for mongo shell.
    # Includes Cyrus SASL, OIDC, PLAIN, and AWS (if TLS support is on)
    # support. Depends on sasl_client_native.
    cyrusSaslClientEnv = env.Clone()

    saslLibs = ["sasl2"]
    if env.TargetOSIs("windows"):
        saslLibs.extend(["secur32"])

    cyrusSaslClientEnv.Library(
        target="cyrus_sasl_client",
        source=[
            "cyrus_sasl_client_session.cpp",
            "sasl_sspi.cpp",
            "sasl_sspi_options.cpp",
            "sasl_sspi_options.idl",
        ],
        LIBDEPS=[
            "native_sasl_client",
        ],
        SYSLIBDEPS=saslLibs,
        LIBDEPS_DEPENDENTS=[
            "$BUILD_DIR/mongo/shell/mongo_initializers",
        ],
        LIBDEPS_TAGS=[
            "lint-allow-nonprivate-on-deps-dependents",
            "lint-allow-bidirectional-edges",
        ],
    )

env.Library(
    target='authentication',
    source=[
        'authenticate.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/bson/util/bson_extract',
        '$BUILD_DIR/mongo/executor/remote_command',
        'internal_auth',
        'native_sasl_client',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/auth/auth',
        '$BUILD_DIR/mongo/db/server_base',
        'connection_string',
    ],
)

env.Library(
    target='internal_auth',
    source=[
        'internal_auth.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/bson/util/bson_extract',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/auth/auth',
        '$BUILD_DIR/mongo/util/md5',
        'connection_string',
    ],
)

clientDriverEnv = env.Clone()
clientDriverEnv.InjectThirdParty('asio')
if shouldBuildGRPC(env):
    clientDriverEnv.InjectThirdParty(libraries=['grpc'])

clientDriverEnv.Library(
    target='clientdriver_minimal',
    source=[
        'client_api_version_parameters.idl',
        'dbclient_base.cpp',
        'dbclient_cursor.cpp',
        'index_spec.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/dbmessage',
        '$BUILD_DIR/mongo/db/pipeline/aggregation_request_helper',
        '$BUILD_DIR/mongo/db/query/command_request_response',
        '$BUILD_DIR/mongo/db/query/query_request',
        '$BUILD_DIR/mongo/db/wire_version',
        '$BUILD_DIR/mongo/rpc/command_status',
        '$BUILD_DIR/mongo/rpc/rpc',
        'authentication',
        'connection_string',
        'read_preference',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/server_base',
        '$BUILD_DIR/mongo/util/net/ssl_manager',
    ],
)

clientDriverEnv.Library(
    target='clientdriver_network',
    source=[
        'connection_string_connect.cpp',
        'mongo_uri_connect.cpp',
        'connpool.cpp',
        'dbclient_connection.cpp',
        'dbclient_grpc_stream.cpp' if shouldBuildGRPC(env) else [],
        'dbclient_rs.cpp',
        'dbclient_session.cpp',
        'global_conn_pool.cpp',
        'global_conn_pool.idl',
        'replica_set_change_notifier.cpp',
        'replica_set_monitor.cpp',
        'replica_set_monitor_manager.cpp',
        'replica_set_monitor_stats.cpp',
        'streamable_replica_set_monitor.cpp',
        'streamable_replica_set_monitor_query_processor.cpp',
        'streamable_replica_set_monitor_error_handler.cpp',
        'server_discovery_monitor.cpp',
        'server_ping_monitor.cpp',
        'streamable_replica_set_monitor_discovery_time_processor.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/client/sdam/sdam',
        '$BUILD_DIR/mongo/db/server_base',
        '$BUILD_DIR/mongo/executor/connection_pool_stats',
        '$BUILD_DIR/mongo/executor/network_interface',
        '$BUILD_DIR/mongo/executor/network_interface_factory',
        '$BUILD_DIR/mongo/executor/network_interface_thread_pool',
        '$BUILD_DIR/mongo/executor/thread_pool_task_executor',
        '$BUILD_DIR/mongo/transport/grpc/grpc_transport_layer' if shouldBuildGRPC(env) else [],
        '$BUILD_DIR/mongo/transport/transport_layer_manager',
        '$BUILD_DIR/mongo/util/background_job',
        '$BUILD_DIR/mongo/util/md5',
        '$BUILD_DIR/mongo/util/net/network',
        'clientdriver_minimal',
        'read_preference',
        'replica_set_monitor_server_parameters',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/auth/auth',
        '$BUILD_DIR/mongo/db/commands/test_commands_enabled',
        '$BUILD_DIR/mongo/db/server_feature_flags',
        '$BUILD_DIR/mongo/transport/message_compressor',
        '$BUILD_DIR/mongo/util/net/ssl_manager',
    ],
)

env.Library(
    target='replica_set_monitor_server_parameters',
    source=[
        'replica_set_monitor_server_parameters.cpp',
        'replica_set_monitor_server_parameters.idl',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/server_base',
    ],
)

env.Library(
    target='async_client',
    source=[
        'async_client.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/wire_version',
        '$BUILD_DIR/mongo/rpc/command_status',
        '$BUILD_DIR/mongo/rpc/rpc',
        '$BUILD_DIR/mongo/transport/transport_layer_common',
        '$BUILD_DIR/mongo/util/net/ssl_manager',
        'authentication',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/commands/test_commands_enabled',
        '$BUILD_DIR/mongo/db/connection_health_metrics_parameter',
        '$BUILD_DIR/mongo/db/server_feature_flags',
        '$BUILD_DIR/mongo/db/stats/counters',
        '$BUILD_DIR/mongo/executor/egress_connection_closer_manager',
        '$BUILD_DIR/mongo/transport/message_compressor',
        '$BUILD_DIR/mongo/util/fail_point',
    ],
)

env.Library(
    target='remote_command_targeter',
    source=[
        'remote_command_targeter_factory_impl.cpp',
        'remote_command_targeter_rs.cpp',
        'remote_command_targeter_standalone.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/service_context',
        'clientdriver_network',
    ],
)

env.Library(
    target='remote_command_targeter_mock',
    source=[
        'remote_command_targeter_mock.cpp',
        'remote_command_targeter_factory_mock.cpp',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/server_base',
        '$BUILD_DIR/mongo/util/net/network',
    ],
)

env.Library(
    target='replica_set_monitor_test_helper',
    source=[
        'streamable_replica_set_monitor_for_testing.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/client/clientdriver_network',
        '$BUILD_DIR/mongo/client/sdam/sdam_test_util',
        '$BUILD_DIR/mongo/util/net/network',
    ],
)

env.Library(
    target='fetcher',
    source=[
        'fetcher.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/executor/task_executor_interface',
        '$BUILD_DIR/mongo/rpc/command_status',
        'remote_command_retry_scheduler',
    ],
    LIBDEPS_PRIVATE=[
        '$BUILD_DIR/mongo/db/server_base',
    ],
)

env.Library(
    target='remote_command_retry_scheduler',
    source=[
        'remote_command_retry_scheduler.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/base',
        '$BUILD_DIR/mongo/executor/task_executor_interface',
    ],
)

if wiredtiger:
    env.CppUnitTest(
        target='client_test',
        source=[
            'async_remote_command_targeter_adapter_test.cpp',
            'authenticate_test.cpp',
            'connection_string_test.cpp',
            'dbclient_cursor_test.cpp',
            'fetcher_test.cpp',
            'index_spec_test.cpp',
            'mongo_uri_test.cpp',
            'read_preference_test.cpp',
            'remote_command_retry_scheduler_test.cpp',
            'replica_set_monitor_server_parameters_test.cpp',
            'server_discovery_monitor_expedited_test.cpp',
            'server_discovery_monitor_test.cpp',
            'server_ping_monitor_test.cpp',
            'streamable_replica_set_monitor_error_handler_test.cpp',
            'streamable_replica_set_monitor_discovery_time_processor_test.cpp',
        ],
        LIBDEPS=[
            '$BUILD_DIR/mongo/client/sdam/sdam',
            '$BUILD_DIR/mongo/client/sdam/sdam_test_util',
            '$BUILD_DIR/mongo/db/auth/authmocks',
            '$BUILD_DIR/mongo/db/server_base',
            '$BUILD_DIR/mongo/db/service_context_test_fixture',
            '$BUILD_DIR/mongo/dbtests/mocklib',
            '$BUILD_DIR/mongo/executor/network_interface_mock',
            '$BUILD_DIR/mongo/executor/task_executor_test_fixture',
            '$BUILD_DIR/mongo/executor/thread_pool_task_executor_test_fixture',
            '$BUILD_DIR/mongo/rpc/command_status',
            '$BUILD_DIR/mongo/transport/transport_layer_common',
            '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
            '$BUILD_DIR/mongo/unittest/task_executor_proxy',
            '$BUILD_DIR/mongo/util/md5',
            '$BUILD_DIR/mongo/util/net/network',
            'authentication',
            'clientdriver_minimal',
            'clientdriver_network',
            'connection_string',
            'fetcher',
            'read_preference',
            'remote_command_retry_scheduler',
            'remote_command_targeter_mock',
            'replica_set_monitor_protocol_test_util',
        ],
    )

env.CppIntegrationTest(
    target='replica_set_monitor_integration_test',
    source=[
        'replica_set_monitor_integration_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/client/clientdriver_network',
        '$BUILD_DIR/mongo/db/wire_version',
        '$BUILD_DIR/mongo/executor/network_interface_factory',
        '$BUILD_DIR/mongo/executor/network_interface_thread_pool',
        '$BUILD_DIR/mongo/executor/thread_pool_task_executor',
        '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
        '$BUILD_DIR/mongo/util/concurrency/thread_pool',
        '$BUILD_DIR/mongo/util/version_impl',
    ],
)

env.Library(
    target='replica_set_monitor_protocol_test_util',
    source=[
        'replica_set_monitor_protocol_test_util.cpp',
    ],
    LIBDEPS=[
        'clientdriver_network',
    ],
)

env.CppUnitTest(
    target='client_rs_test',
    source=[
        'dbclient_rs_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/dbtests/mocklib',
        '$BUILD_DIR/mongo/util/clock_source_mock',
        'clientdriver_network',
        'replica_set_monitor_test_helper',
    ],
)
if shouldBuildGRPC(env):
    clientDriverEnv.CppUnitTest(
        target='dbclient_grpc_stream_test',
        source=[
            'dbclient_grpc_stream_test.cpp',
        ],
        LIBDEPS=[
            '$BUILD_DIR/mongo/db/service_context_non_d',
            '$BUILD_DIR/mongo/db/service_context_test_fixture',
            '$BUILD_DIR/mongo/transport/grpc/grpc_transport_mock',
            '$BUILD_DIR/mongo/util/version_impl',
            'clientdriver_network',
        ],
    )

env.CppUnitTest(
    target='scoped_db_connection_pool_test',
    source=['scoped_db_connection_test.cpp'],
    LIBDEPS=[
        '$BUILD_DIR/mongo/dbtests/mocklib',
        'clientdriver_network',
    ],
)

env.CppUnitTest(
    target='dbclient_connection_test',
    source=[
        'dbclient_connection_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/util/version_impl',
        'clientdriver_network',
    ],
)

# The following two tests cannot be combined because the second one
# needs to be filtered out for the repl and sharding variants of the
# integration tests.
env.CppIntegrationTest(
    target='client_connpool_integration_test',
    source=[
        'connpool_integration_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
        '$BUILD_DIR/mongo/util/version_impl',
        'clientdriver_network',
    ],
)

env.CppIntegrationTest(
    target='client_dbclient_connection_integration_test',
    source=[
        'dbclient_connection_integration_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/transport/transport_layer_egress_init',
        '$BUILD_DIR/mongo/util/version_impl',
        'clientdriver_network',
    ],
)

env.Library(
    target='dbclient_mockcursor',
    source=['dbclient_mockcursor.cpp'],
    LIBDEPS_PRIVATE=['clientdriver_minimal'],
)
