# Copyright 2018 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 APIs for the Android rules."""

load(":path.bzl", _path = "path")
load(":utils.bzl", "log")

_ANDROID_CONSTRAINT_MISSING_ERROR = (
    "A list of constraints provided without the 'android' constraint."
)

def _segment_idx(path_segments):
    """Finds the index of the segment in the path that preceeds the source root.

    Args:
      path_segments: A list of strings, where each string is the segment of a
        filesystem path.

    Returns:
      An index to the path segment that represents the Java segment or -1 if
      none found.
    """
    if _path.is_absolute(path_segments[0]):
        log.error("path must not be absolute: %s" % _path.join(path_segments))

    root_idx = -1
    for idx, segment in enumerate(path_segments):
        if segment in ["java", "javatests", "src", "testsrc"]:
            root_idx = idx
            break
    if root_idx < 0:
        return root_idx

    is_src = path_segments[root_idx] == "src"
    check_maven_idx = root_idx if is_src else -1
    if root_idx == 0 or is_src:
        # Check for a nested root directory.
        for idx in range(root_idx + 1, len(path_segments) - 2):
            segment = path_segments[idx]
            if segment == "src" or (is_src and segment in ["java", "javatests"]):
                next_segment = path_segments[idx + 1]
                if next_segment in ["com", "org", "net"]:
                    root_idx = idx
                elif segment == "src":
                    check_maven_idx = idx
                break

    if check_maven_idx >= 0 and check_maven_idx + 2 < len(path_segments):
        next_segment = path_segments[check_maven_idx + 1]
        if next_segment in ["main", "test"]:
            next_segment = path_segments[check_maven_idx + 2]
            if next_segment in ["java", "resources"]:
                root_idx = check_maven_idx + 2
    return root_idx

def _resolve_package(path):
    """Determines the Java package name from the given path.

    Examples:
        "{workspace}/java/foo/bar/wiz" -> "foo.bar.wiz"
        "{workspace}/javatests/foo/bar/wiz" -> "foo.bar.wiz"

    Args:
      path: A string, representing a file path.

    Returns:
      A string representing a Java package name or None if could not be
      determined.
    """
    path_segments = _path.split(path.partition(":")[0])
    java_idx = _segment_idx(path_segments)
    if java_idx < 0:
        return None
    else:
        return ".".join(path_segments[java_idx + 1:])

def _resolve_package_from_label(
        label,
        custom_package = None):
    """Resolves the Java package from a Label.

    When no legal Java package can be resolved from the label, None will be
    returned unless fallback is specified.

    When a fallback is requested, a not safe for Java compilation package will
    be returned. The fallback value will be derrived by taking the label.package
    and replacing all path separators with ".".
    """
    if custom_package:
        return custom_package

    # For backwards compatibility, also include directories
    # from the label's name
    # Ex: "//foo/bar:java/com/google/baz" is a legal one and
    # results in "com.google"
    label_path = _path.join(
        [label.package] +
        _path.split(label.name)[:-1],
    )
    return _resolve_package(label_path)

def _root(path):
    """Determines the Java root from the given path.

    Examples:
        "{workspace}/java/foo/bar/wiz" -> "{workspace}/java"
        "{workspace}/javatests/foo/bar/wiz" -> "{workspace}/javatests"
        "java/foo/bar/wiz" -> "java"
        "javatests/foo/bar/wiz" -> "javatests"

    Args:
      path: A string, representing a file path.

    Returns:
      A string representing the Java root path or None if could not be
      determined.
    """
    path_segments = _path.split(path.partition(":")[0])
    java_idx = _segment_idx(path_segments)
    if java_idx < 0:
        return None
    else:
        return _path.join(path_segments[0:java_idx + 1])

def _check_for_invalid_java_package(java_package):
    return "-" in java_package or len(java_package.split(".")) < 2

def _invalid_java_package(custom_package, java_package):
    """Checks if the given java package is invalid.

    Only checks if either custom_package or java_package contains the
    illegal character "-" or if they are composed of only one word.
    Only checks java_package if custom_package is an empty string or None.

    Args:
      custom_package: string. Java package given as an attribute to a rule to override
      the java_package.
      java_package: string. Java package inferred from the directory where the BUILD
      containing the rule is.

    Returns:
      A boolean. True if custom_package or java_package contains "-" or is only one word.
      Only checks java_package if custom_package is an empty string or None.
    """
    return (
        (custom_package and _check_for_invalid_java_package(custom_package)) or
        (not custom_package and _check_for_invalid_java_package(java_package))
    )

# The Android specific Java compile.
def _compile_android(
        ctx,
        output_jar,
        output_srcjar = None,
        srcs = [],
        resources = [],
        javac_opts = [],
        r_java = None,
        deps = [],
        exports = [],
        plugins = [],
        exported_plugins = [],
        annotation_processor_additional_outputs = [],
        annotation_processor_additional_inputs = [],
        enable_deps_without_srcs = False,
        neverlink = False,
        constraints = ["android"],
        strict_deps = "Error",
        java_toolchain = None):
    """Compiles the Java and IDL sources for Android.

    Args:
      ctx: The context.
      output_jar: File. The artifact to place the compilation unit.
      output_srcjar: File. The artifact to place the sources of the compilation
        unit. Optional.
      srcs: sequence of Files. A list of files and jars to be compiled.
      resources: sequence of Files. Will be added to the output jar - see
        java_library.resources. Optional.
      javac_opts: sequence of strings. A list of the desired javac options.
        Optional.
      r_java: JavaInfo. The R.jar dependency. Optional.
      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
      exports: sequence of JavaInfo providers. A list of exports. Optional.
      plugins: sequence of JavaPluginInfo providers. A list of plugins. Optional.
      exported_plugins: sequence of JavaPluginInfo providers. A list of exported
        plugins. Optional.
      annotation_processor_additional_outputs: sequence of Files. A list of
        files produced by an annotation processor.
      annotation_processor_additional_inputs: sequence of Files. A list of
        files consumed by an annotation processor.
      enable_deps_without_srcs: Enables the behavior from b/14473160.
      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
      constraints: sequence of Strings. A list of constraints, to constrain the
        target. Optional. By default [].
      strict_deps: string. A string that specifies how to handle strict deps.
        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
        By default 'ERROR'.
      java_toolchain: The java_toolchain Target.

    Returns:
      A JavaInfo provider representing the Java compilation.
    """
    if "android" not in constraints:
        log.error(_ANDROID_CONSTRAINT_MISSING_ERROR)

    if not srcs:
        if deps and enable_deps_without_srcs:
            # TODO(b/122039567): Produces a JavaInfo that exports the deps, but
            # not the plugins. To reproduce the "deps without srcs" bug,
            # b/14473160, behavior in Starlark.
            exports = exports + [
                android_common.enable_implicit_sourceless_deps_exports_compatibility(dep)
                for dep in deps
            ]
        if not exports:
            # Add a "no-op JavaInfo" to propagate the exported_plugins when
            # deps or exports have not been specified by the target and
            # additionally forces java_common.compile method to create the
            # empty output jar and srcjar when srcs have not been specified.
            noop_java_info = java_common.merge([])
            exports = exports + [noop_java_info]

    r_java_info = [r_java] if r_java else []

    java_info = _compile(
        ctx,
        output_jar,
        output_srcjar = output_srcjar,
        srcs = srcs,
        resources = resources,
        javac_opts = javac_opts,
        deps = r_java_info + deps,
        # In native, the JavaInfo exposes two Jars as compile-time deps, the
        # compiled sources and the Android R.java jars. To simulate this
        # behavior, the JavaInfo of the R.jar is also exported.
        exports = r_java_info + exports,
        plugins = plugins,
        exported_plugins = exported_plugins,
        annotation_processor_additional_outputs = (
            annotation_processor_additional_outputs
        ),
        annotation_processor_additional_inputs = (
            annotation_processor_additional_inputs
        ),
        neverlink = neverlink,
        constraints = constraints,
        strict_deps = strict_deps,
        java_toolchain = java_toolchain,
    )
    return java_info

def _compile(
        ctx,
        output_jar,
        output_srcjar = None,
        srcs = [],
        resources = [],
        javac_opts = [],
        deps = [],
        exports = [],
        plugins = [],
        exported_plugins = [],
        annotation_processor_additional_outputs = [],
        annotation_processor_additional_inputs = [],
        neverlink = False,
        constraints = [],
        strict_deps = "Error",
        java_toolchain = None):
    """Compiles the Java and IDL sources for Android.

    Args:
      ctx: The context.
      output_jar: File. The artifact to place the compilation unit.
      output_srcjar: File. The artifact to place the sources of the compilation
        unit. Optional.
      srcs: sequence of Files. A list of files and jars to be compiled.
      resources: sequence of Files. Will be added to the output jar - see
        java_library.resources. Optional.
      javac_opts: sequence of strings. A list of the desired javac options.
        Optional.
      deps: sequence of JavaInfo providers. A list of dependencies. Optional.
      exports: sequence of JavaInfo providers. A list of exports. Optional.
      plugins: sequence of JavaPluginInfo providers. A list of plugins. Optional.
      exported_plugins: sequence of JavaPluginInfo providers. A list of exported
        plugins. Optional.
      annotation_processor_additional_outputs: sequence of Files. A list of
        files produced by an annotation processor.
      annotation_processor_additional_inputs: sequence of Files. A list of
        files consumed by an annotation processor.
      resources: sequence of Files. Will be added to the output jar - see
        java_library.resources. Optional.
      neverlink: Bool. Makes the compiled unit a compile-time only dependency.
      constraints: sequence of Strings. A list of constraints, to constrain the
        target. Optional. By default [].
      strict_deps: string. A string that specifies how to handle strict deps.
        Possible values: 'OFF', 'ERROR','WARN' and 'DEFAULT'. For more details
        see https://docs.bazel.build/versions/master/user-manual.html#flag--strict_java_deps.
        By default 'ERROR'.
      java_toolchain: The java_toolchain Target.

    Returns:
      A JavaInfo provider representing the Java compilation.
    """

    # Split javac opts.
    opts = []
    for opt in javac_opts:
        opts.extend(opt.split(" "))

    # Separate the sources *.java from *.srcjar.
    source_files = []
    source_jars = []
    for src in srcs:
        if src.path.endswith(".srcjar"):
            source_jars.append(src)
        else:
            source_files.append(src)

    return java_common.compile(
        ctx,
        output = output_jar,
        output_source_jar = output_srcjar,
        source_files = source_files,
        source_jars = source_jars,
        resources = resources,
        javac_opts = opts,
        deps = deps,
        exports = exports,
        plugins = plugins,
        exported_plugins = exported_plugins,
        annotation_processor_additional_outputs = (
            annotation_processor_additional_outputs
        ),
        annotation_processor_additional_inputs = (
            annotation_processor_additional_inputs
        ),
        neverlink = neverlink,
        strict_deps = strict_deps,
        java_toolchain = java_toolchain[java_common.JavaToolchainInfo],
    )

def _singlejar(
        ctx,
        inputs,
        output,
        mnemonic = "SingleJar",
        progress_message = "Merge into a single jar.",
        include_build_data = False,
        java_toolchain = None):
    args = ctx.actions.args()
    args.add("--output")
    args.add(output)
    args.add("--compression")
    args.add("--normalize")
    if not include_build_data:
        args.add("--exclude_build_data")
    args.add("--warn_duplicate_resources")
    if inputs:
        args.add("--sources")
        args.add_all(inputs)

    args.use_param_file("@%s")
    args.set_param_file_format("multiline")

    ctx.actions.run(
        executable = java_toolchain[java_common.JavaToolchainInfo].single_jar,
        arguments = [args],
        inputs = inputs,
        outputs = [output],
        mnemonic = mnemonic,
        progress_message = progress_message,
    )

def _run(
        ctx,
        host_javabase,
        jvm_flags = [],
        **args):
    """Run a java binary

    Args:
      ctx: The context.
      host_javabase: Target. The host_javabase.
      jvm_flags: Additional arguments to the JVM itself.
      **args: Additional arguments to pass to ctx.actions.run(). Some will get modified.
    """

    if type(ctx) != "ctx":
        fail("Expected type ctx for argument ctx, got %s" % type(ctx))

    if type(host_javabase) != "Target":
        fail("Expected type Target for argument host_javabase, got %s" % type(host_javabase))

    # Set reasonable max heap default. Required to prevent runaway memory usage.
    # Can still be overridden by callers of this method.
    jvm_flags = ["-Xms4G", "-Xmx4G", "-XX:+ExitOnOutOfMemoryError"] + jvm_flags

    # executable should be a File or a FilesToRunProvider
    jar = args.get("executable")
    if type(jar) == "FilesToRunProvider":
        jar = jar.executable
    elif type(jar) != "File":
        fail("Expected type File or FilesToRunProvider for argument executable, got %s" % type(jar))

    java_runtime = host_javabase[java_common.JavaRuntimeInfo]
    args["executable"] = java_runtime.java_executable_exec_path

    # inputs can be a list or a depset of File
    inputs = args.get("inputs", default = [])
    if type(inputs) == type([]):
        args["inputs"] = depset(direct = inputs + [jar], transitive = [java_runtime.files])
    else:  # inputs is a depset
        args["inputs"] = depset(direct = [jar], transitive = [inputs, java_runtime.files])

    jar_args = ctx.actions.args()
    jar_args.add("-jar", jar)

    args["arguments"] = jvm_flags + [jar_args] + args.get("arguments", default = [])

    ctx.actions.run(**args)

java = struct(
    compile = _compile,
    compile_android = _compile_android,
    resolve_package = _resolve_package,
    resolve_package_from_label = _resolve_package_from_label,
    root = _root,
    invalid_java_package = _invalid_java_package,
    run = _run,
    singlejar = _singlejar,
)
