load("//bazel:yr.bzl", "cc_strip")
load("//bazel:yr_go.bzl", "yr_go_test")

filegroup(
    name = "go_sources",
    srcs = glob([
        "**/*.go",
        "**/go.mod",
        "**/go.sum",
    ]),
)

cc_strip(
    name = "go_strip",
    srcs = ["//api/go/libruntime/cpplibruntime:libcpplibruntime.so"],
)

genrule(
    name = "yr_go_pkg",
    srcs = [
        "go_strip",
        ":go_sources",
    ] + select({
        "//:disable_datasystem": [],
        "//conditions:default": [
            "@datasystem_sdk//:shared",
        ],
    }) + select({
        "//:disable_observability": [],
        "//conditions:default": [
            "//src/utility/metrics:shared_exporters",
        ],
    }),
    outs = ["yr_go_pkg.out"],
    cmd = """
        BASE_DIR="$$(pwd)" &&
        GO_OUT_DIR=$$BASE_DIR/build/output/runtime/service/go/bin/ &&
        mkdir -p $$GO_OUT_DIR &&
        cd $$BASE_DIR &&
        chmod +w $(locations :go_strip) &&
        if [[ "$$(uname)" != "Darwin" ]]; then chrpath -d $(locations :go_strip) 2>/dev/null || true; fi &&
        cp -R $(locations :go_strip) $$GO_OUT_DIR &&
        for f in $(SRCS); do
            case "$$(basename "$$f")" in
                libtbb.so|libtbb.so.2|libtbb.2.dylib|libdatasystem.so|libdatasystem.dylib|libobservability-*.so|libobservability-*.dylib)
                    [ -f "$$f" ] && cp -R "$$f" $$GO_OUT_DIR || true
                    ;;
            esac
        done &&
        cd $$(realpath $$BASE_DIR/api/go/runtime/) &&
        export GOROOT=/opt/buildtools/golang_go-1.24.1 &&
        export PATH=$$GOROOT/bin:$$PATH &&
        export GOWORK=off &&
        export GOTOOLCHAIN=local &&
        go version &&
        # Build in module mode only. In CI/bazel execroot there is no sibling workspace
        # (for example `../../../yuanrong-frontend`), so we must ignore repository-level go.work.
        go mod tidy &&
        if [[ "$$(uname)" == "Darwin" ]]; then
            CGO_ENABLED=1 go build -buildmode=pie -o $$GO_OUT_DIR/goruntime yr_runtime_main.go
        else
            LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH}:$$GO_OUT_DIR CC='gcc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -O2' go build -buildmode=pie -ldflags '-extldflags "-fPIC -fstack-protector-strong -Wl,-z,now,-z,relro,-z,noexecstack,-s -Wall -Werror"' -o $$GO_OUT_DIR/goruntime yr_runtime_main.go
        fi &&
        cd $$BASE_DIR &&
        chmod -R 750 $$GO_OUT_DIR &&
        GO_SDK_DIR=$$BASE_DIR/build/output/runtime/sdk/go/runtime &&
        rm -rf $$GO_SDK_DIR &&
        mkdir -p $$GO_SDK_DIR &&
        cp -Rf $$BASE_DIR/api/go/libruntime $$GO_SDK_DIR &&
        find $$GO_SDK_DIR/libruntime/ -name *.cpp -delete 2>/dev/null || true &&
        find $$GO_SDK_DIR/libruntime/ -name *.bazel -delete 2>/dev/null || true &&
        cp -Rf $$BASE_DIR/api/go/faassdk $$GO_SDK_DIR &&
        cp -Rf $$BASE_DIR/api/go/posixsdk $$GO_SDK_DIR &&
        cp -Rf $$BASE_DIR/api/go/yr $$GO_SDK_DIR &&
        cp -Rf $$BASE_DIR/api/go/go.mod $$GO_SDK_DIR &&
        cp -Rf $$BASE_DIR/api/go/README.md $$GO_SDK_DIR &&
        echo "$$GO_OUT_DIR" > $@
    """,
    local = True,
    visibility = ["//visibility:public"],
)

config_setting(
    name = "asan",
    values = {"define": "sanitize=address"},
)

config_setting(
    name = "tsan",
    values = {"define": "sanitize=thread"},
)

alias(
    name = "yr_go_test",
    actual = select({
        ":asan": "yr_go_test_asan",
        ":tsan": "yr_go_test_tsan",
        "//conditions:default": "yr_go_test_default",
    }),
)

yr_go_test(
    name = "yr_go_test_asan",
    sanitizer = "address",
)

yr_go_test(
    name = "yr_go_test_tsan",
    sanitizer = "thread",
)

yr_go_test(
    name = "yr_go_test_default",
    sanitizer = "off",
)