# Copyright 2026 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.
"""Definition of  the java_single_jar rule."""

load("//java/common:java_common.bzl", "java_common")
load("//java/common:java_info.bzl", "JavaInfo")

# copybara: default visibility

def _single_jar_inputs(deps, deploy_env):
    transitive_inputs = []
    for dep in deps:
        if JavaInfo in dep:
            info = dep[JavaInfo]
            transitive_inputs.append(info.transitive_runtime_jars)
            if hasattr(info, "compilation_info"):
                compilation_info = info.compilation_info
                if hasattr(compilation_info, "runtime_classpath"):
                    transitive_inputs.append(compilation_info.runtime_classpath)
        else:
            files = []
            for f in dep[DefaultInfo].files.to_list():
                if not f.extension == "jar":
                    fail("unexpected file type in java_single_jar.deps: %s" % f.path)
                files.append(f)
            transitive_inputs.append(depset(files))
    inputs = depset(transitive = transitive_inputs)

    if hasattr(java_common, "JavaRuntimeClasspathInfo"):
        deploy_env_jars = depset(transitive = [
            dep[java_common.JavaRuntimeClasspathInfo].runtime_classpath
            for dep in deploy_env
        ])
        excluded_jars = {jar: None for jar in deploy_env_jars.to_list()}
        if excluded_jars:
            inputs = depset([jar for jar in inputs.to_list() if jar not in excluded_jars])
    return inputs

def _bazel_java_single_jar_impl(ctx):
    inputs = _single_jar_inputs(ctx.attr.deps, ctx.attr.deploy_env)

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

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

    if ctx.attr.exclude_build_data:
        args.add("--exclude_build_data")
    if ctx.attr.multi_release:
        args.add("--multi_release")

    if ctx.attr.exclude_pattern:
        args.add("--exclude_pattern", ctx.attr.exclude_pattern)

    ctx.actions.run(
        inputs = inputs,
        outputs = [ctx.outputs.output],
        arguments = [args],
        progress_message = "Merging into %s" % ctx.outputs.output.short_path,
        mnemonic = "JavaSingleJar",
        executable = ctx.executable._singlejar,
        use_default_shell_env = True,
    )

    files = depset([ctx.outputs.output])
    providers = [DefaultInfo(
        files = files,
        runfiles = ctx.runfiles(transitive_files = files),
    )]
    if hasattr(java_common, "JavaRuntimeClasspathInfo"):
        providers.append(java_common.JavaRuntimeClasspathInfo(runtime_classpath = inputs))
    return providers

bazel_java_single_jar = rule(
    attrs = {
        "deps": attr.label_list(
            allow_files = True,
            doc = """
                The Java targets (including java_import and java_library) to collect
                transitive dependencies from. Runtime dependencies are collected via
                deps, exports, and runtime_deps. Resources are also collected.
                Native cc_library or java_wrap_cc dependencies are not.""",
        ),
        "deploy_manifest_lines": attr.string_list(doc = """
          A list of lines to add to the <code>META-INF/manifest.mf</code> file."""),
        "deploy_env": attr.label_list(
            providers = [java_common.JavaRuntimeClasspathInfo] if hasattr(java_common, "JavaRuntimeClasspathInfo") else [],
            allow_files = False,
            doc = """
            A list of `java_binary` or `java_single_jar` targets which represent
            the deployment environment for this binary.

            Set this attribute when building a plugin which will be loaded by another
            `java_binary`.

            `deploy_env` dependencies are excluded from the jar built by this rule.""",
        ),
        "compress": attr.string(default = "preserve", doc = """
            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."""),
        "exclude_build_data": attr.bool(default = True, doc = """
            Whether to omit the build-data.properties file generated
            by default."""),
        "multi_release": attr.bool(default = True, doc = """Whether to enable Multi-Release output jars."""),
        "exclude_pattern": attr.string(default = "", doc = """
            A regex pattern of files to exclude from the jar.
        """),
        "_singlejar": attr.label(
            default = Label("//toolchains:singlejar"),
            cfg = "exec",
            allow_single_file = True,
            executable = True,
        ),
        "output": attr.output(),
    },
    implementation = _bazel_java_single_jar_impl,
    doc = """
Collects Java dependencies and jar files into a single jar

`java_single_jar` collects Java dependencies and jar files into a single jar.
This is similar to java_binary with everything related to executables disabled,
and provides an alternative to the java_binary "deploy jar hack".

## Example

```skylark
load("//tools/build_defs/java_single_jar:java_single_jar.bzl", "java_single_jar")

java_single_jar(
    name = "my_single_jar",
    deps = [
        "//java/com/google/foo",
        "//java/com/google/bar",
    ],
)
```

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