# -*- mode: python -*-

Import("env")

env = env.Clone()

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

# Core definitions: ABT, Logical and physical properties, Metadata, and core utilities.
env.Library(
    target="optimizer_base",
    source=[
        "defs.cpp",
        "explain.cpp",
        "index_bounds.cpp",
        "metadata.cpp",
        "node.cpp",
        "partial_schema_requirements.cpp",
        "props.cpp",
        "reference_tracker.cpp",
        "syntax/expr.cpp",
        "utils/abt_compare.cpp",
        "utils/abt_hash.cpp",
        "utils/ce_math.cpp",
        "utils/interval_utils.cpp",
        "utils/path_utils.cpp",
        "utils/reftracker_utils.cpp",
        "utils/utils.cpp",
    ],
    LIBDEPS=[
        # We should only depend on SBE for value representation and basic arithmetic for constant folding.
        "$BUILD_DIR/mongo/db/exec/sbe/query_sbe_makeobj_spec",
        "$BUILD_DIR/mongo/db/sbe_values",
    ],
)

# Memo, and related utilities.
env.Library(
    target="optimizer_memo",
    source=[
        "cascades/memo.cpp",
        "cascades/memo_defs.cpp",
        "cascades/rewrite_queues.cpp",
        "utils/memo_utils.cpp",
    ],
    LIBDEPS=[
        "optimizer_base",
    ],
)

# Cascades rewrites.
env.Library(
    target="optimizer_cascades",
    source=[
        "cascades/enforcers.cpp",
        "cascades/logical_props_derivation.cpp",
        "cascades/implementers.cpp",
        "cascades/logical_rewriter.cpp",
        "cascades/physical_rewriter.cpp",
    ],
    LIBDEPS=[
        "optimizer_memo",
    ],
)

# Rewrites which manipulate the ABT directly.
env.Library(
    target="optimizer_rewrites",
    source=[
        "rewrites/const_eval.cpp",
        "rewrites/normalize_projections.cpp",
        "rewrites/path.cpp",
        "rewrites/path_lower.cpp",
        "rewrites/proj_spec_lower.cpp",
        "rewrites/proj_spec_builder.cpp",
        "rewrites/sampling_const_eval.cpp",
    ],
    LIBDEPS=[
        "optimizer_base",
    ],
)

env.CppUnitTest(
    target="optimizer_proj_spec_test",
    source=[
        "rewrites/proj_spec_test.cpp",
    ],
    LIBDEPS=[
        "$BUILD_DIR/mongo/db/exec/sbe/query_sbe",  # needed to register extended type destruction for MakeObjSpec :(
        "optimizer_rewrites",
        "unit_test_utils",
    ],
)

# Main optimizer target.
env.Library(
    target="optimizer",
    source=[
        "metadata_factory.cpp",
        "opt_phase_manager.cpp",
    ],
    LIBDEPS=[
        "optimizer_cascades",
        "optimizer_rewrites",
    ],
)

# Lightweight test utils.
env.Library(
    target="unit_test_utils",
    source=[
        "utils/unit_test_utils.cpp",
    ],
    LIBDEPS=[
        # We do not depend on the entire pipeline target.
        "$BUILD_DIR/mongo/db/bson/dotted_path_support",
        "$BUILD_DIR/mongo/db/pipeline/abt_utils",
        "$BUILD_DIR/mongo/db/query/ce/query_ce_heuristic",
        "$BUILD_DIR/mongo/db/query/ce/query_ce_hinted",
        "$BUILD_DIR/mongo/db/query/cost_model/query_cost_model",
        "$BUILD_DIR/mongo/db/query/optimizer/optimizer",
        "$BUILD_DIR/mongo/unittest/unittest",
    ],
)

# Heavyweight test utils (depend on pipeline).
env.Library(
    target='unit_test_pipeline_utils',
    source=[
        'utils/unit_test_pipeline_utils.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/pipeline/abt_translation',
        '$BUILD_DIR/mongo/db/pipeline/pipeline',
        '$BUILD_DIR/mongo/db/query/canonical_query',
        '$BUILD_DIR/mongo/db/query/query_test_service_context',
        '$BUILD_DIR/mongo/db/service_context_test_fixture',
        'unit_test_utils',
    ],
)

env.CppUnitTest(
    target='optimizer_test',
    source=[
        'bool_expression_test.cpp',
        'explain_paths_exprs_test.cpp',
        'explain_query_params_test.cpp',
        'index_union_optimizer_test.cpp',
        'logical_rewriter_optimizer_test.cpp',
        'optimizer_test.cpp',
        'physical_rewriter_optimizer_test.cpp',
        'physical_rewriter_parallelism_test.cpp',
        'reference_tracker_test.cpp',
        'remove_orphans_requirement_test.cpp',
        'rewrites/const_eval_test.cpp',
        'rewrites/path_optimizer_test.cpp',
        'unit_test_infra_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/exec/sbe/query_sbe',  # needed to register extended type destruction for MakeObjSpec :(
        'unit_test_utils',
    ],
)

env.CppUnitTest(
    target='interval_simplify_test',
    source=[
        'interval_simplify_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/service_context_non_d',
        '$BUILD_DIR/mongo/db/service_context_test_fixture',
        'optimizer',
        'unit_test_pipeline_utils',
    ],
)

env.CppUnitTest(
    target='optimizer_failure_test',
    source=[
        'optimizer_failure_test.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/concurrency/lock_manager',
        'unit_test_utils',
    ],
)

env.Benchmark(
    target='path_lower_bm',
    source=[
        'rewrites/path_lower_bm.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/concurrency/lock_manager',
        '$BUILD_DIR/mongo/unittest/unittest',
        'optimizer_rewrites',
        'unit_test_utils',
    ],
)

optimizer_gdb_test_program = env.Program(
    target='optimizer_gdb_test_program',
    source=[
        'optimizer_gdb_test_program.cpp',
    ],
    LIBDEPS=[
        '$BUILD_DIR/mongo/db/service_context_non_d',
        '$BUILD_DIR/mongo/db/service_context_test_fixture',
        'optimizer',
        'unit_test_utils',
    ],
    AIB_COMPONENT='pretty-printer-tests',
    AIB_COMPONENTS_EXTRA=['dist-test'],
)
optimizer_gdb_test_program_installed = env.GetAutoInstalledFiles(optimizer_gdb_test_program[0])

env.PrettyPrinterTest('optimizer_gdb_test.py', TEST_PROGRAM=optimizer_gdb_test_program_installed)
