# Copyright 2022 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.
"""Bazel java_binary rule"""

load("@bazel_features//:features.bzl", "bazel_features")
load("@bazel_skylib//lib:paths.bzl", "paths")
load("@rules_cc//cc:find_cc_toolchain.bzl", "use_cc_toolchain")
load("//java/common:java_semantics.bzl", "semantics")
load(
    "//java/common/rules:android_lint.bzl",
    "android_lint_subrule",
)
load("//java/common/rules:java_binary.bzl", "BASIC_JAVA_BINARY_ATTRIBUTES")
load("//java/common/rules:rule_util.bzl", "merge_attrs")
load("//java/common/rules/impl:java_binary_deploy_jar.bzl", "create_deploy_archives")
load("//java/common/rules/impl:java_binary_impl.bzl", "basic_java_binary")
load("//java/common/rules/impl:java_helper.bzl", "helper")
load("//java/private:java_info.bzl", "JavaInfo")

def _bazel_java_binary_impl(ctx):
    return bazel_base_binary_impl(ctx, is_test_rule_class = False) + helper.executable_providers(ctx)

def bazel_base_binary_impl(ctx, is_test_rule_class):
    """Common implementation for binaries and tests

    Args:
        ctx: (RuleContext)
        is_test_rule_class: (bool)

    Returns:
        [Provider]
    """
    deps = _collect_all_targets_as_deps(ctx, classpath_type = "compile_only")
    runtime_deps = _collect_all_targets_as_deps(ctx)

    main_class = _check_and_get_main_class(ctx)
    coverage_main_class = main_class
    coverage_config = helper.get_coverage_config(ctx, _get_coverage_runner(ctx))
    if coverage_config:
        main_class = coverage_config.main_class

    launcher_info = _get_launcher_info(ctx)

    executable = _get_executable(ctx)

    feature_config = helper.get_feature_config(ctx)
    if feature_config:
        strip_as_default = helper.should_strip_as_default(ctx, feature_config)
    else:
        # No C++ toolchain available.
        strip_as_default = False

    providers, default_info, jvm_flags = basic_java_binary(
        ctx,
        deps,
        runtime_deps,
        ctx.files.resources,
        main_class,
        coverage_main_class,
        coverage_config,
        launcher_info,
        executable,
        strip_as_default,
        is_test_rule_class = is_test_rule_class,
    )

    if ctx.attr.use_testrunner:
        _java_runtime_version = semantics.find_java_runtime_toolchain(ctx).version
        if _java_runtime_version >= 17 and _java_runtime_version < 24:
            jvm_flags.append("-Djava.security.manager=allow")
        test_class = ctx.attr.test_class if hasattr(ctx.attr, "test_class") else ""
        if test_class == "":
            test_class = helper.primary_class(ctx)
        if test_class == None:
            fail("cannot determine test class. You might want to rename the " +
                 " rule or add a 'test_class' attribute.")
        jvm_flags.extend([
            "-ea",
            "-Dbazel.test_suite=" + helper.shell_escape(test_class),
        ])

    java_attrs = providers["InternalDeployJarInfo"].java_attrs

    if executable:
        _create_stub(ctx, java_attrs, launcher_info.launcher, executable, jvm_flags, main_class, coverage_main_class)

    runfiles = default_info.runfiles

    if executable:
        runtime_toolchain = semantics.find_java_runtime_toolchain(ctx)
        runfiles = runfiles.merge(ctx.runfiles(transitive_files = runtime_toolchain.files))

    test_support = helper.get_test_support(ctx)
    if test_support:
        runfiles = runfiles.merge(test_support[DefaultInfo].default_runfiles)

    providers["DefaultInfo"] = DefaultInfo(
        files = default_info.files,
        runfiles = runfiles,
        executable = default_info.executable,
    )

    info = providers.pop("InternalDeployJarInfo")
    create_deploy_archives(
        ctx,
        info.java_attrs,
        launcher_info,
        main_class,
        coverage_main_class,
        info.strip_as_default,
        add_exports = info.add_exports,
        add_opens = info.add_opens,
    )

    return providers.values()

def _get_coverage_runner(ctx):
    if ctx.configuration.coverage_enabled and ctx.attr.create_executable:
        toolchain = semantics.find_java_toolchain(ctx)
        runner = toolchain.jacocorunner
        if not runner:
            fail("jacocorunner not set in java_toolchain: %s" % toolchain.label)
        runner_jar = runner.executable

        # wrap the jar in JavaInfo so we can add it to deps for java_common.compile()
        return JavaInfo(output_jar = runner_jar, compile_jar = runner_jar)

    return None

def _collect_all_targets_as_deps(ctx, classpath_type = "all"):
    deps = helper.collect_all_targets_as_deps(ctx, classpath_type = classpath_type)

    if classpath_type == "compile_only" and ctx.fragments.java.enforce_explicit_java_test_deps():
        return deps

    test_support = helper.get_test_support(ctx)
    if test_support:
        deps.append(test_support)
    return deps

def _check_and_get_main_class(ctx):
    create_executable = ctx.attr.create_executable
    main_class = _get_main_class(ctx)

    if not create_executable and main_class:
        fail("main class must not be specified when executable is not created")
    if create_executable and not main_class:
        if not ctx.attr.srcs:
            fail("need at least one of 'main_class' or Java source files")
        main_class = helper.primary_class(ctx)
        if main_class == None:
            fail("main_class was not provided and cannot be inferred: " +
                 "source path doesn't include a known root (java, javatests, src, testsrc)")

    return _get_main_class(ctx)

def _get_main_class(ctx):
    if not ctx.attr.create_executable:
        return None

    main_class = _get_main_class_from_rule(ctx)

    if main_class == "":
        main_class = helper.primary_class(ctx)
    return main_class

def _get_main_class_from_rule(ctx):
    main_class = ctx.attr.main_class
    if main_class:
        return main_class
    if ctx.attr.use_testrunner:
        return "com.google.testing.junit.runner.BazelTestRunner"
    return main_class

def _get_launcher_info(ctx):
    launcher = helper.launcher_artifact_for_target(ctx)
    return struct(
        launcher = launcher,
        unstripped_launcher = launcher,
        runfiles = [],
        runtime_jars = [],
        jvm_flags = [],
        classpath_resources = [],
    )

def _get_executable(ctx):
    if not ctx.attr.create_executable:
        return None
    executable_name = ctx.label.name
    if helper.is_target_platform_windows(ctx):
        executable_name = executable_name + ".exe"

    return ctx.actions.declare_file(executable_name)

_LAUNCHER_MAKER_TOOLCHAIN_TYPE = "@bazel_tools//tools/launcher:launcher_maker_toolchain_type"
_LAUNCHER_MAKER_TOOLCHAIN = config_common.toolchain_type(_LAUNCHER_MAKER_TOOLCHAIN_TYPE, mandatory = True)

def _find_launcher_maker(ctx):
    if bazel_features.rules._has_launcher_maker_toolchain:
        return ctx.toolchains[_LAUNCHER_MAKER_TOOLCHAIN_TYPE].binary
    return ctx.executable._windows_launcher_maker

def _create_stub(ctx, java_attrs, launcher, executable, jvm_flags, main_class, coverage_main_class):
    java_runtime_toolchain = semantics.find_java_runtime_toolchain(ctx)
    java_executable = helper.get_java_executable(ctx, java_runtime_toolchain, launcher)
    workspace_name = ctx.workspace_name
    workspace_prefix = workspace_name + ("/" if workspace_name else "")
    runfiles_enabled = helper.runfiles_enabled(ctx)
    coverage_enabled = ctx.configuration.coverage_enabled

    test_support = helper.get_test_support(ctx)
    test_support_jars = test_support[JavaInfo].transitive_runtime_jars if test_support else depset()
    classpath = depset(
        transitive = [
            java_attrs.runtime_classpath,
            test_support_jars if ctx.fragments.java.enforce_explicit_java_test_deps() else depset(),
        ],
    )

    if helper.is_target_platform_windows(ctx):
        jvm_flags_for_launcher = []
        for flag in jvm_flags:
            jvm_flags_for_launcher.extend(ctx.tokenize(flag))
        return _create_windows_exe_launcher(ctx, java_executable, classpath, main_class, jvm_flags_for_launcher, runfiles_enabled, executable)

    if runfiles_enabled:
        prefix = "" if helper.is_absolute_target_platform_path(ctx, java_executable) else "${JAVA_RUNFILES}/"
        java_bin = "JAVABIN=${JAVABIN:-" + prefix + java_executable + "}"
    else:
        java_bin = "JAVABIN=${JAVABIN:-$(rlocation " + java_executable + ")}"

    td = ctx.actions.template_dict()
    td.add_joined(
        "%classpath%",
        classpath,
        map_each = lambda file: _format_classpath_entry(runfiles_enabled, workspace_prefix, file),
        # At the moment, this condition is always false since the dedicated
        # Windows launcher is used above when targeting Windows.
        join_with = ";" if helper.is_target_platform_windows(ctx) else ":",
        format_joined = "\"%s\"",
        allow_closure = True,
    )

    ctx.actions.expand_template(
        template = ctx.file._stub_template,
        output = executable,
        substitutions = {
            "%runfiles_manifest_only%": "" if runfiles_enabled else "1",
            "%workspace_prefix%": workspace_prefix,
            "%javabin%": java_bin,
            "%needs_runfiles%": "0" if helper.is_absolute_target_platform_path(ctx, java_runtime_toolchain.java_executable_exec_path) else "1",
            "%set_jacoco_metadata%": "",
            "%set_jacoco_main_class%": "export JACOCO_MAIN_CLASS=" + coverage_main_class if coverage_enabled else "",
            "%set_jacoco_java_runfiles_root%": "export JACOCO_JAVA_RUNFILES_ROOT=${JAVA_RUNFILES}/" + workspace_prefix if coverage_enabled else "",
            "%java_start_class%": helper.shell_escape(main_class),
            "%jvm_flags%": " ".join(jvm_flags),
        },
        computed_substitutions = td,
        is_executable = True,
    )
    return executable

def _format_classpath_entry(runfiles_enabled, workspace_prefix, file):
    if runfiles_enabled:
        return "${RUNPATH}" + file.short_path

    return "$(rlocation " + paths.normalize(workspace_prefix + file.short_path) + ")"

def _create_windows_exe_launcher(ctx, java_executable, classpath, main_class, jvm_flags_for_launcher, runfiles_enabled, executable):
    launch_info = ctx.actions.args().use_param_file("%s", use_always = True).set_param_file_format("multiline")
    launch_info.add("binary_type=Java")
    launch_info.add(ctx.workspace_name, format = "workspace_name=%s")
    launch_info.add("1" if runfiles_enabled else "0", format = "symlink_runfiles_enabled=%s")
    launch_info.add(java_executable, format = "java_bin_path=%s")
    launch_info.add(main_class, format = "java_start_class=%s")
    launch_info.add_joined(classpath, map_each = _short_path, join_with = ";", format_joined = "classpath=%s", omit_if_empty = False)
    launch_info.add_joined(jvm_flags_for_launcher, join_with = "\t", format_joined = "jvm_flags=%s", omit_if_empty = False)
    launch_info.add(semantics.find_java_runtime_toolchain(ctx).java_home_runfiles_path, format = "jar_bin_path=%s/bin/jar.exe")

    # TODO(b/295221112): Change to use the "launcher" attribute (only windows use a fixed _launcher attribute)
    launcher_artifact = ctx.executable._launcher
    ctx.actions.run(
        executable = _find_launcher_maker(ctx),
        inputs = [launcher_artifact],
        outputs = [executable],
        arguments = [launcher_artifact.path, launch_info, executable.path],
        use_default_shell_env = True,
        toolchain = _LAUNCHER_MAKER_TOOLCHAIN_TYPE if bazel_features.rules._has_launcher_maker_toolchain else None,
        mnemonic = "JavaLauncherMaker",
    )
    return executable

def _short_path(file):
    return file.short_path

def _compute_test_support(use_testrunner):
    return Label(semantics.JAVA_TEST_RUNNER_LABEL) if use_testrunner else None

def make_binary_rule(implementation, *, doc, attrs, executable = False, test = False, initializer = None):
    return rule(
        implementation = implementation,
        initializer = initializer,
        doc = doc,
        attrs = attrs,
        executable = executable,
        test = test,
        fragments = ["cpp", "java"],
        provides = [JavaInfo],
        toolchains = [semantics.JAVA_TOOLCHAIN] + use_cc_toolchain(mandatory = False) + (
            [semantics.JAVA_RUNTIME_TOOLCHAIN] if executable or test else []
        ) + (
            [_LAUNCHER_MAKER_TOOLCHAIN] if bazel_features.rules._has_launcher_maker_toolchain else []
        ),
        # TODO(hvd): replace with filegroups?
        outputs = {
            "classjar": "%{name}.jar",
            "sourcejar": "%{name}-src.jar",
            "deploysrcjar": "%{name}_deploy-src.jar",
            "deployjar": "%{name}_deploy.jar",
            "unstrippeddeployjar": "%{name}_deploy.jar.unstripped",
        },
        exec_groups = {
            "cpp_link": exec_group(toolchains = use_cc_toolchain(mandatory = False)),
        },
        subrules = [android_lint_subrule],
    )

BASE_BINARY_ATTRS = merge_attrs(
    BASIC_JAVA_BINARY_ATTRIBUTES,
    {
        "resource_strip_prefix": attr.string(
            doc = """
The path prefix to strip from Java resources.
<p>
If specified, this path prefix is stripped from every file in the <code>resources</code>
attribute. It is an error for a resource file not to be under this directory. If not
specified (the default), the path of resource file is determined according to the same
logic as the Java package of source files. For example, a source file at
<code>stuff/java/foo/bar/a.txt</code> will be located at <code>foo/bar/a.txt</code>.
</p>
            """,
        ),
        "_test_support": attr.label(default = _compute_test_support),
        "_launcher": attr.label(
            cfg = "target",
            executable = True,
            default = "@bazel_tools//tools/launcher:launcher",
        ),
    },
    {
        "_windows_launcher_maker": attr.label(
            default = "@bazel_tools//tools/launcher:launcher_maker",
            cfg = "exec",
            executable = True,
        ),
    } if not bazel_features.rules._has_launcher_maker_toolchain else {},
)

def make_java_binary(executable):
    return make_binary_rule(
        _bazel_java_binary_impl,
        doc = """
<p>
  Builds a Java archive ("jar file"), plus a wrapper shell script with the same name as the rule.
  The wrapper shell script uses a classpath that includes, among other things, a jar file for each
  library on which the binary depends. When running the wrapper shell script, any nonempty
  <code>JAVABIN</code> environment variable will take precedence over the version specified via
  Bazel's <code>--java_runtime_version</code> flag.
</p>
<p>
  The wrapper script accepts several unique flags. Refer to
  <code>java_stub_template.txt</code>
  for a list of configurable flags and environment variables accepted by the wrapper.
</p>

<h4 id="java_binary_implicit_outputs">Implicit output targets</h4>
<ul>
  <li><code><var>name</var>.jar</code>: A Java archive, containing the class files and other
    resources corresponding to the binary's direct dependencies.</li>
  <li><code><var>name</var>-src.jar</code>: An archive containing the sources ("source
    jar").</li>
  <li><code><var>name</var>_deploy.jar</code>: A Java archive suitable for deployment (only
    built if explicitly requested).
    <p>
      Building the <code>&lt;<var>name</var>&gt;_deploy.jar</code> target for your rule
      creates a self-contained jar file with a manifest that allows it to be run with the
      <code>java -jar</code> command or with the wrapper script's <code>--singlejar</code>
      option. Using the wrapper script is preferred to <code>java -jar</code> because it
      also passes the <a href="#java_binary-jvm_flags">JVM flags</a> and the options
      to load native libraries.
    </p>
    <p>
      The deploy jar contains all the classes that would be found by a classloader that
      searched the classpath from the binary's wrapper script from beginning to end. It also
      contains the native libraries needed for dependencies. These are automatically loaded
      into the JVM at runtime.
    </p>
    <p>If your target specifies a <a href="#java_binary.launcher">launcher</a>
      attribute, then instead of being a normal JAR file, the _deploy.jar will be a
      native binary. This will contain the launcher plus any native (C++) dependencies of
      your rule, all linked into a static binary. The actual jar file's bytes will be
      appended to that native binary, creating a single binary blob containing both the
      executable and the Java code. You can execute the resulting jar file directly
      like you would execute any native binary.</p>
  </li>
  <li><code><var>name</var>_deploy-src.jar</code>: An archive containing the sources
    collected from the transitive closure of the target. These will match the classes in the
    <code>deploy.jar</code> except where jars have no matching source jar.</li>
</ul>

<p>
It is good practice to use the name of the source file that is the main entry point of the
application (minus the extension). For example, if your entry point is called
<code>Main.java</code>, then your name could be <code>Main</code>.
</p>

<p>
  A <code>deps</code> attribute is not allowed in a <code>java_binary</code> rule without
  <a href="#java_binary-srcs"><code>srcs</code></a>; such a rule requires a
  <a href="#java_binary-main_class"><code>main_class</code></a> provided by
  <a href="#java_binary-runtime_deps"><code>runtime_deps</code></a>.
</p>

<p>The following code snippet illustrates a common mistake:</p>

<pre class="code">
<code class="lang-starlark">
java_binary(
    name = "DontDoThis",
    srcs = [
        <var>...</var>,
        <code class="deprecated">"GeneratedJavaFile.java"</code>,  # a generated .java file
    ],
    deps = [<code class="deprecated">":generating_rule",</code>],  # rule that generates that file
)
</code>
</pre>

<p>Do this instead:</p>

<pre class="code">
<code class="lang-starlark">
java_binary(
    name = "DoThisInstead",
    srcs = [
        <var>...</var>,
        ":generating_rule",
    ],
)
</code>
</pre>
        """,
        attrs = merge_attrs(
            BASE_BINARY_ATTRS,
            ({} if executable else {
                "args": attr.string_list(),
                "output_licenses": attr.string_list(),
            }),
        ),
        executable = executable,
    )

java_binary = make_java_binary(executable = True)
