# 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.
"Protocol Buffers"

def _run_pbjs(actions, executable, output_name, proto_files, suffix = ".js", wrap = "amd", amd_name = ""):
    js_file = actions.declare_file(output_name + suffix)

    # Create an intermediate file so that we can do some manipulation of the
    # generated .js output that makes it compatible with our named AMD loading.
    js_tmpl_file = actions.declare_file(output_name + suffix + ".tmpl")

    # Reference of arguments:
    # https://github.com/dcodeIO/ProtoBuf.js/#pbjs-for-javascript
    args = actions.args()
    args.add(["--target", "static-module"])
    args.add(["--wrap", wrap])
    args.add("--strict-long")  # Force usage of Long type with int64 fields
    args.add(["--out", js_file.path + ".tmpl"])
    args.add([f.path for f in proto_files])

    actions.run(
        executable = executable._pbjs,
        inputs = proto_files,
        outputs = [js_tmpl_file],
        arguments = [args],
    )

    actions.expand_template(
        template = js_tmpl_file,
        output = js_file,
        substitutions = {
            # convert anonymous AMD module
            #  define(["protobufjs/minimal"], function($protobuf) {
            # to named
            #  define("wksp/path/to/module", ["protobufjs/minimal"], ...
            "define([": "define('%s/%s', [" % (amd_name, output_name),
        },
    )
    return js_file

def _run_pbts(actions, executable, js_file):
    ts_file = actions.declare_file(js_file.basename[:-len(".closure.js")] + ".d.ts")

    # Reference of arguments:
    # https://github.com/dcodeIO/ProtoBuf.js/#pbts-for-typescript
    args = actions.args()
    args.add(["--out", ts_file.path])
    args.add(js_file.path)

    actions.run(
        executable = executable._pbts,
        progress_message = "Generating typings from %s" % js_file.short_path,
        inputs = [js_file],
        outputs = [ts_file],
        arguments = [args],
    )
    return ts_file

def _ts_proto_library(ctx):
    sources = depset()
    for dep in ctx.attr.deps:
        if not hasattr(dep, "proto"):
            fail("ts_proto_library dep %s must be a proto_library rule" % dep.label)

        # TODO(alexeagle): go/new-proto-library suggests
        # > should not parse .proto files. Instead, they should use the descriptor
        # > set output from proto_library
        # but protobuf.js doesn't seem to accept that bin format
        sources = depset(transitive = [sources, dep.proto.transitive_sources])

    output_name = ctx.attr.output_name or ctx.label.name

    js_es5 = _run_pbjs(
        ctx.actions,
        ctx.executable,
        output_name,
        sources,
        amd_name = "/".join([p for p in [
            ctx.workspace_name,
            ctx.label.package,
        ] if p]),
    )
    js_es6 = _run_pbjs(
        ctx.actions,
        ctx.executable,
        output_name,
        sources,
        suffix = ".closure.js",
        wrap = "es6",
    )
    dts = _run_pbts(ctx.actions, ctx.executable, js_es6)

    # Return a structure that is compatible with the deps[] of a ts_library.
    return struct(
        files = depset([dts]),
        typescript = struct(
            declarations = depset([dts]),
            transitive_declarations = depset([dts]),
            type_blacklisted_declarations = depset(),
            es5_sources = depset([js_es5]),
            es6_sources = depset([js_es6]),
            transitive_es5_sources = depset(),
            transitive_es6_sources = depset([js_es6]),
        ),
    )

ts_proto_library = rule(
    implementation = _ts_proto_library,
    attrs = {
        "deps": attr.label_list(doc = "proto_library targets"),
        "output_name": attr.string(
            doc = """Name of the resulting module, which you will import from.
            If not specified, the name will match the target's name.""",
        ),
        "_pbjs": attr.label(
            default = Label("//internal/protobufjs:pbjs"),
            executable = True,
            cfg = "host",
        ),
        "_pbts": attr.label(
            default = Label("//internal/protobufjs:pbts"),
            executable = True,
            cfg = "host",
        ),
    },
)
"""
Wraps https://github.com/dcodeIO/protobuf.js for use in Bazel.

`ts_proto_library` has identical outputs to `ts_library`, so it can be used anywhere
a `ts_library` can appear, such as in the `deps[]` of another `ts_library`.

Example:

```
load("@build_bazel_rules_typescript//:defs.bzl", "ts_library", "ts_proto_library")

proto_library(
    name = "car_proto",
    srcs = ["car.proto"],
)

ts_proto_library(
    name = "car",
    deps = [":car_proto"],
)

ts_library(
    name = "test_lib",
    testonly = True,
    srcs = ["car.spec.ts"],
    deps = [":car"],
)
```

Note in this example we named the `ts_proto_library` rule `car` so that the
result will be `car.d.ts`. This means our TypeScript code can just
`import {symbols} from './car'`. Use the `output_name` attribute if you want to
name the rule differently from the output file.

The JavaScript produced by protobuf.js has a runtime dependency on a support library.
Under devmode (e.g. `ts_devserver`, `ts_web_test_suite`) you'll need to include these scripts
in the `bootstrap` phase (before Require.js loads). You can use the label
`@build_bazel_rules_typescript//:protobufjs_bootstrap_scripts` to reference these scripts
in the `bootstrap` attribute of `ts_web_test_suite` or `ts_devserver`.

To complete the example above, you could write a `ts_web_test_suite`:

```
load("@build_bazel_rules_typescript//:defs.bzl", "ts_web_test_suite")

ts_web_test_suite(
    name = "test",
    deps = ["test_lib"],
    bootstrap = ["@build_bazel_rules_typescript//:protobufjs_bootstrap_scripts"],
    browsers = [
      "@io_bazel_rules_webtesting//browsers:chromium-local",
      "@io_bazel_rules_webtesting//browsers:firefox-local",
    ],
)
```
"""
