# Copyright (C) 2019 The Android Open Source Project
#
# 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.

# This file defines the proto_gen() rule that is used for generating protos
# with custom plugins (ipc and protozero).

def _proto_gen_impl(ctx):
    proto_src = [
        f
        for dep in ctx.attr.deps
        for f in dep[ProtoInfo].direct_sources
    ]
    includes = [
        f
        for dep in ctx.attr.deps
        for f in dep[ProtoInfo].transitive_imports.to_list()
    ]

    proto_path = "."

    out_dir = str(ctx.genfiles_dir.path)
    strip_base_path = ""
    if ctx.attr.root != "//":
        # This path is hit in Google internal builds, where root is typically
        # //third_party/perfetto.
        proto_path = "."

        # The below will likely be //third_party/perfetto/ but may also be any
        # subdir under //third_party/perfetto.
        last_slash_idx = ctx.build_file_path.rfind("/")
        strip_base_path = ctx.build_file_path[:last_slash_idx + 1]
    elif ctx.label.workspace_root:
        # This path is hit when proto targets are built as @perfetto//:xxx
        # instead of //:xxx. This happens in embedder builds. In this case,
        # workspace_root == "external/perfetto" and we need to rebase the paths
        # passed to protoc.
        proto_path = ctx.label.workspace_root
        out_dir += "/" + ctx.label.workspace_root
        strip_base_path = ctx.label.workspace_root + "/"

    out_files = []
    suffix = ctx.attr.suffix
    for src in proto_src:
        base_path = src.path[:-len(".proto")]
        if base_path.startswith(strip_base_path):
            base_path = base_path[len(strip_base_path):]
        out_files += [ctx.actions.declare_file(base_path + ".%s.h" % suffix)]
        out_files += [ctx.actions.declare_file(base_path + ".%s.cc" % suffix)]

    arguments = [
        "--proto_path=" + proto_path,
    ]
    plugin_deps = []
    if ctx.attr.plugin:
        wrap_arg = ctx.attr.wrapper_namespace
        arguments += [
            "--plugin=protoc-gen-plugin=" + ctx.executable.plugin.path,
            "--plugin_out=wrapper_namespace=" + wrap_arg + ":" + out_dir,
        ]
        plugin_deps += [ctx.executable.plugin]
    else:
        arguments += [
            "--cpp_out=lite=true:" + out_dir,
        ]

    arguments += [src.path for src in proto_src]
    ctx.actions.run(
        inputs = proto_src + includes + plugin_deps,
        tools = plugin_deps,
        outputs = out_files,
        executable = ctx.executable.protoc,
        arguments = arguments,
    )
    cc_files = depset([f for f in out_files if f.path.endswith(".cc")])
    h_files = depset([f for f in out_files if f.path.endswith(".h")])
    return [
        DefaultInfo(files = cc_files),
        OutputGroupInfo(
            cc = cc_files,
            h = h_files,
        ),
    ]


proto_gen = rule(
    attrs = {
        "deps": attr.label_list(
            mandatory = True,
            allow_empty = False,
            providers = [ProtoInfo],
        ),
        "plugin": attr.label(
            executable = True,
            mandatory = False,
            cfg = "host",
        ),
        "wrapper_namespace": attr.string(
            mandatory = False,
            default = ""
        ),
        "suffix": attr.string(
            mandatory = True,
        ),
        "protoc": attr.label(
            executable = True,
            cfg = "host",
        ),
        "root": attr.string(
            mandatory = False,
            default = "//",
        ),
    },
    output_to_genfiles = True,
    implementation = _proto_gen_impl,
)


def _proto_descriptor_gen_impl(ctx):
    descriptors = [
        f
        for dep in ctx.attr.deps
        for f in dep[ProtoInfo].transitive_descriptor_sets.to_list()
    ]
    ctx.actions.run_shell(
        inputs=descriptors,
        outputs=ctx.outputs.outs,
        command='cat %s > %s' % (
            ' '.join([f.path for f in descriptors]), ctx.outputs.outs[0].path)
    )


proto_descriptor_gen = rule(
    implementation=_proto_descriptor_gen_impl,
    attrs = {
        "deps": attr.label_list(
            mandatory = True,
            allow_empty = False,
            providers = [ProtoInfo],
        ),
        "outs": attr.output_list(mandatory=True),
    }
)
