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

load("@io_k8s_repo_infra//defs:build.bzl", "release_filegroup")
load(":container.bzl", "multi_arch_container", "multi_arch_container_push")
load(":platforms.bzl", "SERVER_PLATFORMS", "for_platforms")

# This list defines the docker images that consist a release
DOCKERIZED_BINARIES = {
    "acmesolver": {
        "target": "//cmd/acmesolver:acmesolver",
    },
    "cainjector": {
        "target": "//cmd/cainjector:cainjector",
    },
    "controller": {
        "target": "//cmd/controller:controller",
    },
    "webhook": {
        "target": "//cmd/webhook:webhook",
    },
    "ctl": {
        "target": "//cmd/ctl:ctl",
    },
}

# Allows passing --define image_type custom flag to Bazel command. Used to allow
# optionally build with the dynamic base image. This would only be used by
# alternative/experimental cert-manager builds that, for example, need to create
# dynamically linked binaries due to linking to a C library.
# Example command to build server images with dynamic base:
# bazel run --define image_type=dynamic --platforms=@io_bazel_rules_go//go/toolchain:linux_amd64 //build:server-images.
config_setting(
    name = "dynamic_image",
    values = {
        "define": "image_type=dynamic",
    },
)

# The static base will always be used by default, but having this config setting
# makes it easier to parameterize Bazel commands in the Makefile.
config_setting(
    name = "static_image",
    values = {
        "define": "image_type=static",
    },
)

# When pushing to quay.io, we want to use an arch, since the archless name is now used for a
# manifest list. Bazel doesn't support manifest lists (yet), so we can't do that either.
[multi_arch_container(
    name = binary,
    architectures = SERVER_PLATFORMS["linux"],
    # Always use the static base unless dynamic explicitly requested.
    base = select({
        ":dynamic_image": "@dynamic_base//image",
        ":static_image": "@static_base//image",
        "//conditions:default": "@static_base//image",
    }),
    binary = select(for_platforms(
        for_server = meta["target"],
        only_os = "linux",
    )),
    # Since the multi_arch_container macro replaces the {ARCH} format string,
    # we need to escape the stamping vars.
    docker_tags = ["{{STABLE_DOCKER_REGISTRY}}/cert-manager-%s-{ARCH}:{{STABLE_DOCKER_TAG}}" % binary],
    stamp = 1,
    symlinks = {
        # Some cluster startup scripts expect to find the binaries in /usr/local/bin,
        # but the debs install the binaries into /usr/bin.
        "/usr/local/bin/" + binary: "/usr/bin/" + binary,
    },
    tags = ["manual"],
    user = "1000",
    visibility = ["//visibility:private"],
) for binary, meta in DOCKERIZED_BINARIES.items()]

# Also roll up all images into a single bundle to push with one target.
multi_arch_container_push(
    name = "server-images",
    architectures = SERVER_PLATFORMS["linux"],
    docker_tags_images = {
        "{{STABLE_DOCKER_REGISTRY}}/cert-manager-%s-{ARCH}:{{STABLE_DOCKER_TAG}}" % binary: "%s.image" % binary
        for binary in DOCKERIZED_BINARIES.keys()
    },
    tags = ["manual"],
)

[genrule(
    name = binary + "_docker_tag",
    srcs = [meta["target"]],
    outs = [binary + ".docker_tag"],
    cmd = "grep ^STABLE_DOCKER_TAG bazel-out/stable-status.txt | awk '{print $$2}' >$@",
    stamp = 1,
) for binary, meta in DOCKERIZED_BINARIES.items()]

genrule(
    name = "os_package_version",
    outs = ["version"],
    cmd = """
grep ^STABLE_BUILD_SCM_REVISION bazel-out/stable-status.txt \
    | awk '{print $$2}' \
    | sed -e 's/^v//' -Ee 's/-([a-z]+)/~\\1/' -e 's/-/+/g' \
    >$@
""",
    stamp = 1,
)

# This rule will produce tarballs and docker tags for all server images.
# Building this rule will result in invocation of the multi_arch_container rule
# because the srcs list contains Bazel labels that correspond to the output of
# the native.genrule in multi_arch_container definiton.
release_filegroup(
    name = "server-artifacts",
    srcs = [":%s.tar" % binary for binary in DOCKERIZED_BINARIES.keys()] +
           [":%s.docker_tag" % binary for binary in DOCKERIZED_BINARIES.keys()],
    tags = ["manual"],
)

release_filegroup(
    name = "client-artifacts",
    conditioned_srcs = for_platforms(for_client = [
        "//cmd/ctl:ctl",
    ]),
)

filegroup(
    name = "test-targets",
    srcs = select(for_platforms(
        for_test = [
            "//test/e2e:e2e.test",
            "@com_github_onsi_ginkgo//ginkgo:ginkgo",
            # TODO: include e2e test dependencies like Helm charts, config files etc
        ],
    )),
)

filegroup(
    name = "package-srcs",
    srcs = glob(["**"]),
    tags = ["automanaged"],
    visibility = ["//visibility:private"],
)

filegroup(
    name = "all-srcs",
    srcs = [
        ":package-srcs",
        "//build/release-tars:all-srcs",
    ],
    tags = ["automanaged"],
    visibility = ["//visibility:public"],
)
