#  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": True,
    "@io_bazel_rules_go//go/config:static": True,

    # 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"
        ),
    },
)
