# 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_all(["--target", "static-module"])
    args.add_all(["--wrap", wrap])
    args.add("--strict-long")  # Force usage of Long type with int64 fields
    args.add_all(["--out", js_file.path + ".tmpl"])
    args.add_all(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_all(["--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 = {
        "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.""",
        ),
        "deps": attr.label_list(doc = "proto_library targets"),
        "_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",
    ],
)
```
"""
