# Copyright 2021 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 java_import rule.
"""

load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("//java/common:java_common.bzl", "java_common")
load("//java/common:java_info.bzl", "JavaInfo")
load("//java/common:java_semantics.bzl", "semantics")
load(":basic_java_library.bzl", "construct_defaultinfo")
load(":import_deps_check.bzl", "import_deps_check")
load(":proguard_validation.bzl", "validate_proguard_specs")

visibility(["//java/..."])

_java_common_internal = java_common.internal_DO_NOT_USE()
_run_ijar_private_for_builtins = _java_common_internal.run_ijar_private_for_builtins

def _filter_provider(provider, *attrs):
    return [dep[provider] for attr in attrs for dep in attr if provider in dep]

def _collect_jars(ctx, jars):
    jars_dict = {}
    for info in jars:
        if JavaInfo in info:
            fail("'jars' attribute cannot contain labels of Java targets")
        for jar in info.files.to_list():
            jar_path = jar.dirname + jar.basename
            if jars_dict.get(jar_path) != None:
                fail("in jars attribute of java_import rule //" + ctx.label.package + ":" + ctx.attr.name + ": " + jar.basename + " is a duplicate")
            jars_dict[jar_path] = jar
    return [jar_tuple[1] for jar_tuple in jars_dict.items()] if len(jars_dict.items()) > 0 else []

def _process_with_ijars_if_needed(jars, ctx):
    file_dict = {}
    use_ijars = ctx.fragments.java.use_ijars()
    for jar in jars:
        interface_jar = jar
        if use_ijars:
            ijar_basename = jar.short_path.removeprefix("../").removesuffix("." + jar.extension) + "-ijar.jar"
            interface_jar_directory = "_ijar/" + ctx.label.name + "/" + ijar_basename

            interface_jar = ctx.actions.declare_file(interface_jar_directory)
            _run_ijar_private_for_builtins(
                ctx.actions,
                target_label = ctx.label,
                jar = jar,
                output = interface_jar,
                java_toolchain = semantics.find_java_toolchain(ctx),
            )
        file_dict[jar] = interface_jar

    return file_dict

def _check_export_error(ctx, exports):
    not_in_allowlist = hasattr(ctx.attr, "_allowlist_java_import_exports") and not getattr(ctx.attr, "_allowlist_java_import_exports")[PackageSpecificationInfo].contains(ctx.label)
    disallow_java_import_exports = ctx.fragments.java.disallow_java_import_exports()

    if len(exports) != 0 and (disallow_java_import_exports or not_in_allowlist):
        fail("java_import.exports is no longer supported; use java_import.deps instead")

def _check_empty_jars_error(ctx, jars):
    # TODO(kotlaja): Remove temporary incompatible flag [disallow_java_import_empty_jars] once migration is done.
    not_in_allowlist = hasattr(ctx.attr, "_allowlist_java_import_empty_jars") and not getattr(ctx.attr, "_allowlist_java_import_empty_jars")[PackageSpecificationInfo].contains(ctx.label)
    disallow_java_import_empty_jars = ctx.fragments.java.disallow_java_import_empty_jars()

    if len(jars) == 0 and disallow_java_import_empty_jars and not_in_allowlist:
        fail("empty java_import.jars is no longer supported " + ctx.label.package)

def _create_java_info_with_dummy_output_file(ctx, srcjar, all_deps, exports, runtime_deps_list, neverlink, cc_info_list, add_exports, add_opens):
    dummy_jar = ctx.actions.declare_file(ctx.label.name + "_dummy.jar")
    dummy_src_jar = srcjar
    if dummy_src_jar == None:
        dummy_src_jar = ctx.actions.declare_file(ctx.label.name + "_src_dummy.java")
        ctx.actions.write(dummy_src_jar, "")
    return java_common.compile(
        ctx,
        output = dummy_jar,
        java_toolchain = semantics.find_java_toolchain(ctx),
        source_files = [dummy_src_jar],
        deps = all_deps,
        runtime_deps = runtime_deps_list,
        neverlink = neverlink,
        exports = [export[JavaInfo] for export in exports if JavaInfo in export],  # Watchout, maybe you need to add them there manually.
        native_libraries = cc_info_list,
        add_exports = add_exports,
        add_opens = add_opens,
    )

def bazel_java_import_rule(
        ctx,
        jars = [],
        srcjar = None,
        deps = [],
        runtime_deps = [],
        exports = [],
        neverlink = False,
        proguard_specs = [],
        add_exports = [],
        add_opens = []):
    """Implements java_import.

    This rule allows the use of precompiled .jar files as libraries in other Java rules.

    Args:
      ctx: (RuleContext) Used to register the actions.
      jars: (list[Artifact]) List of output jars.
      srcjar: (Artifact) The jar containing the sources.
      deps: (list[Target]) The list of dependent libraries.
      runtime_deps: (list[Target]) Runtime dependencies to attach to the rule.
      exports: (list[Target])  The list of exported libraries.
      neverlink: (bool) Whether this rule should only be used for compilation and not at runtime.
      proguard_specs: (list[File]) Files to be used as Proguard specification.
      add_exports: (list[str]) Allow this library to access the given <module>/<package>.
      add_opens: (list[str]) Allow this library to reflectively access the given <module>/<package>.

    Returns:
      (list[provider]) A list containing DefaultInfo, JavaInfo,
      OutputGroupsInfo, ProguardSpecProvider providers.
    """

    _check_empty_jars_error(ctx, jars)
    _check_export_error(ctx, exports)

    collected_jars = _collect_jars(ctx, jars)
    all_deps = _filter_provider(JavaInfo, deps, exports)

    jdeps_artifact = None
    merged_java_info = java_common.merge(all_deps)
    not_in_allowlist = hasattr(ctx.attr, "_allowlist_java_import_deps_checking") and not ctx.attr._allowlist_java_import_deps_checking[PackageSpecificationInfo].contains(ctx.label)
    if len(collected_jars) > 0 and not_in_allowlist and "incomplete-deps" not in ctx.attr.tags:
        jdeps_artifact = import_deps_check(
            ctx,
            collected_jars,
            merged_java_info.compile_jars,
            merged_java_info.transitive_compile_time_jars,
            "java_import",
        )

    compilation_to_runtime_jar_map = _process_with_ijars_if_needed(collected_jars, ctx)
    runtime_deps_list = [runtime_dep[JavaInfo] for runtime_dep in runtime_deps if JavaInfo in runtime_dep]
    cc_info_list = [dep[CcInfo] for dep in deps if CcInfo in dep]
    java_info = None
    if len(collected_jars) > 0:
        java_infos = []
        for jar in collected_jars:
            java_infos.append(JavaInfo(
                output_jar = jar,
                compile_jar = compilation_to_runtime_jar_map[jar],
                deps = all_deps,
                runtime_deps = runtime_deps_list,
                neverlink = neverlink,
                source_jar = srcjar,
                exports = [export[JavaInfo] for export in exports if JavaInfo in export],  # Watchout, maybe you need to add them there manually.
                native_libraries = cc_info_list,
                add_exports = add_exports,
                add_opens = add_opens,
            ))
        java_info = java_common.merge(java_infos)
    else:
        # TODO(kotlaja): Remove next line once all java_import targets with empty jars attribute are cleaned from depot (b/246559727).
        java_info = _create_java_info_with_dummy_output_file(ctx, srcjar, all_deps, exports, runtime_deps_list, neverlink, cc_info_list, add_exports, add_opens)

    target = {"JavaInfo": java_info}

    target["ProguardSpecProvider"] = validate_proguard_specs(
        ctx,
        proguard_specs,
        [deps, runtime_deps, exports],
    )

    # TODO(kotlaja): Revise if collected_runtimes can be added into construct_defaultinfo directly.
    collected_runtimes = []
    for runtime_dep in ctx.attr.runtime_deps:
        collected_runtimes.extend(runtime_dep.files.to_list())

    target["DefaultInfo"] = construct_defaultinfo(
        ctx,
        collected_jars,
        collected_jars + collected_runtimes,
        neverlink,
        exports,
    )

    output_group_src_jars = depset() if srcjar == None else depset([srcjar])
    target["OutputGroupInfo"] = OutputGroupInfo(
        **{
            "_source_jars": output_group_src_jars,
            "_direct_source_jars": output_group_src_jars,
            "_validation": depset() if jdeps_artifact == None else depset([jdeps_artifact]),
            "_hidden_top_level_INTERNAL_": target["ProguardSpecProvider"].specs,
        }
    )
    return target

def _proxy(ctx):
    return bazel_java_import_rule(
        ctx,
        ctx.attr.jars,
        ctx.file.srcjar,
        ctx.attr.deps,
        ctx.attr.runtime_deps,
        ctx.attr.exports,
        ctx.attr.neverlink,
        ctx.files.proguard_specs,
        ctx.attr.add_exports,
        ctx.attr.add_opens,
    ).values()

_ALLOWED_RULES_IN_DEPS_FOR_JAVA_IMPORT = [
    "java_library",
    "java_import",
    "cc_library",
    "cc_binary",
]

# buildifier: disable=attr-licenses
JAVA_IMPORT_ATTRS = {
    "data": attr.label_list(
        allow_files = True,
        flags = ["SKIP_CONSTRAINTS_OVERRIDE"],
        doc = """
The list of files needed by this rule at runtime.
        """,
    ),
    "deps": attr.label_list(
        providers = [JavaInfo],
        allow_rules = _ALLOWED_RULES_IN_DEPS_FOR_JAVA_IMPORT,
        doc = """
The list of other libraries to be linked in to the target.
See <a href="${link java_library.deps}">java_library.deps</a>.
        """,
    ),
    "exports": attr.label_list(
        providers = [JavaInfo],
        allow_rules = _ALLOWED_RULES_IN_DEPS_FOR_JAVA_IMPORT,
        doc = """
Targets to make available to users of this rule.
See <a href="${link java_library.exports}">java_library.exports</a>.
        """,
    ),
    "runtime_deps": attr.label_list(
        allow_files = [".jar"],
        allow_rules = _ALLOWED_RULES_IN_DEPS_FOR_JAVA_IMPORT,
        providers = [[CcInfo], [JavaInfo]],
        flags = ["SKIP_ANALYSIS_TIME_FILETYPE_CHECK"],
        doc = """
Libraries to make available to the final binary or test at runtime only.
See <a href="${link java_library.runtime_deps}">java_library.runtime_deps</a>.
        """,
    ),
    # JavaImportBazeRule attr
    "jars": attr.label_list(
        allow_files = [".jar"],
        mandatory = True,
        doc = """
The list of JAR files provided to Java targets that depend on this target.
        """,
    ),
    "srcjar": attr.label(
        allow_single_file = [".srcjar", ".jar"],
        flags = ["DIRECT_COMPILE_TIME_INPUT"],
        doc = """
A JAR file that contains source code for the compiled JAR files.
        """,
    ),
    "neverlink": attr.bool(
        default = False,
        doc = """
Only use this library for compilation and not at runtime.
Useful if the library will be provided by the runtime environment
during execution. Examples of libraries like this are IDE APIs
for IDE plug-ins or <code>tools.jar</code> for anything running on
a standard JDK.
        """,
    ),
    "constraints": attr.string_list(
        doc = """
Extra constraints imposed on this rule as a Java library.
        """,
    ),
    # ProguardLibraryRule attr
    "proguard_specs": attr.label_list(
        allow_files = True,
        doc = """
Files to be used as Proguard specification.
These will describe the set of specifications to be used by Proguard. If specified,
they will be added to any <code>android_binary</code> target depending on this library.

The files included here must only have idempotent rules, namely -dontnote, -dontwarn,
assumenosideeffects, and rules that start with -keep. Other options can only appear in
<code>android_binary</code>'s proguard_specs, to ensure non-tautological merges.
        """,
    ),
    # Additional attrs
    "add_exports": attr.string_list(
        doc = """
Allow this library to access the given <code>module</code> or <code>package</code>.
<p>
This corresponds to the javac and JVM --add-exports= flags.
        """,
    ),
    "add_opens": attr.string_list(
        doc = """
Allow this library to reflectively access the given <code>module</code> or
<code>package</code>.
<p>
This corresponds to the javac and JVM --add-opens= flags.
        """,
    ),
    "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(),
    "_java_toolchain_type": attr.label(default = semantics.JAVA_TOOLCHAIN_TYPE),
}

java_import = rule(
    _proxy,
    doc = """
<p>
  This rule allows the use of precompiled <code>.jar</code> files as
  libraries for <code><a href="${link java_library}">java_library</a></code> and
  <code>java_binary</code> rules.
</p>

<h4 id="java_import_examples">Examples</h4>

<pre class="code">
<code class="lang-starlark">
    java_import(
        name = "maven_model",
        jars = [
            "maven_model/maven-aether-provider-3.2.3.jar",
            "maven_model/maven-model-3.2.3.jar",
            "maven_model/maven-model-builder-3.2.3.jar",
        ],
    )
</code>
</pre>
    """,
    attrs = JAVA_IMPORT_ATTRS,
    provides = [JavaInfo],
    fragments = ["java", "cpp"],
    toolchains = [semantics.JAVA_TOOLCHAIN],
)
