load("@fbcode_macros//build_defs:build_file_migration.bzl", "fbcode_target", "non_fbcode_target")
load("@fbcode_macros//build_defs:cpp_library.bzl", "cpp_library")
load(
    "@fbsource//tools/build_defs:platform_defs.bzl",
    "IOS",
    "MACOSX",
)
load("@fbsource//tools/build_defs:selects.bzl", "selects")
load(
    "../../defs.bzl",
    "folly_xplat_library",
)

oncall("fbcode_entropy_wardens_folly")

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "compatibility",
    srcs = [
    ],
    apple_sdks = (IOS, MACOSX),
    raw_headers = [
        "Compatibility.h",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "exception_tracer_base",
    srcs = [
        "ExceptionTracer.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    raw_headers = [
        "ExceptionTracer.h",
    ],
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:symbolizer",
        "//third-party/glog:glog",
        "//xplat/folly:cpp_attributes",
        "//xplat/folly:portability",
        "//xplat/folly:string",
        "//xplat/folly/debugging/exception_tracer:exception_abi",
        "//xplat/folly/debugging/exception_tracer:stacktrace",
        "//xplat/third-party/linker_lib:dl",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "exception_abi",
    raw_headers = [
        "ExceptionAbi.h",
    ],
    exported_deps = [
        "//xplat/folly/debugging/exception_tracer:compatibility",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "smart_exception_tracer",
    srcs = [
        "SmartExceptionTracer.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    link_whole = True,
    raw_headers = [
        "SmartExceptionTracer.h",
    ],
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:symbolizer",
        "//xplat/folly:exception_wrapper",
        "//xplat/folly:map_util",
        "//xplat/folly:scope_guard",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_base",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_callbacks",
        "//xplat/folly/debugging/exception_tracer:smart_exception_tracer_singleton",
        "//xplat/folly/lang:exception",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "smart_exception_tracer_singleton",
    srcs = [
        "SmartExceptionTracerSingleton.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    raw_headers = [
        "SmartExceptionTracerSingleton.h",
    ],
    exported_deps = [
        "//xplat/folly:synchronized",
        "//xplat/folly/container:f14_hash",
        "//xplat/folly/debugging/exception_tracer:stacktrace",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "smart_exception_stack_trace_hooks",
    srcs = [
        "SmartExceptionStackTraceHooks.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    link_whole = True,
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:symbolizer",
        ":exception_tracer_callbacks",
        ":smart_exception_tracer_singleton",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "exception_counter",
    srcs = [
        "ExceptionCounterLib.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    link_whole = True,
    raw_headers = [
        "ExceptionCounterLib.h",
    ],
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:symbolizer",
        "fbsource//xplat/folly/hash:spooky_hash_v2",
        "fbsource//xplat/folly/synchronization:rw_spin_lock",
        "//xplat/folly:range",
        "//xplat/folly:singleton_thread_local",
        "//xplat/folly:synchronized",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_base",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_callbacks",
        "//xplat/folly/debugging/exception_tracer:stacktrace",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "exception_tracer",
    srcs = [
        "ExceptionStackTraceLib.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    link_whole = True,
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:symbolizer",
        "//xplat/folly:utility",
        "//xplat/folly/debugging/exception_tracer:exception_abi",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_base",
        "//xplat/folly/debugging/exception_tracer:exception_tracer_callbacks",
        "//xplat/folly/debugging/exception_tracer:stacktrace",
    ],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "stacktrace",
    srcs = [
        "StackTrace.cpp",
    ],
    apple_sdks = (IOS, MACOSX),
    raw_headers = [
        "StackTrace.h",
    ],
    deps = [
        "fbsource//xplat/folly/experimental/symbolizer:stack_trace",
        "//xplat/folly:portability",
    ],
)

FBCODE_STATIC_LIBSTDCXX_SELECTOR = selects.and_(
    selects.cond("ovr_config//runtime/constraints:fbcode"),
    selects.cond("ovr_config//cpp:libstdc++"),
    selects.or_(
        selects.cond("fbsource//arvr/third-party/toolchains/platform010/build/libgcc:libgcc-static"),
        selects.cond("ovr_config//third-party/libgcc:11.x"),
    ),
)

FOLLY_SHOULD_INSTALL_STATIC_CXA_FUNCTIONS_WRAPPERS = selects.or_(
    selects.cond("fbsource//xplat/toolchains/android/ndk:cxx-static-runtime-type"),
    FBCODE_STATIC_LIBSTDCXX_SELECTOR,
)

FOLLY_SHOULD_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER = selects.or_(
    selects.cond("fbsource//xplat/toolchains/android/ndk:cxx-static-runtime-type"),
    FBCODE_STATIC_LIBSTDCXX_SELECTOR,
)

EXCEPTION_TRACER_LIB_COMPILER_FLAGS = selects.if_(
    FOLLY_SHOULD_INSTALL_STATIC_CXA_FUNCTIONS_WRAPPERS,
    ["-DFOLLY_INSTALL_STATIC_CXA_FUNCTIONS_WRAPPERS=1"],
    [],
) + selects.if_(
    FOLLY_SHOULD_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER,
    ["-DFOLLY_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER=1"],
    [],
)

EXCEPTION_TRACER_LIB_EXPORTED_LINKER_FLAGS = selects.if_(
    FOLLY_SHOULD_INSTALL_STATIC_CXA_FUNCTIONS_WRAPPERS,
    [
        # @fb-only[end= ]: "-Wl,--wrap=__cxa_throw",
        # @fb-only[end= ]: "-Wl,--wrap=__cxa_rethrow",
        # @fb-only[end= ]: "-Wl,--wrap=__cxa_begin_catch",
        # @fb-only[end= ]: "-Wl,--wrap=__cxa_end_catch",
    ],
    [],
) + selects.if_(
    FOLLY_SHOULD_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER,
    select({
        "DEFAULT": ["-Wl,--wrap=_ZSt17rethrow_exceptionSt13exception_ptr"],
        "ovr_config//cpp:libstdc++": ["-Wl,--wrap=_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE"],
    }),
    [],
)

non_fbcode_target(
    _kind = folly_xplat_library,
    name = "exception_tracer_callbacks",
    srcs = [
        "ExceptionTracerLib.cpp",
    ],
    compiler_flags = EXCEPTION_TRACER_LIB_COMPILER_FLAGS,
    exported_linker_flags = EXCEPTION_TRACER_LIB_EXPORTED_LINKER_FLAGS,
    link_whole = True,
    raw_headers = [
        "ExceptionTracerLib.h",
    ],
    deps = [
        "//xplat/folly:indestructible",
        "//xplat/folly:portability",
        "//xplat/folly:shared_mutex",
        "//xplat/folly:synchronized",
        "//xplat/folly/debugging/exception_tracer:compatibility",
        "//xplat/third-party/linker_lib:dl",
    ],
)

# !!!! fbcode/folly/debugging/exception_tracer/TARGETS was merged into this file, see https://fburl.com/workplace/xl8l9yuo for more info !!!!

fbcode_target(
    _kind = cpp_library,
    name = "compatibility",
    srcs = [],
    headers = ["Compatibility.h"],
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_abi",
    headers = ["ExceptionAbi.h"],
    exported_deps = [
        ":compatibility",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_counter",
    srcs = ["ExceptionCounterLib.cpp"],
    headers = ["ExceptionCounterLib.h"],
    deps = [
        ":exception_tracer_callbacks",
        ":stacktrace",
        "//folly:range",
        "//folly:singleton_thread_local",
        "//folly:synchronized",
        "//folly/experimental/symbolizer:symbolizer",
        "//folly/hash:spooky_hash_v2",
        "//folly/synchronization:rw_spin_lock",
    ],
    exported_deps = [
        ":compatibility",
        ":exception_tracer_base",
        ":exception_tracer_callbacks",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_counter_static_registration",
    srcs = ["ExceptionCounterLibStaticRegistration.cpp"],
    link_whole = True,
    deps = [
        ":exception_counter",
        ":exception_tracer_callbacks",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_tracer",
    srcs = ["ExceptionStackTraceLib.cpp"],
    headers = [],
    link_whole = True,
    deps = [
        ":exception_abi",
        ":exception_tracer_base",
        ":exception_tracer_callbacks",
        ":stacktrace",
        "//folly:utility",
    ],
    exported_deps = [
        ":exception_tracer_callbacks",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_tracer_base",
    srcs = ["ExceptionTracer.cpp"],
    headers = ["ExceptionTracer.h"],
    # Usage of dlsym(RTLD_NEXT, "symbol") does not always work with link groups
    # due to relying on link order. Excluding all libs with `RTLD_NEXT` usage from any link group.
    labels = ["EXCLUDED_FROM_LINK_GROUPS"],
    deps = [
        ":exception_abi",
        ":stacktrace",
        "//folly:portability",
        "//folly:string",
        "//folly/experimental/symbolizer:symbolizer",
    ],
    exported_deps = [
        "//folly/portability:config",
    ],
    external_deps = [
        "glog",
        ("glibc", None, "dl"),
    ],
)

LIBSTDCXX_BUCKIFIED_SELECTOR = selects.and_(
    selects.cond("ovr_config//cpp:libstdc++"),
    selects.cond("ovr_config//third-party/libgcc:11.x"),
)

STATIC_CXX_STDLIB_SELECTOR = selects.or_(
    LIBSTDCXX_BUCKIFIED_SELECTOR,
)

fbcode_target(
    _kind = cpp_library,
    name = "exception_tracer_callbacks",
    srcs = ["ExceptionTracerLib.cpp"],
    headers = ["ExceptionTracerLib.h"],
    compiler_flags = selects.if_(
        STATIC_CXX_STDLIB_SELECTOR,
        select({
            "DEFAULT": [],
            "ovr_config//cpp:libc++": ["-DFOLLY_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER=1"],
            "ovr_config//cpp:libstdc++": [
                "-DFOLLY_INSTALL_STATIC_CXA_FUNCTIONS_WRAPPERS=1",
                "-DFOLLY_INSTALL_STD_RETHROW_EXCEPTION_WRAPPER=1",
            ],
        }),
        [],
    ),
    exported_linker_flags = selects.if_(
        STATIC_CXX_STDLIB_SELECTOR,
        select({
            "DEFAULT": [],
            "ovr_config//cpp:libc++": [
                "-Wl,--wrap=_ZSt17rethrow_exceptionSt13exception_ptr",
            ],
            "ovr_config//cpp:libstdc++": [
                "-Wl,--wrap=__cxa_throw",
                "-Wl,--wrap=__cxa_rethrow",
                "-Wl,--wrap=__cxa_begin_catch",
                "-Wl,--wrap=__cxa_end_catch",
                "-Wl,--wrap=_ZSt17rethrow_exceptionNSt15__exception_ptr13exception_ptrE",
            ],
        }),
        [],
    ),
    labels = ["EXCLUDED_FROM_LINK_GROUPS"],
    link_whole = True,
    supports_python_dlopen = True,
    deps = [
        "//folly:indestructible",
        "//folly:portability",
        "//folly:shared_mutex",
        "//folly:synchronized",
    ],
    exported_deps = [
        ":compatibility",
    ],
    external_deps = [
        ("glibc", None, "dl"),
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "stacktrace",
    srcs = ["StackTrace.cpp"],
    headers = ["StackTrace.h"],
    deps = [
        "//folly/experimental/symbolizer:stack_trace",
    ],
    exported_deps = [
        "//folly:portability",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "smart_exception_tracer_singleton",
    srcs = [
        "SmartExceptionTracerSingleton.cpp",
    ],
    headers = [
        "SmartExceptionTracerSingleton.h",
    ],
    exported_deps = [
        ":stacktrace",
        "//folly:synchronized",
        "//folly/container:f14_hash",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "smart_exception_stack_trace_hooks",
    srcs = [
        "SmartExceptionStackTraceHooks.cpp",
    ],
    link_whole = True,
    deps = [
        ":exception_tracer_callbacks",
        ":smart_exception_tracer_singleton",
        "//folly/experimental/symbolizer:symbolizer",
    ],
)

fbcode_target(
    _kind = cpp_library,
    name = "smart_exception_tracer",
    srcs = ["SmartExceptionTracer.cpp"],
    headers = ["SmartExceptionTracer.h"],
    deps = [
        ":exception_tracer_callbacks",
        ":smart_exception_tracer_singleton",
        ":stacktrace",
        "//folly:map_util",
        "//folly:scope_guard",
        "//folly:synchronized",
        "//folly/container:f14_hash",
        "//folly/lang:exception",
    ],
    exported_deps = [
        ":compatibility",
        ":exception_tracer_base",
        ":exception_tracer_callbacks",
        "//folly:exception_wrapper",
    ],
    external_deps = [
        "glog",
    ],
)
