# Copyright 2018 The Bazel Authors. All rights reserved.
#
# 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.

"""Toolchain for compiling rust stubs from protobuf and gRPC."""

# buildifier: disable=bzl-visibility
load("//rust/private:utils.bzl", "name_to_crate_name")

def generated_file_stem(file_path):
    """Returns the basename of a file without any extensions.

    Example:
    ```python
    content.append("pub mod %s;" % _generated_file_stem(f))
    ```

    Args:
        file_path (string): A path to a file

    Returns:
        string: The file stem of the filename
    """
    basename = file_path.rsplit("/", 2)[-1]
    basename = name_to_crate_name(basename)
    return basename.rsplit(".", 2)[0]

def rust_generate_proto(
        ctx,
        transitive_descriptor_sets,
        protos,
        imports,
        output_dir,
        proto_toolchain,
        is_grpc = False):
    """Generate a proto compilation action.

    Args:
        ctx (ctx): rule context.
        transitive_descriptor_sets (depset): descriptor generated by previous protobuf libraries.
        protos (list): list of paths of protos to compile.
        imports (depset): directory, relative to the package, to output the list of stubs.
        output_dir (str): The basename of the output directory for for the output generated stubs
        proto_toolchain (ToolchainInfo): The toolchain for rust-proto compilation. See `rust_proto_toolchain`
        is_grpc (bool, optional): generate gRPC stubs. Defaults to False.

    Returns:
        list: the list of generate stubs (File)
    """

    tools = [
        proto_toolchain.protoc,
        proto_toolchain.proto_plugin,
    ]
    executable = proto_toolchain.protoc
    args = ctx.actions.args()

    if not protos:
        fail("Protobuf compilation requested without inputs!")
    paths = ["%s/%s" % (output_dir, generated_file_stem(i)) for i in protos.to_list()]
    outs = [ctx.actions.declare_file(path + ".rs") for path in paths]
    output_directory = outs[0].dirname

    if is_grpc:
        # Add grpc stubs to the list of outputs
        grpc_files = [ctx.actions.declare_file(path + "_grpc.rs") for path in paths]
        outs.extend(grpc_files)

        # gRPC stubs is generated only if a service is defined in the proto,
        # so we create an empty grpc module in the other case.
        tools.append(proto_toolchain.grpc_plugin)
        tools.append(ctx.executable._optional_output_wrapper)
        args.add_all([f.path for f in grpc_files])
        args.add_all([
            "--",
            proto_toolchain.protoc.path,
            "--plugin=protoc-gen-grpc-rust=" + proto_toolchain.grpc_plugin.path,
            "--grpc-rust_out=" + output_directory,
        ])
        executable = ctx.executable._optional_output_wrapper

    args.add_all([
        "--plugin=protoc-gen-rust=" + proto_toolchain.proto_plugin.path,
        "--rust_out=" + output_directory,
    ])

    args.add_joined(
        transitive_descriptor_sets,
        join_with = ":",
        format_joined = "--descriptor_set_in=%s",
    )

    args.add_all(protos)
    ctx.actions.run(
        inputs = depset(
            transitive = [
                transitive_descriptor_sets,
                imports,
            ],
        ),
        outputs = outs,
        tools = tools,
        progress_message = "Generating Rust protobuf stubs",
        mnemonic = "RustProtocGen",
        executable = executable,
        arguments = [args],
    )
    return outs

def _rust_proto_toolchain_impl(ctx):
    return platform_common.ToolchainInfo(
        edition = ctx.attr.edition,
        grpc_compile_deps = ctx.attr.grpc_compile_deps,
        grpc_plugin = ctx.file.grpc_plugin,
        proto_compile_deps = ctx.attr.proto_compile_deps,
        proto_plugin = ctx.file.proto_plugin,
        protoc = ctx.executable.protoc,
    )

# Default dependencies needed to compile protobuf stubs.
PROTO_COMPILE_DEPS = [
    Label("//proto/raze:protobuf"),
]

# Default dependencies needed to compile gRPC stubs.
GRPC_COMPILE_DEPS = PROTO_COMPILE_DEPS + [
    Label("//proto/raze:grpc"),
    Label("//proto/raze:tls_api"),
    Label("//proto/raze:tls_api_stub"),
]

rust_proto_toolchain = rule(
    implementation = _rust_proto_toolchain_impl,
    attrs = {
        "edition": attr.string(
            doc = "The edition used by the generated rust source.",
        ),
        "grpc_compile_deps": attr.label_list(
            doc = "The crates the generated grpc libraries depends on.",
            cfg = "target",
            default = GRPC_COMPILE_DEPS,
        ),
        "grpc_plugin": attr.label(
            doc = "The location of the Rust protobuf compiler plugin to generate rust gRPC stubs.",
            allow_single_file = True,
            cfg = "exec",
            default = Label("//proto:protoc_gen_rust_grpc"),
        ),
        "proto_compile_deps": attr.label_list(
            doc = "The crates the generated protobuf libraries depends on.",
            cfg = "target",
            default = PROTO_COMPILE_DEPS,
        ),
        "proto_plugin": attr.label(
            doc = "The location of the Rust protobuf compiler plugin used to generate rust sources.",
            allow_single_file = True,
            cfg = "exec",
            default = Label("//proto:protoc_gen_rust"),
        ),
        "protoc": attr.label(
            doc = "The location of the `protoc` binary. It should be an executable target.",
            executable = True,
            cfg = "exec",
            default = Label("@com_google_protobuf//:protoc"),
        ),
    },
    doc = """\
Declares a Rust Proto toolchain for use.

This is used to configure proto compilation and can be used to set different \
protobuf compiler plugin.

Example:

Suppose a new nicer gRPC plugin has came out. The new plugin can be \
used in Bazel by defining a new toolchain definition and declaration:

```python
load('@rules_rust//proto:toolchain.bzl', 'rust_proto_toolchain')

rust_proto_toolchain(
   name="rust_proto_impl",
   grpc_plugin="@rust_grpc//:grpc_plugin",
   grpc_compile_deps=["@rust_grpc//:grpc_deps"],
)

toolchain(
    name="rust_proto",
    exec_compatible_with = [
        "@platforms//cpu:cpuX",
    ],
    target_compatible_with = [
        "@platforms//cpu:cpuX",
    ],
    toolchain = ":rust_proto_impl",
)
```

Then, either add the label of the toolchain rule to register_toolchains in the WORKSPACE, or pass \
it to the `--extra_toolchains` flag for Bazel, and it will be used.

See @rules_rust//proto:BUILD for examples of defining the toolchain.
""",
)
