load("@rules_cc//cc:defs.bzl", "cc_library")

package(default_visibility = ["//visibility:private"])

cc_library(
    name = "blake3",
    visibility = ["//visibility:public"],
    deps = [
        ":blake3_internal_dispatch",
        ":blake3_internal_headers",
    ],
)

cc_library(
    name = "blake3_internal_headers",
    hdrs = [
        "blake3.h",
        "blake3_impl.h",
    ],
)

cc_library(
    name = "blake3_internal_dispatch_c",
    srcs = [
        "blake3.c",
        "blake3_dispatch.c",
        "blake3_portable.c",
    ],
    copts = select({
        "@platforms//os:windows": [],
        "//conditions:default": [
            "-std=c99",
            "-fvisibility=hidden",
        ],
    }),
    deps = [
        ":blake3_internal_headers",
    ],
    linkstatic = True,
)

cc_library(
    name = "blake3_internal_dispatch_tbb",
    srcs = ["blake3_tbb.cpp"],
    copts = select({
        "@platforms//os:windows": [
            "/std:c++20",
            "/EHs-c-",  # No exceptions
            "/GR-",     # No RTTI
        ],
        "//conditions:default": [
            "-std=c++20",
            "-fno-exceptions",
            "-fno-rtti",
            "-fvisibility=hidden",
        ],
    }),
    defines = [
        "BLAKE3_USE_TBB",
        "TBB_USE_EXCEPTIONS=0",
    ],
    deps = [
        ":blake3_internal_headers",
        "@onetbb//:tbb",
    ],
    linkstatic = True,
)

cc_library(
    name = "blake3_internal_dispatch",
    deps = [
        ":blake3_internal_dispatch_c",
    ] + select({
        "//:tbb_enabled": [":blake3_internal_dispatch_tbb"],
        "//conditions:default": [],
    }) + select({
        "@platforms//cpu:aarch64": [":blake3_internal_neon"],
        "@platforms//cpu:x86_32": [
            ":blake3_internal_sse2",
            ":blake3_internal_sse41",
            ":blake3_internal_avx2",
            ":blake3_internal_avx512",
        ],
        "@platforms//cpu:x86_64": [
            ":blake3_internal_sse2_x86-64_asm",
            ":blake3_internal_sse41_x86-64_asm",
            ":blake3_internal_avx2_x86-64_asm",
            ":blake3_internal_avx512_x86-64_asm",
        ],
        "//conditions:default": [],
    }),
)

cc_library(
    name = "blake3_internal_sse2",
    srcs = ["blake3_sse2.c"],
    copts = select({
        "@platforms//os:windows": ["/arch:SSE2"],
        "//conditions:default": ["-msse2"],
    }),
    deps = [":blake3_internal_headers"],
)

cc_library(
    name = "blake3_internal_sse41",
    srcs = ["blake3_sse41.c"],
    copts = select({
        # MSVC has no dedicated sse4.1 flag
        "@platforms//os:windows": ["/arch:AVX"],
        "//conditions:default": ["-msse4.1"],
    }),
    deps = [":blake3_internal_headers"],
)

cc_library(
    name = "blake3_internal_avx2",
    srcs = ["blake3_avx2.c"],
    copts = select({
        "@platforms//os:windows": ["/arch:AVX2"],
        "//conditions:default": ["-mavx2"],
    }),
    deps = [":blake3_internal_headers"],
)

cc_library(
    name = "blake3_internal_avx512",
    srcs = ["blake3_avx512.c"],
    copts = select({
        "@platforms//os:windows": ["/arch:AVX512"],
        "//conditions:default": [
            "-mavx512f",
            "-mavx512vl",
        ],
    }),
    deps = [":blake3_internal_headers"],
)

cc_library(
    name = "blake3_internal_neon",
    srcs = ["blake3_neon.c"],
    defines = ["BLAKE3_USE_NEON=1"],
    deps = [":blake3_internal_headers"],
)

cc_library(
    name = "blake3_internal_sse2_x86-64_asm",
    srcs = select({
        "@platforms//os:windows": ["blake3_sse2_x86-64_windows_msvc.asm"],
        "//conditions:default": ["blake3_sse2_x86-64_unix.S"],
    }),
)

cc_library(
    name = "blake3_internal_sse41_x86-64_asm",
    srcs = select({
        "@platforms//os:windows": ["blake3_sse41_x86-64_windows_msvc.asm"],
        "//conditions:default": ["blake3_sse41_x86-64_unix.S"],
    }),
)

cc_library(
    name = "blake3_internal_avx2_x86-64_asm",
    srcs = select({
        "@platforms//os:windows": ["blake3_avx2_x86-64_windows_msvc.asm"],
        "//conditions:default": ["blake3_avx2_x86-64_unix.S"],
    }),
)

cc_library(
    name = "blake3_internal_avx512_x86-64_asm",
    srcs = select({
        "@platforms//os:windows": ["blake3_avx512_x86-64_windows_msvc.asm"],
        "//conditions:default": ["blake3_avx512_x86-64_unix.S"],
    }),
)
