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

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

"""Rust generation rules for `ujson`."""

def _ujson_rust(ctx):
    cc_toolchain = find_cc_toolchain(ctx).cc
    module = ctx.actions.declare_file("{}.rs".format(ctx.label.name))
    ujson_lib = ctx.attr.ujson_lib[CcInfo].compilation_context.headers.to_list()

    # Get the include search path for ujson.
    ujson_lib_root = ctx.attr.ujson_lib[CcInfo].compilation_context.quote_includes.to_list()

    srcs = []
    includes = []
    for src in ctx.attr.srcs:
        srcs.extend(src[CcInfo].compilation_context.direct_public_headers)
        includes.extend(src[CcInfo].compilation_context.headers.to_list())

    # TODO(cfrantz): Is there a better way to find the `rustfmt` binary?
    rustfmt_files = ctx.attr._rustfmt.data_runfiles.files.to_list()
    rustfmt = [f for f in rustfmt_files if f.basename == "rustfmt"][0]

    defines = ["-D{}".format(d) for d in ctx.attr.defines]

    # The pipeline for generating rust code from a ujson header file:
    # 1. Preprocess the file with RUST_PREPROCESSOR_EMIT
    # 2. Grep out all the preprocessor noise (which starts with `#`).
    # 3. Substitute all `rust_attr` for `#`, thus creating rust attributes.
    # 4. Format it with `rustfmt` so it looks nice and can be inspected.
    command = """
        {preprocessor} -nostdinc -I{ujson_lib_root_includes} \
        -DRUST_PREPROCESSOR_EMIT=1 -DNOSTDINC=1 {defines} $@ \
        | grep -v '#' \
        | sed -e "s/rust_attr/#/g" \
        | {rustfmt} > {module}""".format(
        preprocessor = cc_toolchain.preprocessor_executable,
        defines = " ".join(defines),
        module = module.path,
        rustfmt = rustfmt.path,
        ujson_lib_root_includes = " -I".join(ujson_lib_root),
    )

    ctx.actions.run_shell(
        outputs = [module],
        inputs = ujson_lib + srcs + includes,
        tools = cc_toolchain.all_files.to_list() + rustfmt_files,
        arguments = [src.path for src in srcs],
        command = command,
    )
    return [
        DefaultInfo(files = depset([module]), runfiles = ctx.runfiles([module])),
    ]

ujson_rust = rule(
    implementation = _ujson_rust,
    attrs = {
        "srcs": attr.label_list(
            providers = [CcInfo],
            doc = "ujson cc_library targets to generate Rust for",
        ),
        "defines": attr.string_list(
            doc = "C preprocessor defines",
        ),
        "ujson_lib": attr.label(
            default = "//sw/device/lib/ujson",
            doc = "Location of the ujson library",
            providers = [CcInfo],
        ),
        "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")),
        "_rustfmt": attr.label(
            default = "@rules_rust//rust/toolchain:current_rustfmt_files",
            cfg = "exec",
        ),
    },
    toolchains = ["@rules_cc//cc:toolchain_type"],
)
