#  Copyright 2020 The Monogon Project Authors.
#
#  SPDX-License-Identifier: Apache-2.0
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

"""
Rules for building Linux kernel images.

This currently performs the build in a fully unhermetic manner, using
make/gcc/... from the sandbox sysroot, and is only slightly better than a genrule. This
should be replaced by a hermetic build that at least uses rules_cc toolchain
information, or even better, just uses cc_library targets.
"""

load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME")
load("@rules_cc//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_toolchain", "use_cc_toolchain")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("//build/utils:detect_root.bzl", "detect_root")
load("//osbase/build:def.bzl", "ignore_unused_configuration")

def _linux_image_impl_resources(_os, _ninputs):
    """
    Configures linux build resources.

    See `resource_set` documentation in builtins.actions Bazel docs.
    """

    # 16 threads seems about right - this fits well in both our build machines and
    # development machines.
    cpu = 16

    # In MB. Picked based on observing build in htop.
    mb_per_cpu = 256
    return {
        "cpu": cpu,
        "memory": cpu * mb_per_cpu,
        "local_test": 0,
    }

DISABLED_FEATURES = []

# NOTE: Multicall tool is called as path/to/llvm clang to workaround bug in out-of-process execution where tool name is repeated and parsing breaks.

def _linux_image_impl(ctx):
    kernel_config = ctx.file.kernel_config
    kernel_src = ctx.files.kernel_src
    image_format = ctx.attr.image_format

    # Root of the given Linux sources.
    root = detect_root(ctx.attr.kernel_src)

    # Figure out target CC toolchain
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = DISABLED_FEATURES + ctx.disabled_features,
    )
    c_compiler_path = cc_common.get_tool_for_action(
        feature_configuration = feature_configuration,
        action_name = C_COMPILE_ACTION_NAME,
    )

    # Figure out Kbuild ARCH option
    target_arch = None
    compressed_image_name = None

    if ctx.target_platform_has_constraint(ctx.attr._constraint_x86_64[platform_common.ConstraintValueInfo]):
        target_arch = "x86"
        compressed_image_name = "bzImage"

    if ctx.target_platform_has_constraint(ctx.attr._constraint_aarch64[platform_common.ConstraintValueInfo]):
        target_arch = "arm64"
        compressed_image_name = "Image"

    if ctx.target_platform_has_constraint(ctx.attr._constraint_riscv64[platform_common.ConstraintValueInfo]):
        target_arch = "riscv"
        compressed_image_name = "Image"

    if not target_arch:
        fail("Target platform does not match expected constraints: @platforms//cpu:x86_64, @platforms//cpu:aarch64, or @platforms//cpu:riscv64.")

    # Tuple containing information about how to build and access the resulting
    # image.
    # The first element (target) is the make target to build, the second
    # (image_source) is the resulting file to be copied and the last
    # (image_name) is the name of the image that will be generated by this
    # rule.
    (target, image_source, image_name) = {
        "vmlinux": ("vmlinux modules", "vmlinux", "vmlinux"),
        "Image": ("all modules", "arch/" + target_arch + "/boot/" + compressed_image_name, "Image"),
    }[image_format]

    image = ctx.actions.declare_file(image_name)
    modinfo = ctx.actions.declare_file("modules.builtin.modinfo")
    modules = ctx.actions.declare_directory("modules")
    ctx.actions.run_shell(
        outputs = [image, modinfo, modules],
        inputs = depset([kernel_config] + kernel_src, transitive = [cc_toolchain.all_files]),
        resource_set = _linux_image_impl_resources,
        command = '''
            kconfig=$1
            target=$2
            image_source=$3
            image=$4
            root=$5
            modinfo=$6
            modules=$7
            arch=$8
            cc=$PWD/$9

            builddir=$(mktemp -d)

            mkdir ${root}/.bin
            cp ${kconfig} ${builddir}/.config
            (cd ${root} && make -j 16 KBUILD_OUTPUT="${builddir}" ARCH="${arch}" CC="${cc//clang/llvm} clang" LD="${cc//clang/ld.lld}" OBJCOPY="${cc//clang/llvm-objcopy}" OBJDUMP="${cc//clang/llvm-objdump}" AR="${cc//clang/llvm-ar}" NM="${cc//clang/llvm-nm}" STRIP="${cc//clang/llvm-strip}" READELF="${cc//clang/llvm-readelf}" olddefconfig ${target} >/dev/null)
            cp "${builddir}"/${image_source} ${image}
            cp "${builddir}"/modules.builtin.modinfo ${modinfo}
            # Not using modules_install as it tries to run depmod and friends
            for f in $(find "${builddir}" -name '*.ko' -type f -printf "%P\n" ); do
                install -D "${builddir}/$f" "${modules}/$f"
            done
            rm -Rf "$builddir"
        ''',
        arguments = [
            kernel_config.path,
            target,
            image_source,
            image.path,
            root,
            modinfo.path,
            modules.path,
            target_arch,
            c_compiler_path,
        ],
        use_default_shell_env = True,
    )

    return [
        DefaultInfo(
            files = depset([image]),
            runfiles = ctx.runfiles(files = [image]),
        ),
        OutputGroupInfo(
            modinfo = depset([modinfo]),
            modules = depset([modules]),
        ),
    ]

linux_image = rule(
    doc = """
        Build Linux kernel image unhermetically in a given format.
    """,
    implementation = _linux_image_impl,
    cfg = ignore_unused_configuration,
    attrs = {
        "kernel_config": attr.label(
            doc = """
                Linux kernel configuration file to build this kernel image with.
            """,
            allow_single_file = True,
        ),
        "kernel_src": attr.label(
            doc = """
                Filegroup containing Linux kernel sources.
            """,
            default = "@linux//:all",
        ),
        "image_format": attr.string(
            doc = """
                Format of generated Linux image, one of 'vmlinux' or 'Image',
            """,
            values = [
                "vmlinux",
                "Image",
            ],
            default = "Image",
        ),
        "_allowlist_function_transition": attr.label(
            default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
        ),
        # Bazel doesn't let you access the target platform directly, use these
        "_constraint_x86_64": attr.label(
            default = "@platforms//cpu:x86_64",
        ),
        "_constraint_aarch64": attr.label(
            default = "@platforms//cpu:aarch64",
        ),
        "_constraint_riscv64": attr.label(
            default = "@platforms//cpu:riscv64",
        ),
    } | CC_TOOLCHAIN_ATTRS,
    toolchains = use_cc_toolchain(),
    fragments = ["cpp"],
)
