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

"""Common util functions for java_* rules"""

load(":common/cc/cc_common.bzl", "cc_common")
load(":common/cc/cc_helper.bzl", "cc_helper")
load(":common/java/java_semantics.bzl", "semantics")
load(":common/paths.bzl", "paths")

testing = _builtins.toplevel.testing
_java_common_internal = _builtins.internal.java_common_internal_do_not_use

def _collect_all_targets_as_deps(ctx, classpath_type = "all"):
    deps = []
    if not classpath_type == "compile_only":
        if hasattr(ctx.attr, "runtime_deps"):
            deps.extend(ctx.attr.runtime_deps)
        if hasattr(ctx.attr, "exports"):
            deps.extend(ctx.attr.exports)

    deps.extend(ctx.attr.deps or [])

    launcher = _filter_launcher_for_target(ctx)
    if launcher:
        deps.append(launcher)

    return deps

def _filter_launcher_for_target(ctx):
    # create_executable=0 disables the launcher
    if hasattr(ctx.attr, "create_executable") and not ctx.attr.create_executable:
        return None

    # use_launcher=False disables the launcher
    if hasattr(ctx.attr, "use_launcher") and not ctx.attr.use_launcher:
        return None

    # BUILD rule "launcher" attribute
    if ctx.attr.launcher and cc_common.launcher_provider in ctx.attr.launcher:
        return ctx.attr.launcher

    return None

def _launcher_artifact_for_target(ctx):
    launcher = _filter_launcher_for_target(ctx)
    if not launcher:
        return None
    files = launcher[DefaultInfo].files.to_list()
    if len(files) != 1:
        fail("%s expected a single artifact in %s" % (ctx.label, launcher))
    return files[0]

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

    if not create_executable and use_testrunner:
        fail("cannot have use_testrunner without creating an executable")
    if not create_executable and main_class:
        fail("main class must not be specified when executable is not created")
    if create_executable and not use_testrunner:
        if not main_class:
            if not ctx.attr.srcs:
                fail("need at least one of 'main_class', 'use_testrunner' or Java source files")
            main_class = _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)")
    if not create_executable:
        return None
    if not main_class:
        if use_testrunner:
            main_class = "com.google.testing.junit.runner.GoogleTestRunner"
        else:
            main_class = _primary_class(ctx)
    return main_class

def _primary_class(ctx):
    if ctx.attr.srcs:
        main = ctx.label.name + ".java"
        for src in ctx.files.srcs:
            if src.basename == main:
                return _full_classname(_strip_extension(src))
    return _full_classname(paths.get_relative(ctx.label.package, ctx.label.name))

def _strip_extension(file):
    return file.dirname + "/" + (
        file.basename[:-(1 + len(file.extension))] if file.extension else file.basename
    )

# TODO(b/193629418): once out of builtins, create a canonical implementation and remove duplicates in depot
def _full_classname(path):
    java_segments = _java_segments(path)
    return ".".join(java_segments) if java_segments != None else None

def _java_segments(path):
    if path.startswith("/"):
        fail("path must not be absolute: '%s'" % path)
    segments = path.split("/")
    root_idx = -1
    for idx, segment in enumerate(segments):
        if segment in ["java", "javatests", "src", "testsrc"]:
            root_idx = idx
            break
    if root_idx < 0:
        return None
    is_src = "src" == segments[root_idx]
    check_mvn_idx = root_idx if is_src else -1
    if (root_idx == 0 or is_src):
        for i in range(root_idx + 1, len(segments) - 1):
            segment = segments[i]
            if "src" == segment or (is_src and (segment in ["java", "javatests"])):
                next = segments[i + 1]
                if next in ["com", "org", "net"]:
                    root_idx = i
                elif "src" == segment:
                    check_mvn_idx = i
                break

    if check_mvn_idx >= 0 and check_mvn_idx < len(segments) - 2:
        next = segments[check_mvn_idx + 1]
        if next in ["main", "test"]:
            next = segments[check_mvn_idx + 2]
            if next in ["java", "resources"]:
                root_idx = check_mvn_idx + 2
    return segments[(root_idx + 1):]

def _concat(*lists):
    result = []
    for list in lists:
        result.extend(list)
    return result

def _get_shared_native_deps_path(
        linker_inputs,
        link_opts,
        linkstamps,
        build_info_artifacts,
        features,
        is_test_target_partially_disabled_thin_lto):
    """
    Returns the path of the shared native library.

    The name must be generated based on the rule-specific inputs to the link actions. At this point
    this includes order-sensitive list of linker inputs and options collected from the transitive
    closure and linkstamp-related artifacts that are compiled during linking. All those inputs can
    be affected by modifying target attributes (srcs/deps/stamp/etc). However, target build
    configuration can be ignored since it will either change output directory (in case of different
    configuration instances) or will not affect anything (if two targets use same configuration).
    Final goal is for all native libraries that use identical linker command to use same output
    name.

    <p>TODO(bazel-team): (2010) Currently process of identifying parameters that can affect native
    library name is manual and should be kept in sync with the code in the
    CppLinkAction.Builder/CppLinkAction/Link classes which are responsible for generating linker
    command line. Ideally we should reuse generated command line for both purposes - selecting a
    name of the native library and using it as link action payload. For now, correctness of the
    method below is only ensured by validations in the CppLinkAction.Builder.build() method.
    """

    fp = ""
    for artifact in linker_inputs:
        fp += artifact.short_path
    fp += str(len(link_opts))
    for opt in link_opts:
        fp += opt
    for artifact in linkstamps:
        fp += artifact.short_path
    for artifact in build_info_artifacts:
        fp += artifact.short_path
    for feature in features:
        fp += feature

    # Sharing of native dependencies may cause an ActionConflictException when ThinLTO is
    # disabled for test and test-only targets that are statically linked, but enabled for other
    # statically linked targets. This happens in case the artifacts for the shared native
    # dependency are output by actions owned by the non-test and test targets both. To fix
    # this, we allow creation of multiple artifacts for the shared native library - one shared
    # among the test and test-only targets where ThinLTO is disabled, and the other shared among
    # other targets where ThinLTO is enabled.
    fp += "1" if is_test_target_partially_disabled_thin_lto else "0"

    fingerprint = "%x" % hash(fp)
    return "_nativedeps/" + fingerprint

def _check_and_get_one_version_attribute(ctx, attr):
    value = getattr(semantics.find_java_toolchain(ctx), attr)
    return value

def _jar_and_target_arg_mapper(jar):
    return jar.path + "," + str(jar.owner)

def _get_feature_config(ctx):
    cc_toolchain = cc_helper.find_cpp_toolchain(ctx, mandatory = False)
    if not cc_toolchain:
        return None
    feature_config = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features + ["java_launcher_link", "static_linking_mode"],
        unsupported_features = ctx.disabled_features,
    )
    return feature_config

def _should_strip_as_default(ctx, feature_config):
    fission_is_active = ctx.fragments.cpp.fission_active_for_current_compilation_mode()
    create_per_obj_debug_info = fission_is_active and cc_common.is_enabled(
        feature_name = "per_object_debug_info",
        feature_configuration = feature_config,
    )
    compilation_mode = ctx.var["COMPILATION_MODE"]
    strip_as_default = create_per_obj_debug_info and compilation_mode == "opt"

    return strip_as_default

def _get_coverage_config(ctx, runner):
    toolchain = semantics.find_java_toolchain(ctx)
    if not ctx.configuration.coverage_enabled:
        return None
    runner = runner if ctx.attr.create_executable else None
    manifest = ctx.actions.declare_file("runtime_classpath_for_coverage/%s/runtime_classpath.txt" % ctx.label.name)
    singlejar = toolchain.single_jar
    return struct(
        runner = runner,
        main_class = "com.google.testing.coverage.JacocoCoverageRunner",
        manifest = manifest,
        env = {
            "JAVA_RUNTIME_CLASSPATH_FOR_COVERAGE": manifest.path,
            "SINGLE_JAR_TOOL": singlejar.executable.path,
        },
        support_files = [manifest, singlejar.executable],
    )

def _get_java_executable(ctx, java_runtime_toolchain, launcher):
    java_executable = launcher.short_path if launcher else java_runtime_toolchain.java_executable_runfiles_path
    if not _is_absolute_target_platform_path(ctx, java_executable):
        java_executable = ctx.workspace_name + "/" + java_executable
    return paths.normalize(java_executable)

def _is_target_platform_windows(ctx):
    return cc_helper.has_target_constraints(ctx, ctx.attr._windows_constraints)

def _is_absolute_target_platform_path(ctx, path):
    if _is_target_platform_windows(ctx):
        return len(path) > 2 and path[1] == ":"
    return path.startswith("/")

def _runfiles_enabled(ctx):
    return ctx.configuration.runfiles_enabled()

def _get_test_support(ctx):
    if ctx.attr.create_executable and ctx.attr.use_testrunner:
        return ctx.attr._test_support
    return None

def _test_providers(ctx):
    test_providers = []
    if cc_helper.has_target_constraints(ctx, ctx.attr._apple_constraints):
        test_providers.append(testing.ExecutionInfo({"requires-darwin": ""}))

    test_env = {}
    test_env.update(cc_helper.get_expanded_env(ctx, {}))

    coverage_config = _get_coverage_config(
        ctx,
        runner = None,  # we only need the environment
    )
    if coverage_config:
        test_env.update(coverage_config.env)
    test_providers.append(testing.TestEnvironment(
        environment = test_env,
        inherited_environment = ctx.attr.env_inherit,
    ))

    return test_providers

def _executable_providers(ctx):
    if ctx.attr.create_executable:
        return [_builtins.toplevel.RunEnvironmentInfo(cc_helper.get_expanded_env(ctx, {}))]
    return []

def _resource_mapper(file):
    return "%s:%s" % (
        file.path,
        semantics.get_default_resource_path(file.short_path, segment_extractor = _java_segments),
    )

def _create_single_jar(
        actions,
        toolchain,
        output,
        sources = depset(),
        resources = depset(),
        mnemonic = "JavaSingleJar",
        progress_message = "Building singlejar jar %{output}",
        build_target = None,
        output_creator = None):
    """Register singlejar action for the output jar.

    Args:
      actions: (actions) ctx.actions
      toolchain: (JavaToolchainInfo) The java toolchain
      output: (File) Output file of the action.
      sources: (depset[File]) The jar files to merge into the output jar.
      resources: (depset[File]) The files to add to the output jar.
      mnemonic: (str) The action identifier
      progress_message: (str) The action progress message
      build_target: (Label) The target label to stamp in the manifest. Optional.
      output_creator: (str) The name of the tool to stamp in the manifest. Optional,
          defaults to 'singlejar'
    Returns:
      (File) Output file which was used for registering the action.
    """
    args = actions.args()
    args.set_param_file_format("shell").use_param_file("@%s", use_always = True)
    args.add("--output", output)
    args.add_all(
        [
            "--compression",
            "--normalize",
            "--exclude_build_data",
            "--warn_duplicate_resources",
        ],
    )
    args.add_all("--sources", sources)
    args.add_all("--resources", resources, map_each = _resource_mapper)

    args.add("--build_target", build_target)
    args.add("--output_jar_creator", output_creator)

    actions.run(
        mnemonic = mnemonic,
        progress_message = progress_message,
        executable = toolchain.single_jar,
        toolchain = semantics.JAVA_TOOLCHAIN_TYPE,
        inputs = depset(transitive = [resources, sources]),
        tools = [toolchain.single_jar],
        outputs = [output],
        arguments = [args],
    )
    return output

# TODO(hvd): use skylib shell.quote()
def _shell_escape(s):
    """Shell-escape a string

    Quotes a word so that it can be used, without further quoting, as an argument
    (or part of an argument) in a shell command.

    Args:
        s: (str) the string to escape

    Returns:
        (str) the shell-escaped string
    """
    if not s:
        # Empty string is a special case: needs to be quoted to ensure that it
        # gets treated as a separate argument.
        return "''"
    for c in s.elems():
        # We do this positively so as to be sure we don't inadvertently forget
        # any unsafe characters.
        if not c.isalnum() and c not in "@%-_+:,./":
            return "'" + s.replace("'", "'\\''") + "'"
    return s

def _tokenize_javacopts(ctx = None, opts = []):
    """Tokenizes a list or depset of options to a list.

    Iff opts is a depset, we reverse the flattened list to ensure right-most
    duplicates are preserved in their correct position.

    If the ctx parameter is omitted, a slow, but pure Starlark, implementation
    of shell tokenization is used. Otherwise, tokenization is performed using
    ctx.tokenize() which has significantly better performance (up to 100x for
    large options lists).

    Args:
        ctx: (RuleContext|None) the rule context
        opts: (depset[str]|[str]) the javac options to tokenize
    Returns:
        [str] list of tokenized options
    """
    if hasattr(opts, "to_list"):
        opts = reversed(opts.to_list())
    if ctx:
        return [
            token
            for opt in opts
            for token in ctx.tokenize(opt)
        ]
    else:
        # TODO: optimize and use the pure Starlark implementation in cc_helper
        return _java_common_internal.tokenize_javacopts(opts)

def _detokenize_javacopts(opts):
    """Detokenizes a list of options to a depset.

    Args:
        opts: ([str]) the javac options to detokenize

    Returns:
        (depset[str]) depset of detokenized options
    """
    return depset(
        [" ".join([_shell_escape(opt) for opt in opts])],
        order = "preorder",
    )

def _derive_output_file(ctx, base_file, *, name_suffix = "", extension = None, extension_suffix = ""):
    """Declares a new file whose name is derived from the given file

    This method allows appending a suffix to the name (before extension), changing
    the extension or appending a suffix after the extension. The new file is declared
    as a sibling of the given base file. At least one of the three options must be
    specified. It is an error to specify both `extension` and `extension_suffix`.

    Args:
        ctx: (RuleContext) the rule context.
        base_file: (File) the file from which to derive the resultant file.
        name_suffix: (str) Optional. The suffix to append to the name before the
        extension.
        extension: (str) Optional. The new extension to use (without '.'). By default,
        the base_file's extension is used.
        extension_suffix: (str) Optional. The suffix to append to the base_file's extension

    Returns:
        (File) the derived file
    """
    if not name_suffix and not extension_suffix and not extension:
        fail("At least one of name_suffix, extension or extension_suffix is required")
    if extension and extension_suffix:
        fail("only one of extension or extension_suffix can be specified")
    if extension == None:
        extension = base_file.extension
    new_basename = paths.replace_extension(base_file.basename, name_suffix + "." + extension + extension_suffix)
    return ctx.actions.declare_file(new_basename, sibling = base_file)

helper = struct(
    collect_all_targets_as_deps = _collect_all_targets_as_deps,
    filter_launcher_for_target = _filter_launcher_for_target,
    launcher_artifact_for_target = _launcher_artifact_for_target,
    check_and_get_main_class = _check_and_get_main_class,
    primary_class = _primary_class,
    strip_extension = _strip_extension,
    concat = _concat,
    get_shared_native_deps_path = _get_shared_native_deps_path,
    check_and_get_one_version_attribute = _check_and_get_one_version_attribute,
    jar_and_target_arg_mapper = _jar_and_target_arg_mapper,
    get_feature_config = _get_feature_config,
    should_strip_as_default = _should_strip_as_default,
    get_coverage_config = _get_coverage_config,
    get_java_executable = _get_java_executable,
    is_absolute_target_platform_path = _is_absolute_target_platform_path,
    is_target_platform_windows = _is_target_platform_windows,
    runfiles_enabled = _runfiles_enabled,
    get_test_support = _get_test_support,
    test_providers = _test_providers,
    executable_providers = _executable_providers,
    create_single_jar = _create_single_jar,
    shell_escape = _shell_escape,
    tokenize_javacopts = _tokenize_javacopts,
    detokenize_javacopts = _detokenize_javacopts,
    derive_output_file = _derive_output_file,
)
