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

""" Definition of java_single_jar. """

def _check_non_empty(value, name):
    if not value:
        fail("%s must be non-empty" % name)

def _java_single_jar(ctx):
    _check_non_empty(ctx.attr.root_packages, "root_packages")

    inputs = depset()
    if ctx.attr.source_jar:
        inputs = depset(transitive = [dep[JavaInfo].transitive_source_jars for dep in ctx.attr.deps])
    else:
        inputs = depset(transitive = [dep[JavaInfo].transitive_runtime_deps for dep in ctx.attr.deps])

    args = ctx.actions.args()
    args.add_all("--sources", inputs)
    args.use_param_file(
        "@%s",
        use_always = True,
    )
    args.set_param_file_format("multiline")
    args.add("--output", ctx.outputs.jar)
    args.add("--normalize")

    resource_files = depset(
        transitive = [resource.files for resource in ctx.attr.resources],
    ).to_list()
    args.add("--resources")
    for resource_file in resource_files:
        if not resource_file.path.startswith("src/main/resources"):
            fail("resource %s must be stored in src/main/resources/" % resource_file.path)
        relative_path = resource_file.path.replace("src/main/resources/", "")

        # Map src/main/resources/a/b/c.txt to a/b/c.txt.
        args.add(resource_file.path, format = "%s:" + relative_path)

    # Maybe compress code.
    if not ctx.attr.source_jar:
        # Deal with limitation of singlejar flags: tool's default behavior is
        # "no", but you get that behavior only by absence of compression flags.
        if ctx.attr.compress == "preserve":
            args.add("--dont_change_compression")
        elif ctx.attr.compress == "yes":
            args.add("--compression")
        elif ctx.attr.compress == "no":
            pass
        else:
            fail("\"compress\" attribute (%s) must be: yes, no, preserve." % ctx.attr.compress)

    # Each package prefix has to be specified in its own --include_prefixes arg.
    for p in ctx.attr.root_packages:
        args.add("--include_prefixes", p.replace(".", "/"))

    ctx.actions.run(
        inputs = inputs.to_list() + resource_files,
        outputs = [ctx.outputs.jar],
        arguments = [args],
        progress_message = "Merging into %s" % ctx.outputs.jar.short_path,
        mnemonic = "JavaSingleJar",
        executable = ctx.executable._singlejar,
    )

java_single_jar = rule(
    attrs = {
        "deps": attr.label_list(providers = [JavaInfo]),
        "resources": attr.label_list(
            providers = [JavaInfo],
            allow_files = True,
        ),
        "_singlejar": attr.label(
            default = Label("@bazel_tools//tools/jdk:singlejar"),
            cfg = "host",
            allow_single_file = True,
            executable = True,
        ),
        "source_jar": attr.bool(default = False),
        "compress": attr.string(default = "preserve"),
        "root_packages": attr.string_list(),
    },
    outputs = {
        "jar": "%{name}.jar",
    },
    implementation = _java_single_jar,
    doc = """
Collects Java dependencies and jar files into a single jar

Args:
  deps: The Java targets (including java_import and java_library) to collect
      transitive dependencies from. Both compile-time dependencies (deps,
      exports) and runtime dependencies (runtime_deps) are collected.
      Resources are also collected. Native cc_library or java_wrap_cc
      dependencies are not.
  resources: A combination of resource files. Files must be stored in
      src/main/resources. Mapping rules: src/main/resources/a/b/c.txt will be
      copied to a/b/c.txt in the output jar.
  compress: Whether to always deflate ("yes"), always store ("no"), or pass
      through unmodified ("preserve"). The default is "preserve", and is the
      most efficient option -- no extra work is done to inflate or deflate.
  source_jar: Whether to combine only the source jars of input to create a single
      output source jar. The compiled code jars of input will be ignored.
  root_packages: Java packages to include in generated jar.

Outputs:
  {name}.jar: A single jar containing all of the input.
""",
)
