load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("@npm//:defs.bzl", "npm_link_all_packages")
load("@npm//:eslint/package_json.bzl", eslint_bin = "bin")
load("@npm//:prettier/package_json.bzl", prettier = "bin")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@rules_python//python:defs.bzl", "py_binary")
load("@rules_shell//shell:sh_binary.bzl", "sh_binary")
load("//bazel:mongo_js_rules.bzl", "mongo_js_library")
load("//bazel/config:render_template.bzl", "render_template")
load("//bazel/install_rules:bolt.bzl", "bolt_instrument")
load("//bazel/install_rules:copy_files_to_directory.bzl", "copy_files_to_directory")
load("//bazel/install_rules:install_rules.bzl", "TEST_TAGS", "mongo_install")
load("//bazel/toolchains/cc/mongo_linux:mongo_gdb.bzl", "setup_gdb_toolchain_aliases")
load("//bazel/toolchains/cc/mongo_linux:mongo_toolchain.bzl", "setup_mongo_toolchain_aliases")
load("//bazel/uv:defs.bzl", "dependency")

package(
    default_visibility = ["//visibility:public"],
)

exports_files([
    ".bazelrc",
    ".bazelversion",
    ".bazelrc.target_mongo_version",
    ".prettierrc",
    "pyproject.toml",
    "poetry.lock",
    ".resmoke_mongo_version.yml",  # containing MONGO_VERSION, generated by Resmoke for tests in Evergreen.
    "jsconfig.json",
    "monguard/.evergreen/config_mongodb_master.yml",
    "monguard/.evergreen/config_tasks.yml",
])

npm_link_all_packages(name = "node_modules")

mongo_js_library(
    name = "eslintrc",
    srcs = ["eslint.config.mjs"],
    deps = [
        ":node_modules/@eslint/eslintrc",
        ":node_modules/@eslint/js",
        ":node_modules/eslint-plugin-mocha-no-only",
        ":node_modules/eslint-plugin-mongodb",
        ":node_modules/globals",
        "//src/mongo/shell/debugger/vscode:eslint",
    ],
)

eslint_bin.eslint_binary(
    name = "eslint",
    data = [
        "//:eslintrc",
    ],
)

prettier.prettier_binary(
    name = "prettier",
    # Include this js_library and its dependencies in the runfiles (runtime dependencies)
    data = ["//:.prettierrc"],
    # Allow the binary to be run outside bazel
    # See more details about this by commenting this out and running `bazel run //:format`
    env = {"BAZEL_BINDIR": "."},
    fixed_args = [
        # `require` statements in the config file will be resolved relative to its location
        # Therefore to make it hermetic, prettier must be pointed at the copy of the config file
        # in the runfiles folder rather than the one in the source folder.
        "--config=\"$$JS_BINARY__RUNFILES\"/$(rlocationpath //:.prettierrc)",
        # default log level is "log" which spams on success
        # https://prettier.io/docs/en/cli.html#--log-level
        # NB: prettier 2 names this loglevel, in prettier 3 it's renamed log-level, see
        # https://prettier.io/blog/2023/07/05/3.0.0.html#cli-1
        "--log-level=warn",
        # Speed this up a little bit with caching
        "--cache",
    ],
)

alias(
    name = "format",
    actual = "//bazel/format:rules_lint_format_wrapper",
)

alias(
    name = "lint",
    actual = "//bazel:lint",
)

alias(
    name = "codeowners",
    actual = "@bazel_rules_mongo//codeowners:codeowners",
)

alias(
    name = "engflow_auth",
    actual = "@bazel_rules_mongo//engflow_auth:engflow_auth",
)

alias(
    name = "wt_dump_catalog",
    actual = "//buildscripts:wt_dump_catalog",
)

alias(
    name = "wt_dump_collection",
    actual = "//buildscripts:wt_dump_collection",
)

alias(
    name = "mongo-tidy-test",
    actual = "//src/mongo/tools/mongo_tidy_checks/tests:MongoTidyCheck_unittest",
)

alias(
    name = "setup_clang_tidy",
    actual = "//buildscripts:setup_clang_tidy",
)

setup_mongo_toolchain_aliases()

setup_gdb_toolchain_aliases()

sh_binary(
    name = "install-local-toolchain",
    srcs = ["//bazel/install_rules:install_mongodbtoolchain.sh"],
    data = [
        ":gdb_toolchain_files",
        ":toolchain_files",
        "@py_host//:files",
    ],
    target_compatible_with = [
        "@platforms//os:linux",
    ],
)

render_template(
    name = "clang_tidy_config",
    srcs = [
        ".clang-tidy.in",
    ],
    cmd = [
        "--input=$(location .clang-tidy.in)",
        "--output=$(location .clang-tidy)",
    ],
    output = ".clang-tidy",
    python_file = "//buildscripts:clang_tidy_config_gen.py",
)

render_template(
    name = "clang_tidy_config_strict",
    srcs = [
        ".clang-tidy.in",
    ],
    cmd = [
        "--input=$(location .clang-tidy.in)",
        "--output=$(location .clang-tidy.strict)",
        "--warnings-as-errors",
    ],
    output = ".clang-tidy.strict",
    python_file = "//buildscripts:clang_tidy_config_gen.py",
)

genrule(
    name = "compiledb_only",
    srcs = ["compile_commands.json"],
    outs = ["compile_commands_done"],
    cmd = "echo noop > $(location :compile_commands_done)",
    tags = [
        "no-cache",
        "no-remote-exec",
    ],
)

genrule(
    name = "compiledb",
    srcs = ["compile_commands.json"] + select({
        "@platforms//os:windows": [],
        "//conditions:default": [
            ":setup_clang_tidy",
            ":clang_tidy_config",
            "//src/mongo/tools/mongo_tidy_checks",
        ],
    }),
    outs = ["compiledb_setup_done"],
    cmd = "echo noop > $(location :compiledb_setup_done)",
    tags = [
        "no-cache",
        "no-remote-exec",
    ],
)

# This sets up targets for install-wiredtiger and archive-wiredtiger
mongo_install(
    name = "wiredtiger",
    srcs = [
        "//src/third_party/wiredtiger:wt",
    ],
)

# This sets up targets for install-mongod and archive-mongod
mongo_install(
    name = "mongod",
    srcs = [
        "//src/mongo/db:mongod",
    ] + select({
        "@platforms//os:windows": ["@windows_sasl//:bins"],
        "//conditions:default": [],
    }),
)

# This sets up targets for install-mongos and archive-mongos
mongo_install(
    name = "mongos",
    srcs = [
        "//src/mongo/s:mongos",
    ],
)

# This sets up targets for install-mongo and archive-mongo
mongo_install(
    name = "mongo",
    srcs = [
        "//src/mongo/shell:mongo",
    ],
)

# This sets up targets for install-core and archive-core
mongo_install(
    name = "core",
    srcs = [],
    deps = [
        "mongod",
        "mongos",
    ],
)

# This sets up targets for install-devcore and archive-devcore
mongo_install(
    name = "devcore",
    srcs = [],
    root_files = {
        "//x509:generate_main_certificates": "bin/x509",
    },
    deps = [
        "mongo",
        "mongod",
        "mongos",
    ],
)

# This sets up targets for install-mongotest and archive-mongotest
mongo_install(
    name = "mongotest",
    srcs = [
        "//src/mongo/db/query/query_tester:mongotest",
    ],
)

# This sets up targets for install-mongocryptd and archive-mongocryptd
mongo_install(
    name = "mongocryptd",
    srcs = [],
    deps = [
        "//src/mongo/db/modules/enterprise:mongocryptd",
    ],
)

# This reflects the package that actually gets released during packaging. Be careful
# when changing this definition
# This sets up targets for install-dist and archive-dist
mongo_install(
    name = "dist",
    srcs = [
        "//src/mongo/db:mongod",
        "//src/mongo/installer/compass:compass_files",
        "//src/mongo/s:mongos",
    ] + select({
        "@platforms//os:windows": ["@local_windows_msvc//:vc_redist_x64"],
        "//conditions:default": [],
    }),
    include_files = select({
        "//bazel/config:al2023_x86_64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-x86_64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-x86_64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-x86_64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-x86_64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//bazel/config:al2023_aarch64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-aarch64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-aarch64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-aarch64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-aarch64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//conditions:default": {},
    }),
    package_extract_name = select({
        "//bazel/config:build_enterprise_linux_enabled": "mongodb-linux-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_linux_disabled": "mongodb-linux-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_windows_enabled": "mongodb-win32-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_windows_disabled": "mongodb-win32-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_mac_enabled": "mongodb-macos-{MONGO_ARCH}-enterprise-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//bazel/config:build_enterprise_mac_disabled": "mongodb-macos-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
        "//conditions:default": "mongodb-{MONGO_ARCH}-{MONGO_DISTMOD}-{MONGO_VERSION}",
    }),
    publish_debug_in_stripped = select({
        "@platforms//os:windows": True,
        "//conditions:default": False,
    }),
    deps = [
        "//src/mongo/db/modules/enterprise:dist",
    ],
)

filegroup(
    name = "archive_license_files",
    srcs = [
        "//distsrc:mpl",
        "//distsrc:readme",
        "//distsrc:third_party_notices",
    ] + select({
        "//bazel/config:build_enterprise_enabled": ["//src/mongo/db/modules/enterprise/distsrc:enterprise_license"],
        "//conditions:default": ["//distsrc:community_license"],
    }) + select({
        "//bazel/config:build_enterprise_windows_enabled": ["//src/mongo/db/modules/enterprise/distsrc:windows_notices"],
        "//conditions:default": [],
    }) + select({
        "@platforms//os:macos": ["//etc:mac_plist"],
        "//conditions:default": [],
    }),
)

copy_to_directory(
    name = "mongot_folder",
    srcs = select({
        "//bazel/config:include_mongot_enabled": ["@mongot_localdev//:mongot_binaries"],
        "//conditions:default": [],
    }),
    out = "mongot-localdev",
    include_external_repositories = ["*mongot_localdev"],
    tags = [
        "local",
        "no-cache",
    ],
)

copy_files_to_directory(
    name = "gdb_toolchain_folder",
    srcs = [
        "@gdb_v5//:all_files",
        "@mongo_toolchain_v5//:gcc_pretty_printers",
        "@mongo_toolchain_v5//:llvm_objcopy",
        "@mongo_toolchain_v5//:llvm_readelf",
        "@mongo_toolchain_v5//:llvm_runtime",
    ],
    out = "gdb-toolchain",
    repository_names = [
        "gdb_v5",
        "mongo_toolchain_v5",
    ],
    tags = [
        "local",
        "no-cache",
    ],
)

# This sets up targets for install-gdb and archive-gdb. The archive is a sidecar for
# pretty-printer tests and is intentionally kept separate from dist-test.
mongo_install(
    name = "gdb",
    testonly = True,
    srcs = [],
    package_extract_name = "/",
    root_files = {
        "//:gdb_toolchain_folder": "lib",
    },
    target_compatible_with = ["@platforms//os:linux"],
)

# This sets up targets for install-dist-test and archive-dist-test
mongo_install(
    name = "dist-test",
    srcs = [
        "//src/mongo/db:mongod",
        "//src/mongo/db:mongotrafficreader",
        "//src/mongo/db/query:query_pretty_printers_gdb_test_program",
        "//src/mongo/db/query/query_tester:mongotest",
        "//src/mongo/db/query/search/mongotmock",
        "//src/mongo/db/storage/key_string:ksdecode",
        "//src/mongo/replay:mongor",
        "//src/mongo/s:mongos",
        "//src/mongo/shell:mongo",
        "//src/mongo/tools/mongobridge_tool:mongobridge",
        "//src/mongo/tools/mongosentry_tool:mongosentry",
        "//src/mongo/util:pretty_printer_test_program",
        "//src/third_party/wiredtiger:wt",
    ] + select({
        "@platforms//os:windows": ["@windows_sasl//:bins"],
        "//conditions:default": [],
    }) + select({
        "@platforms//os:linux": ["//src/mongo/db/extension/test_examples:dist_test_extensions"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:include_mongot_enabled": ["//:mongot_folder"],
        "//conditions:default": [],
    }),
    # The externally-published mongot/rerank extensions are built for amazon2023 and amazon2. The
    # amazon2023 artifacts only run on AL2023 hosts, but the amazon2 ones (older glibc) work on
    # every other Linux flavor we support, so ship the matching pair per distro. This is what lets
    # the with_mongot_extension_* suites run on the enterprise Linux nightly variants. Note the
    # plain `dist` target above deliberately stays AL2023-only: what ships to customers is a
    # separate decision.
    include_files = select({
        "//bazel/config:al2023_x86_64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-x86_64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-x86_64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-x86_64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-x86_64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//bazel/config:al2023_aarch64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-aarch64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2023-aarch64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-aarch64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2023-aarch64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//bazel/config:non_al2023_linux_x86_64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2-x86_64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2-x86_64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2-x86_64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2-x86_64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//bazel/config:non_al2023_linux_aarch64": {
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2-aarch64.so": "lib/libmongot_extension.so",
            "//src/mongo/db/extension/extensions:mongot_extension_amazon2-aarch64.so.sig": "lib/libmongot_extension.so.sig",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2-aarch64.so": "lib/librerank_extension.so",
            "//src/mongo/db/extension/extensions:rerank_extension_amazon2-aarch64.so.sig": "lib/librerank_extension.so.sig",
        },
        "//conditions:default": {},
    }),
    pretty_printer_tests = {
        "//src/mongo/util:pretty_printer_test.py": "//src/mongo/util:pretty_printer_test_program",
        "//src/mongo/db/shard_role/lock_manager:lock_gdb_test.py": "//src/mongo/db:mongod",
        "//src/mongo/db/query:query_pretty_printers_gdb_test.py": "//src/mongo/db/query:query_pretty_printers_gdb_test_program",
    },
    root_files = select({
        "//bazel/config:install_gdb_enabled_linux": {
            "//:gdb_toolchain_folder": "lib",
            "//src/mongo/db/extension/test_examples:extension_options_configs": "etc/mongo/extensions",
            "//x509:generate_main_certificates": "bin/x509",
        },
        "//bazel/config:install_gdb_disabled_linux": {
            "//src/mongo/db/extension/test_examples:extension_options_configs": "etc/mongo/extensions",
            "//x509:generate_main_certificates": "bin/x509",
        },
        "//conditions:default": {
            "//x509:generate_main_certificates": "bin/x509",
        },
    }),
    try_zstd = True,
    deps = [
        "//src/mongo/db/modules/atlas:dist-test",
        "//src/mongo/db/modules/enterprise:dist-test",
    ],
)

# This sets up targets for install-mongo_crypt and archive-mongo_crypt
mongo_install(
    name = "mongo_crypt",
    srcs = [],
    package_extract_name = "/",
    deps = [
        "//src/mongo/db/modules/enterprise:mongo_crypt",
    ],
)

# This sets up targets for install-mongo_crypt_shlib_test and archive-mongo_crypt_shlib_test
mongo_install(
    name = "mongo_crypt_shlib_test",
    srcs = [],
    deps = [
        "//src/mongo/db/modules/enterprise:mongo_crypt_shlib_test",
    ],
)

# This sets up targets for install-dbtest and archive-dbtest
mongo_install(
    name = "dbtest",
    srcs = [
        "//src/mongo/dbtests:dbtest",
    ],
)

# This sets up targets for install-sdam_json_test and archive-sdam_json_test
mongo_install(
    name = "sdam_json_test",
    srcs = [
        "//src/mongo/client/sdam:sdam_json_test",
    ],
)

# This sets up targets for install-server_selection_json_test and archive-server_selection_json_test
mongo_install(
    name = "server_selection_json_test",
    srcs = [
        "//src/mongo/client/sdam:server_selection_json_test",
    ],
)

# This is because the install system hardlinks files so permission changes end up
# being reflected on the source code version without this copy
copy_file(
    name = "stitch_header",
    src = "//src/mongo/embedded/stitch_support:stitch_support.h",
    out = "copied_files/stitch_support.h",
)

# This sets up targets for install-stitch_support and archive-stitch_support
mongo_install(
    name = "stitch_support",
    srcs = ["//src/mongo/embedded/stitch_support"],
    package_extract_name = "/",
    root_files = {
        "stitch_header": "include/stitch_support/v1/stitch_support",
    },
)

# This sets up targets for install-stitch_support_test and archive-stitch_support_test
mongo_install(
    name = "stitch_support_test",
    testonly = True,
    srcs = [
        "//src/mongo/embedded/stitch_support:stitch_support_test",
    ],
)

# This sets up targets for install-compass and archive-compass
mongo_install(
    name = "compass",
    srcs = ["//src/mongo/installer/compass:compass_files"],
)

[
    mongo_install(
        name = target_name,
        testonly = True,
        srcs = select({
            "//bazel/config:include_autogenerated_targets_enabled": ["//src/mongo/db/modules/enterprise/autogenerated_targets:" + target_name],
            "//conditions:default": [],
        }),
    )
    for target_name in TEST_TAGS.keys()
    if target_name != "mongo_integration_test"
]

# This sets up targets for install-mongo_integration_test and archive-mongo_integration_test
mongo_install(
    name = "mongo_integration_test",
    testonly = True,
    srcs = select({
        "//bazel/config:include_autogenerated_targets_enabled": [
            "//src/mongo/db:mongod",
            "//src/mongo/db/modules/enterprise/autogenerated_targets:mongo_integration_test",
            "//src/mongo/s:mongos",
            "//src/mongo/shell:mongo",
        ],
        "//conditions:default": [],
    }),
    root_files = select({
        "//bazel/config:include_autogenerated_targets_enabled": {
            "//x509:generate_main_certificates": "bin/x509",
        },
        "//conditions:default": {},
    }),
)

# This sets up targets for install-mongotmock and archive-mongotmock
mongo_install(
    name = "mongotmock",
    srcs = [
        "//src/mongo/db/query/search/mongotmock",
    ],
)

# This sets up targets for install-extensions and archive-extensions.
mongo_install(
    name = "extensions",
    srcs = [
        "//src/mongo/db/extension/test_examples:dist_test_extensions",
    ],
    package_extract_name = "/",
)

# Pre-built binaries downloaded from an archive-dist-test task.
filegroup(
    name = "installed-dist-test",
    srcs = glob(
        [
            "dist-test/**",
        ],
        allow_empty = True,
    ),
)

alias(
    name = "db-contrib-tool",
    actual = "//bazel/db_contrib_tool:db-contrib-tool",
)

# Resmoke config files generated by mongo-task-generator
filegroup(
    name = "generated_resmoke_config",
    srcs = glob(
        [
            "generated_resmoke_config/**",
        ],
        allow_empty = True,
    ),
)

# This sets up targets for install-mongor and archive-mongor
mongo_install(
    name = "mongor",
    srcs = [
        "//src/mongo/replay:mongor",
    ],
)

py_binary(
    name = "gen_dts",
    srcs = [
        "//buildscripts/idl:gen_dts",
    ],
    deps = [
        dependency(
            "pyyaml",
            group = "core",
        ),
        dependency(
            "pymongo",
            group = "core",
        ),
    ],
)

bolt_instrument(
    name = "bolt_instrumented_mongod",
    binary_to_instrument = "//src/mongo/db:mongod",
    exec_properties = {
        "no-cache": "1",
        "no-remote": "1",
        "local": "1",
    },
    instrumentation_output_file = "/tmp/mongod.fdata",
    target_compatible_with = select({
        "//bazel/config:bolt_profile_generate_enabled": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

filegroup(
    name = "clang_tidy_config_files",
    srcs = [
        "//src/mongo/db/modules/enterprise/src/streams:clang_tidy_config",
        "//src/mongo/db/modules/enterprise/src/streams/commands/streams_ops_idl:clang_tidy_config",
    ],
)

# This target only does anything meaningful if you pass pgo_profile_url and bolt_profile_url
# as repo_envs to the build
mongo_install(
    name = "profile_data",
    srcs = ["@bolt_data//:created_bolt_fdata"] + select({
        "//bazel/config:compiler_type_gcc": ["created_pgo_gcda"],
        "//bazel/config:compiler_type_clang": ["@pgo_data//:created_clang_pgo_files"],
        "//conditions:default": [],
    }),
)

pkg_tar(
    name = "created_pgo_gcda",
    srcs = ["@pgo_data//:created_gcc_pgo_files"],
    extension = "tgz",
    package_dir = "mongod_perf",
)