# Copyright 2017 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.

load(
    "@bazel_skylib//lib:paths.bzl",
    "paths",
)
load(
    "//go:def.bzl",
    "GoLibrary",
    "go_context",
)
load(
    "//go/private:go_toolchain.bzl",
    "GO_TOOLCHAIN",
)
load(
    "//go/private/rules:transition.bzl",
    "go_reset_target",
)

GoProtoCompiler = provider(
    doc = "Information and dependencies needed to generate Go code from protos",
    fields = {
        "compile": """A function with the signature:

    def compile(go, compiler, protos, imports, importpath)

where go is the go_context object, compiler is this GoProtoCompiler, protos
is a list of ProtoInfo providers for protos to compile, imports is a depset
of strings mapping proto import paths to Go import paths, and importpath is
the import path of the Go library being generated.

The function should declare output .go files and actions to generate them.
It should return a list of .go Files to be compiled by the Go compiler.
""",
        "deps": """List of targets providing GoLibrary, GoSource, and GoArchive.
These are added as implicit dependencies for any go_proto_library using this
compiler. Typically, these are Well Known Types and proto runtime libraries.""",
        "valid_archive": """A Boolean indicating whether the .go files produced
by this compiler are buildable on their own. Compilers that just add methods
to structs produced by other compilers will set this to False.""",
        "internal": "Opaque value containing data used by compile.",
    },
)

def go_proto_compile(go, compiler, protos, imports, importpath):
    """Invokes protoc to generate Go sources for a given set of protos

    Args:
        go: the go object, returned by go_context.
        compiler: a GoProtoCompiler provider.
        protos: list of ProtoInfo providers for protos to compile.
        imports: depset of strings mapping proto import paths to Go import paths.
        importpath: the import path of the Go library being generated.

    Returns:
        A list of .go Files generated by the compiler.
    """

    go_srcs = []
    outpath = None
    proto_paths = {}
    desc_sets = []
    for proto in protos:
        desc_sets.append(proto.transitive_descriptor_sets)
        for src in proto.check_deps_sources.to_list():
            path = proto_path(src, proto)
            if path in proto_paths:
                if proto_paths[path] != src:
                    fail("proto files {} and {} have the same import path, {}".format(
                        src.path,
                        proto_paths[path].path,
                        path,
                    ))
                continue
            proto_paths[path] = src

            out = go.declare_file(
                go,
                path = importpath + "/" + src.basename[:-len(".proto")],
                ext = compiler.internal.suffix,
            )
            go_srcs.append(out)
            if outpath == None:
                outpath = out.dirname[:-len(importpath)]

    transitive_descriptor_sets = depset(direct = [], transitive = desc_sets)

    args = go.actions.args()
    args.add("-protoc", compiler.internal.protoc)
    args.add("-importpath", importpath)
    args.add("-out_path", outpath)
    args.add("-plugin", compiler.internal.plugin)

    # TODO(jayconrod): can we just use go.env instead?
    args.add_all(compiler.internal.options, before_each = "-option")
    if compiler.internal.import_path_option:
        args.add_all([importpath], before_each = "-option", format_each = "import_path=%s")
    args.add_all(transitive_descriptor_sets, before_each = "-descriptor_set")
    args.add_all(go_srcs, before_each = "-expected")
    args.add_all(imports, before_each = "-import")
    args.add_all(proto_paths.keys())
    args.use_param_file("-param=%s")
    go.actions.run(
        inputs = depset(
            direct = [
                compiler.internal.go_protoc,
                compiler.internal.protoc,
                compiler.internal.plugin,
            ],
            transitive = [transitive_descriptor_sets],
        ),
        outputs = go_srcs,
        progress_message = "Generating into %s" % go_srcs[0].dirname,
        mnemonic = "GoProtocGen",
        executable = compiler.internal.go_protoc,
        arguments = [args],
        env = go.env,
        # We may need the shell environment (potentially augmented with --action_env)
        # to invoke protoc on Windows. If protoc was built with mingw, it probably needs
        # .dll files in non-default locations that must be in PATH. The target configuration
        # may not have a C compiler, so we have no idea what PATH should be.
        use_default_shell_env = "PATH" not in go.env,
    )
    return go_srcs

def proto_path(src, proto):
    """proto_path returns the string used to import the proto. This is the proto
    source path within its repository, adjusted by import_prefix and
    strip_import_prefix.

    Args:
        src: the proto source File.
        proto: the ProtoInfo provider.

    Returns:
        An import path string.
    """
    if proto.proto_source_root == ".":
        # true if proto sources were generated
        prefix = src.root.path + "/"
    elif proto.proto_source_root.startswith(src.root.path):
        # sometimes true when import paths are adjusted with import_prefix
        prefix = proto.proto_source_root + "/"
    else:
        # usually true when paths are not adjusted
        prefix = paths.join(src.root.path, proto.proto_source_root) + "/"
    if not src.path.startswith(prefix):
        # sometimes true when importing multiple adjusted protos
        return src.path
    return src.path[len(prefix):]

def _go_proto_compiler_impl(ctx):
    go = go_context(ctx)
    library = go.new_library(go)
    source = go.library_to_source(go, ctx.attr, library, ctx.coverage_instrumented())
    return [
        GoProtoCompiler(
            deps = ctx.attr.deps,
            compile = go_proto_compile,
            valid_archive = ctx.attr.valid_archive,
            internal = struct(
                options = ctx.attr.options,
                suffix = ctx.attr.suffix,
                protoc = ctx.executable._protoc,
                go_protoc = ctx.executable._go_protoc,
                plugin = ctx.executable.plugin,
                import_path_option = ctx.attr.import_path_option,
            ),
        ),
        library,
        source,
    ]

_go_proto_compiler = rule(
    implementation = _go_proto_compiler_impl,
    attrs = {
        "deps": attr.label_list(providers = [GoLibrary]),
        "options": attr.string_list(),
        "suffix": attr.string(default = ".pb.go"),
        "valid_archive": attr.bool(default = True),
        "import_path_option": attr.bool(default = False),
        "plugin": attr.label(
            executable = True,
            cfg = "exec",
            mandatory = True,
        ),
        "_go_protoc": attr.label(
            executable = True,
            cfg = "exec",
            default = "//go/tools/builders:go-protoc",
        ),
        "_protoc": attr.label(
            executable = True,
            cfg = "exec",
            default = "//proto:protoc",
        ),
        "_go_context_data": attr.label(
            default = "//:go_context_data",
        ),
    },
    toolchains = [GO_TOOLCHAIN],
)

def go_proto_compiler(name, **kwargs):
    plugin = kwargs.pop("plugin", "@com_github_golang_protobuf//protoc-gen-go")
    reset_plugin_name = name + "_reset_plugin_"
    go_reset_target(
        name = reset_plugin_name,
        dep = plugin,
        visibility = ["//visibility:private"],
    )
    _go_proto_compiler(
        name = name,
        plugin = reset_plugin_name,
        **kwargs
    )
