# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

load("@nonhermetic//:env.bzl", "ENV")
load("@ot_python_deps//:requirements.bzl", "entry_point")

"""Rules for running FuseSoC.

FuseSoC is a package manager and set of build tools for HDL code.

Because we want the output of some FuseSoC built resources to be
available to bazel (such as the verilated chip model for running
tests), the `fusesoc_build` rule allows bazel to delegate certain
targets to FuseSoC.

This rule is not sandboxed, as our current configuration depends
on FuseSoC and its dependencies (verible, verilator, etc) already
having been installed.  In the future, we will try to rework our
dependencies so the FuseSoC rules can be sandboxed.
"""

load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")

def _corefiles2rootarg(core):
    return core.dirname

def _fusesoc_build_impl(ctx):
    dirname = "build.{}".format(ctx.label.name)
    out_dir = ctx.actions.declare_directory(dirname)
    flags = [ctx.expand_location(f, ctx.attr.srcs) for f in ctx.attr.flags]
    outputs = [out_dir]
    groups = {}
    args = ctx.actions.args()

    for group, files in ctx.attr.output_groups.items():
        deps = [ctx.actions.declare_file("{}/{}".format(dirname, f)) for f in files]
        outputs.extend(deps)
        groups[group] = depset(deps)

    if ctx.attr.verilator_options:
        verilator_options = ctx.attr.verilator_options[BuildSettingInfo].value
        flags.append("--verilator_options={}".format(" ".join(verilator_options)))

    if ctx.attr.make_options:
        make_options = ctx.attr.make_options[BuildSettingInfo].value
        flags.append("--make_options={}".format(" ".join(make_options)))

    args.add_all(
        ctx.files.cores,
        uniquify = True,
        map_each = _corefiles2rootarg,
        format_each = "--cores-root=%s",
    )

    args.add_all([
        "run",
        "--flag=fileset_top",
    ])
    args.add(ctx.attr.target, format = "--target=%s")
    args.add_all([
        "--setup",
        "--build",
    ])
    args.add(out_dir.path, format = "--build-root=%s")

    args.add_all(ctx.attr.systems)
    args.add_all(flags)

    _inputs = ctx.files.srcs + ctx.files.cores

    # For some reason, the sanboxed fusesoc would call vivado twice. Add an
    # option to use the system installed fusesoc.
    if ctx.attr.use_system_fusesoc:
        _exec = "fusesoc"
    else:
        _exec = ctx.executable._fusesoc
        _inputs += ctx.files._fusesoc

    # Note: the `fileset_top` flag used above is specific to the OpenTitan
    # project to select the correct RTL fileset.
    ctx.actions.run(
        mnemonic = "FuseSoC",
        outputs = outputs,
        inputs = _inputs,
        arguments = [args],
        executable = _exec,
        use_default_shell_env = False,
        execution_requirements = {
            "no-sandbox": "",
        },
        env = ENV,
    )
    return [
        DefaultInfo(
            files = depset(outputs),
            data_runfiles = ctx.runfiles(files = outputs + ctx.files.data),
        ),
        OutputGroupInfo(**groups),
    ]

fusesoc_build = rule(
    implementation = _fusesoc_build_impl,
    attrs = {
        "cores": attr.label_list(allow_files = True, doc = "FuseSoC core specification files"),
        "srcs": attr.label_list(allow_files = True, doc = "Source files"),
        "data": attr.label_list(allow_files = True, doc = "Files needed at runtime"),
        "target": attr.string(mandatory = True, doc = "Target name (e.g. 'sim')"),
        "systems": attr.string_list(mandatory = True, doc = "Systems to build"),
        "flags": attr.string_list(doc = "Flags controlling the FuseSOC system build"),
        "output_groups": attr.string_list_dict(
            allow_empty = True,
            doc = "Mapping of group name to lists of files in that named group",
        ),
        "verilator_options": attr.label(),
        "make_options": attr.label(),
        "use_system_fusesoc": attr.bool(
            default = False,
            doc = "Use non-sanboxed fusesoc (for FPGA vivado build)",
        ),
        "_fusesoc": attr.label(
            default = entry_point("fusesoc"),
            executable = True,
            cfg = "exec",
        ),
    },
)
