# # Tetrodotoxin
# Copyright (c) 2023-present Matt Kaes and contributors

load("@emsdk//emscripten_toolchain:wasm_rules.bzl", "wasm_cc_binary")
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
load("@rules_cc//cc:cc_shared_library.bzl", "cc_shared_library")

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

config_setting(
    name = "cuda_enabled",
    define_values = {"godot_cuda": "1"},
)

cc_shared_library(
    name = "support",
    dynamic_deps = ["@tetrodotoxin//ttx:runtime"],
    shared_lib_name = select({
        ":web": "liblab_support.wasm",
        "//conditions:default": "liblab_support.so",
    }),
    user_link_flags = select({
        ":web": [
            "--oformat=wasm",
            "-sSIDE_MODULE=1",
        ],
        "//conditions:default": [
            "-Wl,-z,defs",
            "-Wl,-rpath,$ORIGIN",
        ],
    }),
    deps = [
        "//gdextension/contracts",
        "//imaging/contracts",
        "//imaging/publication",
        "//plugins/render",
        "//sampling:publication",
        "//sampling/contracts",
    ],
)

cc_binary(
    name = "libgodot_ttx.so",
    srcs = ["addon/register.cpp"],
    copts = [
        "-fvisibility=hidden",
        "-frtti",
    ],
    dynamic_deps = [
        ":support",
        "@tetrodotoxin//ttx:runtime",
    ],
    linkopts = select({
        ":web": [
            "--oformat=wasm",
            "-sSIDE_MODULE=1",
        ],
        "//conditions:default": [
            "-Wl,-z,defs",
            "-Wl,-rpath,$ORIGIN",
        ],
    }),
    linkshared = True,
    linkstatic = True,
    deps = [
        "//adapters:cuda",
        "//adapters:imaging",
        "//gdextension",
    ] + select({
        ":web": ["@godot_cpp_web//:godot_cpp"],
        "//conditions:default": ["@godot_cpp"],
    }),
)

filegroup(
    name = "addon_payload",
    srcs = [
        "addon/editor.gd",
        "addon/godot_ttx.gdextension",
        "addon/plugin.cfg",
        ":libgodot_ttx.so",
        ":support",
        "//extensions/counter:counter_extension",
        "//extensions/sampling:sampler_extension",
        "//plugins/cpu:cpu_provider",
        "//tests:godot_check.gd",
        "@tetrodotoxin//ttx:runtime",
    ] + select({
        ":cuda_enabled": [
            "//plugins/cuda:cuda_provider",
            "@ttx_cuda//cuda:plugin",
        ],
        "//conditions:default": [],
    }),
)

genrule(
    name = "addon",
    srcs = [
        ":addon_payload",
        "//adapters:scripts",
        "//adapters:scene",
        "//adapters:resources",
    ],
    outs = ["godot_ttx.tar"],
    cmd = "tar -chf $@ --transform='s|.*/||' $(locations :addon_payload) && " +
          "tar -rhf $@ --transform='s|^adapters/imaging/scripts/|gdscript/|' $(locations //adapters:scripts) && " +
          "tar -rhf $@ --transform='s|^adapters/imaging/||' $(locations //adapters:scene) && " +
          "tar -rhf $@ --transform='s|^adapters/||' $(locations //adapters:resources)",
)

config_setting(
    name = "web",
    constraint_values = ["@platforms//cpu:wasm32"],
)

# Web uses the same module boundaries as the native addon. Keeping the shared
# runtime separate lets provider allocations and retained objects cross those
# boundaries without privately linking another Perimortem allocator.
wasm_cc_binary(
    name = "web_runtime",
    cc_target = "@tetrodotoxin//ttx:runtime",
    outputs = ["web/libttx_runtime.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_support",
    cc_target = ":support",
    outputs = ["web/liblab_support.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_extension",
    cc_target = ":libgodot_ttx.so",
    outputs = ["web/libgodot_ttx.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_counter",
    cc_target = "//extensions/counter:counter_extension",
    outputs = ["web/libcounter_extension.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_sampler",
    cc_target = "//extensions/sampling:sampler_extension",
    outputs = ["web/libsampler_extension.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_cpu",
    cc_target = "//plugins/cpu:cpu_provider",
    outputs = ["web/libcpu_provider.wasm"],
    simd = "simd128",
    threads = "off",
)

wasm_cc_binary(
    name = "web_binding_check",
    testonly = True,
    cc_target = "@tetrodotoxin//validation/unit_tests/ttx/semantic:portable_binding",
    outputs = [
        "web/portable_binding.js",
        "web/portable_binding.wasm",
    ],
    simd = "simd128",
    threads = "off",
)

# Exercise File's unavailable result through the complete System library in
# the real Wasm target, including host files that must remain untouched.
wasm_cc_binary(
    name = "web_file_check",
    testonly = True,
    cc_target = "@tetrodotoxin//validation:file_portability_check",
    outputs = [
        "web/file_portability_check.js",
        "web/file_portability_check.wasm",
    ],
    simd = "simd128",
    threads = "off",
)
