# 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", "binary_provider_helper")
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) + binary_provider_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_classes = helper.test_classes(ctx)
        if not test_classes:
            fail("cannot determine test class. You might want to add a " +
                 "'test_class' or 'test_classes' attribute.")
        jvm_flags.extend([
            "-ea",
            "-D{prop_name}={prop_value}".format(
                prop_name = semantics.TEST_SUITE_PROPERTY_NAME,
                prop_value = helper.shell_escape(",".join(test_classes)),
            ),
        ])

    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,
        exclude_build_data = ctx.attr.exclude_build_data,
        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, coverage_enabled, executable, coverage_main_class)

    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, coverage_enabled, executable, coverage_main_class):
    java_runtime_toolchain = semantics.find_java_runtime_toolchain(ctx)
    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")
    if coverage_enabled:
        launch_info.add(coverage_main_class, format = "jacoco_main_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(java_runtime_toolchain.java_home_runfiles_path, format = "jar_bin_path=%s/bin/jar.exe")
    launch_info.add(java_runtime_toolchain.version, format = "java_version=%s")

    # 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,
    {
        "exclude_build_data": attr.bool(
            default = False,
            doc = """
Whether to omit the <code>build-data.properties</code> file from the
<code>*_deploy.jar</code> output.
            """,
        ),
        "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)
