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

load("//rules:rv.bzl", "rv_rule")
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")

def _get_assembler(cc_toolchain):
    """Find the path to riscv-unknown-elf-as."""

    # Note: the toolchain config doesn"t appear to have a good way to get
    # access to the assembler.  We should be able to access it via the
    # the compiler, but I had trouble with //hw/ip/otbn/util/otbn_as.py invoking
    # the compiler as assembler.
    return [f for f in cc_toolchain.all_files.to_list() if f.basename.endswith("as")][0]

def _otbn_assemble_sources(ctx):
    """Helper function that, for each source file in the provided context, adds
    an action to the context that invokes the otbn assember (otbn_as.py),
    producing a corresponding object file. Returns a list of all object files
    that will be generated by these actions.
    """
    cc_toolchain = find_cc_toolchain(ctx).cc
    assembler = _get_assembler(cc_toolchain)

    objs = []
    for src in ctx.files.srcs:
        obj = ctx.actions.declare_file(src.basename.replace("." + src.extension, ".o"))
        objs.append(obj)
        ctx.actions.run(
            outputs = [obj],
            inputs = ([src] +
                      cc_toolchain.all_files.to_list() +
                      [ctx.executable._otbn_as]),
            env = {
                "RV32_TOOL_AS": assembler.path,
            },
            arguments = ["-o", obj.path, src.path],
            executable = ctx.executable._otbn_as,
        )

    return objs

def _otbn_library(ctx):
    """Produces a collection of object files, one per source file, that can be
    used as a dependency for otbn binaries."""
    objs = _otbn_assemble_sources(ctx)

    return [
        DefaultInfo(
            files = depset(objs),
            data_runfiles = ctx.runfiles(files = objs),
        ),
    ]

def _otbn_binary(ctx):
    """The build process for otbn resources currently invokes
    `//hw/ip/otbn/util/otbn_{as,ld,...}.py` to build the otbn resource.
    These programs are python scripts which translate otbn special
    instructions into the proper opcode sequences and _then_ invoke the normal
    `rv32-{as,ld,...}` programs to produce the resource.  These "native"
    otbn resources are the `otbn_objs` and `elf` output groups.

    In order to make the otbn resource useful to the the main CPU, the
    otbn resource needs to be included as a blob of data that the main
    CPU can dump into the otbn `imem` area and ask otbn to execute it.
    `util/otbn-build.py` does this with some objcopy-fu, emitting
    `foo.rv32embed.o`.  Bazel's `cc_*` rules really want dependency objects
    expressed as archives rather than raw object files, so I've modified
    `otbn-build` to also emit an archive file.

    _Morally_, the otbn resource is a data dependency.  However the
    practical meaning of a `data` dependency in bazel is a file made
    available at runtime, which is not how we're using the otbn resource.
    The closest analog is something like `cc_embed_data`, which is like
    a data dependency that needs to be linked into the main program.
    We achieve by having `otbn_build.py` emit a conventional RV32I library
    that other rules can depend on in their `deps`.
    """
    cc_toolchain = find_cc_toolchain(ctx).cc
    assembler = _get_assembler(cc_toolchain)

    # Run the otbn assembler on source files to produce object (.o) files.
    objs = _otbn_assemble_sources(ctx)

    # Declare output files.
    elf = ctx.actions.declare_file(ctx.attr.name + ".elf")
    rv32embed = ctx.actions.declare_file(ctx.attr.name + ".rv32embed.o")
    archive = ctx.actions.declare_file(ctx.attr.name + ".rv32embed.a")

    deps = [f for dep in ctx.attr.deps for f in dep.files.to_list()]

    # Run the otbn_build.py script to link object files from the sources and
    # dependencies.
    ctx.actions.run(
        outputs = [elf, rv32embed, archive],
        inputs = (objs +
                  deps +
                  cc_toolchain.all_files.to_list() +
                  ctx.files._otbn_data +
                  [ctx.executable._wrapper]),
        env = {
            "RV32_TOOL_AS": assembler.path,
            "RV32_TOOL_AR": cc_toolchain.ar_executable,
            "RV32_TOOL_LD": cc_toolchain.ld_executable,
            "RV32_TOOL_OBJCOPY": cc_toolchain.objcopy_executable,
        },
        arguments = [
            "--app-name={}".format(ctx.attr.name),
            "--archive",
            "--no-assembler",
            "--out-dir={}".format(elf.dirname),
        ] + [obj.path for obj in (objs + deps)],
        executable = ctx.executable._wrapper,
    )

    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )

    outputs = objs + [elf, rv32embed, archive]
    return [
        DefaultInfo(files = depset(outputs), data_runfiles = ctx.runfiles(files = outputs)),
        OutputGroupInfo(
            otbn_objs = depset(objs + deps),
            elf = depset([elf]),
            rv32embed = depset([rv32embed]),
            archive = depset([archive]),
        ),
        # Emit a CcInfo provider so that this rule can be a dependency in other
        # cc_* rules.
        CcInfo(
            linking_context = cc_common.create_linking_context(
                linker_inputs = depset([cc_common.create_linker_input(
                    owner = ctx.label,
                    libraries = depset([cc_common.create_library_to_link(
                        actions = ctx.actions,
                        feature_configuration = feature_configuration,
                        cc_toolchain = cc_toolchain,
                        static_library = archive,
                    )]),
                )]),
            ),
        ),
    ]

def _otbn_sim_test(ctx):
    """This rule is for standalone OTBN unit tests, which are run on the host
    via the OTBN simulator.

    It first generates binaries using the same method as otbn_binary, then runs
    them on the simulator. Tests are expected to count failures in the w0
    register; the test checks that w0=0 to determine if the test passed.
    """
    providers = _otbn_binary(ctx)

    # Extract the output .elf file from the output group.
    elf = providers[1].elf.to_list()[0]

    exp_file = ctx.file.exp

    # Create a simple script that runs the OTBN test wrapper on the .elf file
    # using the provided simulator path.
    sim_test_wrapper = ctx.executable._sim_test_wrapper
    simulator = ctx.executable._simulator
    ctx.actions.write(
        output = ctx.outputs.executable,
        content = "{} {} {} {}".format(sim_test_wrapper.short_path, simulator.short_path, exp_file.short_path, elf.short_path),
    )

    # Runfiles include sources, the .elf file, the simulator and test wrapper
    # themselves, and all the simulator and test wrapper runfiles.
    runfiles = ctx.runfiles(files = (ctx.files.srcs + [elf, exp_file, ctx.executable._simulator, ctx.executable._sim_test_wrapper]))
    runfiles = runfiles.merge(ctx.attr._simulator[DefaultInfo].default_runfiles)
    runfiles = runfiles.merge(ctx.attr._sim_test_wrapper[DefaultInfo].default_runfiles)
    return [
        DefaultInfo(runfiles = runfiles),
        providers[1],
    ]

def _otbn_consttime_test_impl(ctx):
    """This rule checks if a program or subroutine is constant-time.

    There are some limitations to this check; see the Python script's
    documentation for details. In particular, the check may not be able to
    determine that a program runs in constant-time when in fact it does.
    However, if the check passes, the program should always run in constant
    time; that is, the check can produce false negatives but never false
    positives.

    This rule expects one dependency of an otbn_binary or otbn_sim_test type,
    which should provide exactly one `.elf` file.
    """

    # Extract the output .elf file from the output group.
    elf = [f for t in ctx.attr.deps for f in t[OutputGroupInfo].elf.to_list()]
    if len(elf) != 1:
        fail("Expected only one .elf file in dependencies, got: " + str(elf))
    elf = elf[0]

    # Write a very simple script that runs the checker.
    script_content = "{} {} --verbose".format(ctx.executable._checker.short_path, elf.short_path)
    if ctx.attr.subroutine:
        script_content += " --subroutine {}".format(ctx.attr.subroutine)
    if ctx.attr.secrets:
        script_content += " --secrets {}".format(" ".join(ctx.attr.secrets))
    if ctx.attr.initial_constants:
        script_content += " --constants {}".format(" ".join(ctx.attr.initial_constants))
    ctx.actions.write(
        output = ctx.outputs.executable,
        content = script_content,
    )

    # The .elf file must be added to runfiles in order to be visible to the
    # test at runtime. In addition, we need to add all the runfiles from the
    # checker script itself (e.g. the Python runtime and dependencies).
    runfiles = ctx.runfiles(files = [elf])
    runfiles = runfiles.merge(ctx.attr._checker[DefaultInfo].default_runfiles)
    return [DefaultInfo(runfiles = runfiles)]

def _otbn_insn_count_range(ctx):
    """This rule gets min/max possible instruction counts for an OTBN program.
    """

    # Extract the .elf file to check from the dependency list.
    elf = [f for t in ctx.attr.deps for f in t[OutputGroupInfo].elf.to_list()]
    if len(elf) != 1:
        fail("Expected only one .elf file in dependencies, got: " + str(elf))
    elf = elf[0]

    # Command to run the counter script and extract the min/max values.
    out = ctx.actions.declare_file(ctx.attr.name + ".txt")
    ctx.actions.run_shell(
        outputs = [out],
        inputs = [ctx.file._counter, elf],
        command = "{} {} > {}".format(ctx.file._counter.path, elf.path, out.path),
    )

    runfiles = ctx.runfiles(files = ([out]))
    return [DefaultInfo(files = depset([out]), runfiles = runfiles)]

otbn_library = rv_rule(
    implementation = _otbn_library,
    attrs = {
        "srcs": attr.label_list(allow_files = True),
        "_cc_toolchain": attr.label(
            default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
        ),
        "_otbn_as": attr.label(
            default = "//hw/ip/otbn/util:otbn_as",
            executable = True,
            cfg = "exec",
        ),
    },
    fragments = ["cpp"],
    toolchains = ["@rules_cc//cc:toolchain_type"],
    incompatible_use_toolchain_transition = True,
)

otbn_binary = rv_rule(
    implementation = _otbn_binary,
    attrs = {
        "srcs": attr.label_list(allow_files = True),
        "deps": attr.label_list(providers = [DefaultInfo]),
        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
        "_otbn_as": attr.label(
            default = "//hw/ip/otbn/util:otbn_as",
            executable = True,
            cfg = "exec",
        ),
        "_otbn_data": attr.label(
            default = "//hw/ip/otbn/data:all_files",
            allow_files = True,
        ),
        "_wrapper": attr.label(
            default = "//util:otbn_build",
            executable = True,
            cfg = "exec",
        ),
    },
    fragments = ["cpp"],
    toolchains = ["@rules_cc//cc:toolchain_type"],
    incompatible_use_toolchain_transition = True,
)

otbn_sim_test = rv_rule(
    implementation = _otbn_sim_test,
    test = True,
    attrs = {
        "srcs": attr.label_list(allow_files = True),
        "deps": attr.label_list(providers = [DefaultInfo]),
        "exp": attr.label(allow_single_file = True),
        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
        "_otbn_as": attr.label(
            default = "//hw/ip/otbn/util:otbn_as",
            executable = True,
            cfg = "exec",
        ),
        "_otbn_data": attr.label(
            default = "//hw/ip/otbn/data:all_files",
            allow_files = True,
        ),
        "_simulator": attr.label(
            default = "//hw/ip/otbn/dv/otbnsim:standalone",
            executable = True,
            cfg = "exec",
        ),
        "_sim_test_wrapper": attr.label(
            default = "//hw/ip/otbn/util:otbn_sim_test",
            executable = True,
            cfg = "exec",
        ),
        "_wrapper": attr.label(
            default = "//util:otbn_build",
            executable = True,
            cfg = "exec",
        ),
    },
    fragments = ["cpp"],
    toolchains = ["@rules_cc//cc:toolchain_type"],
    incompatible_use_toolchain_transition = True,
)

otbn_consttime_test = rule(
    implementation = _otbn_consttime_test_impl,
    test = True,
    attrs = {
        "srcs": attr.label_list(allow_files = True),
        "deps": attr.label_list(providers = [OutputGroupInfo]),
        "subroutine": attr.string(),
        "secrets": attr.string_list(),
        "initial_constants": attr.string_list(),
        "_checker": attr.label(
            default = "//hw/ip/otbn/util:check_const_time",
            executable = True,
            cfg = "exec",
        ),
    },
)

otbn_insn_count_range = rule(
    implementation = _otbn_insn_count_range,
    attrs = {
        "deps": attr.label_list(providers = [OutputGroupInfo]),
        "_counter": attr.label(
            default = "//hw/ip/otbn/util:get_instruction_count_range.py",
            allow_single_file = True,
        ),
    },
)
