#  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("//build/utils:detect_root.bzl", "detect_root")


_new_settings = {
    # This list should be expanded with any configuration options that end
    # up reaching this rule with different values across different build
    # graph paths, but that do not actually influence the kernel build.
    # Force-setting them to a stable value forces the build configuration
    # to a stable hash.
    # See the transition's comment block for more information.
    "@io_bazel_rules_go//go/config:pure": False,
    "@io_bazel_rules_go//go/config:static": False,

    # Note: this toolchain is not actually used to perform the build.
    "//command_line_option:platforms": "//build/platforms:linux_amd64_static",
}


def _ignore_unused_configuration_impl(settings, attr):
    return _new_settings

# Transition to flip all known-unimportant but varying configuration options to
# a known, stable value.
# This is to prevent Bazel from creating extra configurations for possible
# combinations of options in case the linux_image rule is pulled through build
# graph fragments that have different options set.
#
# Ideally, Bazel would let us mark in a list that we only care about some set
# of options (or at least let us mark those that we explicitly don't care
# about, instead of manually setting them to some value). However, this doesn't
# seem to be possible, thus this transition is a bit of a hack.
ignore_unused_configuration = transition(
    implementation = _ignore_unused_configuration_impl,
    inputs = [],
    outputs = list(_new_settings.keys()),
)

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,
    }

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

    # 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'),
        'bzImage': ('all modules', 'arch/x86/boot/bzImage', 'bzImage'),
    }[image_format]

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

    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 = [ kernel_config ] + kernel_src,
        resource_set = _linux_image_impl_resources,
        command = '''
            kconfig=$1
            target=$2
            image_source=$3
            image=$4
            root=$5
            modinfo=$6
            modules=$7

            builddir=$(mktemp -d)

            mkdir ${root}/.bin
            cp ${kconfig} ${builddir}/.config
            (cd ${root} && KBUILD_OUTPUT="${builddir}" make -j 16 ${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,
        ],
        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,
            default = ":linux-metropolis.config",
        ),
        "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 'bzImage',
            ''',
            values = [
                'vmlinux', 'bzImage',
            ],
            default = 'bzImage',
        ),
        "_allowlist_function_transition": attr.label(
            default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
        ),
    },
)
