# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "objc_library")
load("//bazel/tools:brpc_proto_library.bzl", "brpc_proto_library")

licenses(["notice"])  # Apache v2

exports_files(["LICENSE"])

COPTS = [
    "-fno-omit-frame-pointer",
] + select({
    "//bazel/config:brpc_with_asan": ["-fsanitize=address"],
    "//conditions:default": [],
})

DEFINES = [
    "BTHREAD_USE_FAST_PTHREAD_MUTEX",
    "__const__=__unused__",
    "_GNU_SOURCE",
    "USE_SYMBOLIZE",
    "NO_TCMALLOC",
    "__STDC_FORMAT_MACROS",
    "__STDC_LIMIT_MACROS",
    "__STDC_CONSTANT_MACROS",
] + select({
     "//bazel/config:brpc_with_glog": ["BRPC_WITH_GLOG=1"],
     "//conditions:default": ["BRPC_WITH_GLOG=0"],
 }) + select({
     "//bazel/config:brpc_with_mesalink": ["USE_MESALINK"],
     "//conditions:default": [],
 }) + select({
     "//bazel/config:brpc_with_thrift": ["ENABLE_THRIFT_FRAMED_PROTOCOL=1"],
     "//conditions:default": [],
 }) + select({
     "//bazel/config:brpc_with_thrift_legacy_version": [],
     "//conditions:default": ["THRIFT_STDCXX=std"],
 }) + select({
     "//bazel/config:brpc_with_rdma": ["BRPC_WITH_RDMA=1"],
     "//conditions:default": [],
 }) + select({
     "//bazel/config:brpc_with_debug_bthread_sche_safety": ["BRPC_DEBUG_BTHREAD_SCHE_SAFETY=1"],
     "//conditions:default": ["BRPC_DEBUG_BTHREAD_SCHE_SAFETY=0"],
 }) + select({
     "//bazel/config:brpc_with_debug_lock": ["BRPC_DEBUG_LOCK=1"],
     "//conditions:default": ["BRPC_DEBUG_LOCK=0"],
 }) + select({
     "//bazel/config:brpc_with_no_pthread_mutex_hook": ["NO_PTHREAD_MUTEX_HOOK"],
     "//conditions:default": [],
 })

LINKOPTS = [
    "-pthread",
    "-ldl",
] + select({
    "@bazel_tools//src/conditions:darwin": [
        "-framework CoreFoundation",
        "-framework CoreGraphics",
        "-framework CoreData",
        "-framework CoreText",
        "-framework Security",
        "-framework Foundation",
        "-Wl,-U,_MallocExtension_ReleaseFreeMemory",
        "-Wl,-U,_ProfilerStart",
        "-Wl,-U,_ProfilerStop",
        "-Wl,-U,__Z13GetStackTracePPvii",
        "-Wl,-U,_RegisterThriftProtocol",
        "-Wl,-U,_mallctl",
        "-Wl,-U,_malloc_stats_print",
    ],
    "//conditions:default": [
        "-lrt",
    ],
}) + select({
    "//bazel/config:brpc_with_mesalink": [
        "-lmesalink",
    ],
    "//conditions:default": [],
}) + select({
    "//bazel/config:brpc_with_rdma": [
        "-libverbs",
    ],
    "//conditions:default": [],
}) + select({
        "//bazel/config:brpc_with_asan": ["-fsanitize=address"],
        "//conditions:default": [],
  })

genrule(
    name = "config_h",
    outs = [
        "src/butil/config.h",
    ],
    cmd = """cat << EOF  >$@""" + """
// This file is auto-generated.
#ifndef  BUTIL_CONFIG_H
#define  BUTIL_CONFIG_H
#ifdef BRPC_WITH_GLOG
#undef BRPC_WITH_GLOG
#endif
#define BRPC_WITH_GLOG """ + select({
              "//bazel/config:brpc_with_glog": "1",
              "//conditions:default": "0",
          }) +
          """
#endif  // BUTIL_CONFIG_H
EOF
    """,
)

BUTIL_SRCS = [
    "src/butil/third_party/dmg_fp/g_fmt.cc",
    "src/butil/third_party/dmg_fp/dtoa_wrapper.cc",
    "src/butil/third_party/dynamic_annotations/dynamic_annotations.c",
    "src/butil/third_party/icu/icu_utf.cc",
    "src/butil/third_party/superfasthash/superfasthash.c",
    "src/butil/third_party/modp_b64/modp_b64.cc",
    "src/butil/third_party/symbolize/demangle.cc",
    "src/butil/third_party/symbolize/symbolize.cc",
    "src/butil/third_party/snappy/snappy-sinksource.cc",
    "src/butil/third_party/snappy/snappy-stubs-internal.cc",
    "src/butil/third_party/snappy/snappy.cc",
    "src/butil/third_party/murmurhash3/murmurhash3.cpp",
    "src/butil/arena.cpp",
    "src/butil/at_exit.cc",
    "src/butil/atomicops_internals_x86_gcc.cc",
    "src/butil/base64.cc",
    "src/butil/base64url.cc",
    "src/butil/big_endian.cc",
    "src/butil/cpu.cc",
    "src/butil/debug/alias.cc",
    "src/butil/debug/asan_invalid_access.cc",
    "src/butil/debug/crash_logging.cc",
    "src/butil/debug/debugger.cc",
    "src/butil/debug/debugger_posix.cc",
    "src/butil/debug/dump_without_crashing.cc",
    "src/butil/debug/proc_maps_linux.cc",
    "src/butil/debug/stack_trace.cc",
    "src/butil/debug/stack_trace_posix.cc",
    "src/butil/environment.cc",
    "src/butil/files/file.cc",
    "src/butil/files/file_posix.cc",
    "src/butil/files/file_enumerator.cc",
    "src/butil/files/file_enumerator_posix.cc",
    "src/butil/files/file_path.cc",
    "src/butil/files/file_path_constants.cc",
    "src/butil/files/memory_mapped_file.cc",
    "src/butil/files/memory_mapped_file_posix.cc",
    "src/butil/files/scoped_file.cc",
    "src/butil/files/scoped_temp_dir.cc",
    "src/butil/file_util.cc",
    "src/butil/file_util_posix.cc",
    "src/butil/guid.cc",
    "src/butil/guid_posix.cc",
    "src/butil/hash.cc",
    "src/butil/lazy_instance.cc",
    "src/butil/location.cc",
    "src/butil/memory/aligned_memory.cc",
    "src/butil/memory/ref_counted.cc",
    "src/butil/memory/ref_counted_memory.cc",
    "src/butil/memory/singleton.cc",
    "src/butil/memory/weak_ptr.cc",
    "src/butil/posix/file_descriptor_shuffle.cc",
    "src/butil/posix/global_descriptors.cc",
    "src/butil/process_util.cc",
    "src/butil/rand_util.cc",
    "src/butil/rand_util_posix.cc",
    "src/butil/fast_rand.cpp",
    "src/butil/safe_strerror_posix.cc",
    "src/butil/sha1_portable.cc",
    "src/butil/strings/latin1_string_conversions.cc",
    "src/butil/strings/nullable_string16.cc",
    "src/butil/strings/safe_sprintf.cc",
    "src/butil/strings/string16.cc",
    "src/butil/strings/string_number_conversions.cc",
    "src/butil/strings/string_split.cc",
    "src/butil/strings/string_piece.cc",
    "src/butil/strings/string_util.cc",
    "src/butil/strings/string_util_constants.cc",
    "src/butil/strings/stringprintf.cc",
    "src/butil/strings/utf_offset_string_conversions.cc",
    "src/butil/strings/utf_string_conversion_utils.cc",
    "src/butil/strings/utf_string_conversions.cc",
    "src/butil/synchronization/cancellation_flag.cc",
    "src/butil/synchronization/condition_variable_posix.cc",
    "src/butil/synchronization/waitable_event_posix.cc",
    "src/butil/threading/non_thread_safe_impl.cc",
    "src/butil/threading/platform_thread_posix.cc",
    "src/butil/threading/simple_thread.cc",
    "src/butil/threading/thread_checker_impl.cc",
    "src/butil/threading/thread_collision_warner.cc",
    "src/butil/threading/thread_id_name_manager.cc",
    "src/butil/threading/thread_local_posix.cc",
    "src/butil/threading/thread_local_storage.cc",
    "src/butil/threading/thread_local_storage_posix.cc",
    "src/butil/threading/thread_restrictions.cc",
    "src/butil/threading/watchdog.cc",
    "src/butil/time/clock.cc",
    "src/butil/time/default_clock.cc",
    "src/butil/time/default_tick_clock.cc",
    "src/butil/time/tick_clock.cc",
    "src/butil/time/time.cc",
    "src/butil/time/time_posix.cc",
    "src/butil/version.cc",
    "src/butil/logging.cc",
    "src/butil/class_name.cpp",
    "src/butil/errno.cpp",
    "src/butil/find_cstr.cpp",
    "src/butil/status.cpp",
    "src/butil/string_printf.cpp",
    "src/butil/thread_local.cpp",
    "src/butil/thread_key.cpp",
    "src/butil/unix_socket.cpp",
    "src/butil/endpoint.cpp",
    "src/butil/fd_utility.cpp",
    "src/butil/files/temp_file.cpp",
    "src/butil/files/file_watcher.cpp",
    "src/butil/time.cpp",
    "src/butil/zero_copy_stream_as_streambuf.cpp",
    "src/butil/crc32c.cc",
    "src/butil/containers/case_ignored_flat_map.cpp",
    "src/butil/iobuf.cpp",
    "src/butil/single_iobuf.cpp",
    "src/butil/iobuf_profiler.cpp",
    "src/butil/binary_printer.cpp",
    "src/butil/recordio.cc",
    "src/butil/popen.cpp",
] + select({
    "@bazel_tools//src/conditions:darwin": [
        "src/butil/time/time_mac.cc",
        "src/butil/mac/scoped_mach_port.cc",
    ],
    "//conditions:default": [
        "src/butil/file_util_linux.cc",
        "src/butil/threading/platform_thread_linux.cc",
        "src/butil/strings/sys_string_conversions_posix.cc",
    ],
})

objc_library(
    name = "macos_lib",
    hdrs = [
        "src/butil/atomicops.h",
        "src/butil/atomicops_internals_atomicword_compat.h",
        "src/butil/atomicops_internals_mac.h",
        "src/butil/base_export.h",
        "src/butil/basictypes.h",
        "src/butil/build_config.h",
        "src/butil/compat.h",
        "src/butil/compiler_specific.h",
        "src/butil/containers/hash_tables.h",
        "src/butil/debug/debugger.h",
        "src/butil/debug/leak_annotations.h",
        "src/butil/file_descriptor_posix.h",
        "src/butil/file_util.h",
        "src/butil/files/file.h",
        "src/butil/files/file_path.h",
        "src/butil/files/scoped_file.h",
        "src/butil/lazy_instance.h",
        "src/butil/logging.h",
        "src/butil/mac/bundle_locations.h",
        "src/butil/mac/foundation_util.h",
        "src/butil/mac/scoped_cftyperef.h",
        "src/butil/mac/scoped_typeref.h",
        "src/butil/macros.h",
        "src/butil/string_printf.h",
        "src/butil/memory/aligned_memory.h",
        "src/butil/memory/scoped_policy.h",
        "src/butil/memory/scoped_ptr.h",
        "src/butil/move.h",
        "src/butil/port.h",
        "src/butil/posix/eintr_wrapper.h",
        "src/butil/scoped_generic.h",
        "src/butil/strings/string16.h",
        "src/butil/strings/string_piece.h",
        "src/butil/strings/string_util.h",
        "src/butil/strings/string_util_posix.h",
        "src/butil/strings/sys_string_conversions.h",
        "src/butil/synchronization/lock.h",
        "src/butil/third_party/dynamic_annotations/dynamic_annotations.h",
        "src/butil/third_party/murmurhash3/murmurhash3.h",
        "src/butil/threading/platform_thread.h",
        "src/butil/threading/thread_id_name_manager.h",
        "src/butil/threading/thread_restrictions.h",
        "src/butil/time.h",
        "src/butil/time/time.h",
        "src/butil/type_traits.h",
        ":config_h",
    ],
    enable_modules = True,
    includes = ["src/"],
    non_arc_srcs = [
        "src/butil/mac/bundle_locations.mm",
        "src/butil/mac/foundation_util.mm",
        "src/butil/file_util_mac.mm",
        "src/butil/threading/platform_thread_mac.mm",
        "src/butil/strings/sys_string_conversions_mac.mm",
    ],
    tags = ["manual"],
    deps = [
        "@com_github_gflags_gflags//:gflags",
    ] + select({
        "//bazel/config:brpc_with_glog": ["@com_github_google_glog//:glog"],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "butil",
    srcs = BUTIL_SRCS,
    hdrs = glob([
        "src/butil/*.h",
        "src/butil/*.hpp",
        "src/butil/**/*.h",
        "src/butil/**/*.hpp",
        "src/butil/**/**/*.h",
        "src/butil/**/**/*.hpp",
        "src/butil/**/**/**/*.h",
        "src/butil/**/**/**/*.hpp",
    ]) + [
        "src/butil/third_party/dmg_fp/dtoa.cc",
        ":config_h",
    ],
    defines = DEFINES + select({
        "//bazel/config:brpc_build_for_unittest": [
            "UNIT_TEST",
        ],
        "//conditions:default": [],
    }),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        "@com_github_gflags_gflags//:gflags",
        "@com_github_madler_zlib//:zlib",
        "@com_google_protobuf//:protobuf",
    ] + select({
        "//bazel/config:brpc_with_glog": ["@com_github_google_glog//:glog"],
        "//conditions:default": [],
    }) + select({
        "@bazel_tools//src/conditions:darwin": [":macos_lib"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:brpc_with_boringssl": [
            "@boringssl//:ssl",
            "@boringssl//:crypto"
        ],
        "//conditions:default": [
            "@openssl//:ssl",
            "@openssl//:crypto"
        ],
    }),
)

cc_library(
    name = "bvar",
    srcs = glob(
        [
            "src/bvar/*.cpp",
            "src/bvar/detail/*.cpp",
        ],
        exclude = [
            "src/bvar/default_variables.cpp",
        ],
    ) + select({
        "//bazel/config:brpc_build_for_unittest": [],
        "//conditions:default": ["src/bvar/default_variables.cpp"],
    }),
    hdrs = glob([
        "src/bvar/*.h",
        "src/bvar/utils/*.h",
        "src/bvar/detail/*.h",
    ]),
    defines = [] + select({
        "//bazel/config:with_babylon_counter": ["WITH_BABYLON_COUNTER=1"],
        "//conditions:default": [],
    }) + select({
        "//bazel/config:brpc_build_for_unittest": [
            "BVAR_NOT_LINK_DEFAULT_VARIABLES",
        ],
        "//conditions:default": [],
    }),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
    ]  + select({
        "//bazel/config:with_babylon_counter": ["@babylon//:concurrent_counter"],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "bthread",
    srcs = glob([
        "src/bthread/*.cpp",
    ]),
    hdrs = glob([
        "src/bthread/*.h",
        "src/bthread/*.list",
    ]),
    defines = [] + select({
        "//bazel/config:brpc_with_bthread_tracer": [
            "BRPC_BTHREAD_TRACER",
        ],
        "//conditions:default": [],
    }),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
        ":bvar",
    ] + select({
        "//bazel/config:brpc_with_bthread_tracer": [
            "@com_github_libunwind_libunwind//:libunwind",
            "@com_google_absl//absl/debugging:stacktrace",
            "@com_google_absl//absl/debugging:symbolize",
        ],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "json2pb",
    srcs = glob([
        "src/json2pb/*.cpp",
    ]),
    hdrs = glob([
        "src/json2pb/*.h",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":butil",
    ],
)

cc_library(
    name = "mcpack2pb",
    srcs = [
        "src/mcpack2pb/field_type.cpp",
        "src/mcpack2pb/mcpack2pb.cpp",
        "src/mcpack2pb/parser.cpp",
        "src/mcpack2pb/serializer.cpp",
    ],
    hdrs = glob([
        "src/mcpack2pb/*.h",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc_idl_options_cc_proto",
        ":butil",
    ],
)

filegroup(
    name = "brpc_idl_options_proto_srcs",
    srcs = [
        "src/idl_options.proto",
    ],
    visibility = ["//visibility:public"],
)

brpc_proto_library(
    name = "brpc_idl_options_cc_proto",
    srcs = [":brpc_idl_options_proto_srcs"],
    include = "src",
    visibility = ["//visibility:public"],
)

filegroup(
    name = "brpc_internal_proto_srcs",
    srcs = glob([
        "src/brpc/*.proto",
        "src/brpc/policy/*.proto",
        "src/brpc/rdma/*.proto",
    ]),
    visibility = ["//visibility:public"],
)

brpc_proto_library(
    name = "brpc_internal_cc_proto",
    srcs = [":brpc_internal_proto_srcs"],
    include = "src",
    deps = [":brpc_idl_options_cc_proto"],
    visibility = ["//visibility:public"],
)

cc_library(
    name = "brpc",
    srcs = glob([
        "src/brpc/*.cpp",
        "src/brpc/**/*.cpp",
    ],
    exclude = [
        "src/brpc/thrift_service.cpp",
        "src/brpc/thrift_message.cpp",
        "src/brpc/policy/thrift_protocol.cpp",
        "src/brpc/event_dispatcher_epoll.cpp",
        "src/brpc/event_dispatcher_kqueue.cpp",
    ]) + select({
        "//bazel/config:brpc_with_thrift": glob([
            "src/brpc/thrift*.cpp",
            "src/brpc/**/thrift*.cpp",
        ]),
        "//conditions:default": [],
    }),
    hdrs = glob([
        "src/brpc/*.h",
        "src/brpc/**/*.h",
        "src/brpc/event_dispatcher_epoll.cpp",
        "src/brpc/event_dispatcher_kqueue.cpp",
    ]),
    copts = COPTS,
    includes = [
        "src/",
    ],
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc_internal_cc_proto",
        ":bthread",
        ":butil",
        ":bvar",
        ":json2pb",
        ":mcpack2pb",
        "@com_github_google_leveldb//:leveldb",
    ] + select({
        "//bazel/config:brpc_with_thrift": [
            "@org_apache_thrift//:thrift",
        ],
        "//conditions:default": [],
    }),
)

cc_binary(
    name = "protoc-gen-mcpack",
    srcs = [
        "src/mcpack2pb/generator.cpp",
    ],
    copts = COPTS,
    linkopts = LINKOPTS,
    visibility = ["//visibility:public"],
    deps = [
        ":brpc",
        ":brpc_idl_options_cc_proto",
        "@com_google_protobuf//:protoc_lib",
    ],
)
