# 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.
"""
Defines the native libs processing and an aspect to collect build configuration
of split deps
"""

load("//providers:providers.bzl", "AndroidBinaryNativeLibsInfo", "AndroidCcLinkParamsInfo", "AndroidNativeLibsInfo")
load("//rules:utils.bzl", "utils")
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
load("@rules_java//java/common:java_info.bzl", "JavaInfo")
load("@bazel_skylib//lib:paths.bzl", "paths")

visibility(PROJECT_VISIBILITY)

SplitConfigInfo = provider(
    doc = "Provides information about configuration for a split config dep",
    fields = dict(
        build_config = "The build configuration of the dep.",
        target_platform = "The target platform label of the dep.",
    ),
)

def _split_config_aspect_impl(__, ctx):
    return SplitConfigInfo(
        build_config = ctx.configuration,
        target_platform = ctx.fragments.platform.platform,
    )

split_config_aspect = aspect(
    implementation = _split_config_aspect_impl,
    fragments = ["android"],
)

def _get_libs_dir_name(target_platform):
    name = target_platform.name
    return name

def _get_cc_link_params_infos(ctx, deps):
    infos = []
    for dep in deps:
        if JavaInfo in dep:
            if getattr(dep[JavaInfo], "cc_link_params_info", None):
                infos.append(dep[JavaInfo].cc_link_params_info)
            else:
                # cc_link_params_info attr not available without --experimental_google_legacy_api
                infos.append(
                    CcInfo(
                        compilation_context = None,
                        linking_context = cc_common.create_linking_context(
                            linker_inputs = depset([
                                cc_common.create_linker_input(
                                    owner = ctx.label,
                                    libraries = dep[JavaInfo].transitive_native_libraries,
                                ),
                            ]),
                        ),
                    ),
                )

    return infos

def merge_transitive_native_libs(ctx, deps):
    """Returns a single merged AndroidCcLinkParamsInfo for all deps."""
    return AndroidCcLinkParamsInfo(
        link_params = cc_common.merge_cc_infos(
            cc_infos = _get_cc_link_params_infos(ctx, deps) + [
                info.link_params
                for info in utils.collect_providers(
                    AndroidCcLinkParamsInfo,
                    deps,
                )
            ] + utils.collect_providers(
                CcInfo,
                deps,
            ),
        ),
    )

def process(ctx, filename, merged_libraries_map = {}):
    """Links native deps into a shared library

    Args:
      ctx: The context.
      filename: String. The name of the artifact containing the name of the
            linked shared library

      merged_libraries_map: A dict that maps cpu to a struct describing the librarires produced by
            merging.  The struct is expected to have two fields:
            - new_libraries: New libraries produced by the merging process (e.g. the .so containing
              contents of the merged libraries).
            - stub_libraries: Stub librarires produced by the merging process that should
              replace those with the same names from native depenedencies.

    Returns:
        Tuple of (libs, libs_name) where libs is a depset of all native deps
        and libs_name is a File containing the basename of the linked shared
        library

    """
    target_name = ctx.label.name
    native_libs_basename = None
    libs_name = None
    libs = dict()
    for key, deps in ctx.split_attr.deps.items():
        cc_toolchain_dep = ctx.split_attr._cc_toolchain_split[key]
        cc_toolchain = cc_toolchain_dep[cc_common.CcToolchainInfo]
        build_config = cc_toolchain_dep[SplitConfigInfo].build_config
        libs_dir_name = _get_libs_dir_name(
            cc_toolchain_dep[SplitConfigInfo].target_platform,
        )
        linker_input = cc_common.create_linker_input(
            owner = ctx.label,
            user_link_flags = ["-Wl,-soname=lib" + target_name],
        )
        cc_info = cc_common.merge_cc_infos(
            cc_infos = _concat(
                [CcInfo(linking_context = cc_common.create_linking_context(
                    linker_inputs = depset([linker_input]),
                ))],
                _get_cc_link_params_infos(ctx, deps),
                [dep[AndroidCcLinkParamsInfo].link_params for dep in deps if AndroidCcLinkParamsInfo in dep],
                [dep[CcInfo] for dep in deps if CcInfo in dep],
            ),
        )
        new_libraries = []
        stub_libraries = []
        if merged_libraries_map:
            new_libraries.extend(merged_libraries_map[key].new_libraries)
            stub_libraries.extend(merged_libraries_map[key].stub_libraries)

        native_deps_lib = _link_native_deps_if_present(ctx, cc_info, cc_toolchain, build_config, target_name)
        if native_deps_lib:
            new_libraries.append(native_deps_lib)
            native_libs_basename = native_deps_lib.basename

        shared_libs = _collect_unique_shared_libs(
            new_libraries,
            stub_libraries,
            cc_info,
        )

        if shared_libs:
            libs[libs_dir_name] = depset(shared_libs)

    if libs and native_libs_basename:
        libs_name = ctx.actions.declare_file("nativedeps_filename/" + target_name + "/" + filename)
        ctx.actions.write(output = libs_name, content = native_libs_basename)

    transitive_native_libs = _get_transitive_native_libs(ctx)
    return AndroidBinaryNativeLibsInfo(
        native_libs = libs,
        native_libs_name = libs_name,
        transitive_native_libs_by_cpu_architecture = transitive_native_libs,
    )

# Collect all native shared libraries across split transitions. Some AARs
# contain shared libraries across multiple architectures, e.g. x86 and
# armeabi-v7a, and need to be packed into the APK.
def _get_transitive_native_libs(ctx):
    transitive_native_libs = dict()
    for key, value in ctx.split_attr.deps.items():
        transitive_native_libs[key] = depset(
            transitive = [
                dep[AndroidNativeLibsInfo].native_libs
                for dep in value
                if AndroidNativeLibsInfo in dep
            ],
        )
    return transitive_native_libs

def _all_inputs(cc_info):
    return [
        lib
        for input in cc_info.linking_context.linker_inputs.to_list()
        for lib in input.libraries
    ]

def _collect_unique_shared_libs(new_libraries, stub_libraries, cc_info):
    """Return all the unique shared libraries to be used by the apk.

    New libraries are from external sources, and strictly added to list of shared libraries.
    Stub libraries replace those with the same names from CcInfo (as part of machinery for native
    library merging).

    Also check that there are no duplicates among the new libraries and CcInfo libraries.

    Args:
       new_libraries: Additional libraries that should be used, in addition to those found in
             CcInfo.
       stub_libraries: Libraries that should be used in place of those with the same names
             from CcInfo.
       cc_info: List of CcInfos containing the shared libraries from the build graph.

    Returns:
       The list of shared libraries from all sources.

    """

    # used to exclude so's from cc_info with the same names.
    stub_basenames = {
        library.basename: library
        for library in stub_libraries
    }

    # Used to check duplicate names among new_libraries and cc_info.
    basenames = {
        library.basename: library
        for library in new_libraries
    }

    # Used to check duplicate paths, and whose keys are part of the set of libraries to return.
    artifacts = {
        library: None
        for library in new_libraries
    }
    for input in _all_inputs(cc_info):
        if input.pic_static_library or input.static_library:
            # This is not a shared library and will not be loaded by Android, so skip it.
            continue

        artifact = None
        if input.interface_library:
            if input.resolved_symlink_interface_library:
                artifact = input.resolved_symlink_interface_library
            else:
                artifact = input.interface_library
        elif input.resolved_symlink_dynamic_library:
            artifact = input.resolved_symlink_dynamic_library
        else:
            artifact = input.dynamic_library

        if not artifact:
            fail("Should never happen: did not find artifact for link!")

        basename = artifact.basename
        if artifact in artifacts:
            # We have already reached this library, e.g., through a different solib symlink.
            continue
        if basename in stub_basenames:
            continue
        artifacts[artifact] = None
        if basename in basenames:
            old_artifact = basenames[basename]
            fail(
                "Each library in the transitive closure must have a " +
                "unique basename to avoid name collisions when packaged into " +
                "an apk, but two libraries have the basename '" + basename +
                "': " + str(artifact) + " and " + str(old_artifact) + (
                    " (the library built by this target)" if old_artifact in new_libraries else ""
                ),
            )
        else:
            basenames[basename] = artifact

    return artifacts.keys() + stub_libraries

def _contains_code_to_link(input):
    if not input.static_library and not input.pic_static_library:
        # this is a shared library so we're going to have to copy it
        return False
    if input.objects:
        object_files = input.objects
    elif input.pic_objects:
        object_files = input.pic_objects
    elif _is_any_source_file(input.static_library, input.pic_static_library):
        # this is an opaque library so we're going to have to link it
        return True
    else:
        # if we reach here, this is a cc_library without sources generating an
        # empty archive which does not need to be linked
        # TODO(hvd): replace all such cc_library with exporting_cc_library
        return False
    for obj in object_files:
        if not _is_shared_library(obj):
            # this library was built with a non-shared-library object so we should link it
            return True
    return False

def _is_any_source_file(*files):
    for file in files:
        if file and file.is_source:
            return True
    return False

def _is_shared_library(lib_artifact):
    if (lib_artifact.extension in ["so", "dll", "dylib"]):
        return True

    lib_name = lib_artifact.basename

    # validate against the regex "^.+\\.((so)|(dylib))(\\.\\d\\w*)+$",
    # must match VERSIONED_SHARED_LIBRARY.
    for ext in (".so.", ".dylib."):
        name, _, version = lib_name.rpartition(ext)
        if name and version:
            version_parts = version.split(".")
            for part in version_parts:
                if not part[0].isdigit():
                    return False
                for c in part[1:].elems():
                    if not (c.isalnum() or c == "_"):
                        return False
            return True
    return False

def _is_stamping_enabled(ctx):
    if ctx.configuration.is_tool_configuration():
        return 0
    return getattr(ctx.attr, "stamp", 0)

def _get_build_info(ctx, cc_toolchain):
    # TODO(gnish): This is a temporary workaround until Blaze with Starlark CcToolchainInfo is released.
    if hasattr(cc_toolchain, "_build_info_files"):
        # For Starlark CcToolchainInfo.
        build_info_collection = cc_toolchain._build_info_files
    else:
        # For native CcToolchainInfo.
        build_info_collection = cc_toolchain.build_info_files()
    if _is_stamping_enabled(ctx):
        # Makes the target depend on BUILD_INFO_KEY, which helps to discover stamped targets
        # See b/326620485 for more details.
        ctx.version_file  # buildifier: disable=no-effect
        return build_info_collection.non_redacted_build_info_files.to_list()
    else:
        return build_info_collection.redacted_build_info_files.to_list()

def _get_shared_native_deps_path(
        linker_inputs,
        link_opts,
        linkstamps,
        build_info_artifacts,
        features,
        is_test_target_partially_disabled_thin_lto):
    fp = []
    for artifact in linker_inputs:
        fp.append(artifact.short_path)
    fp.append(str(len(link_opts)))
    for opt in link_opts:
        fp.append(opt)
    for artifact in linkstamps:
        fp.append(artifact.short_path)
    for artifact in build_info_artifacts:
        fp.append(artifact.short_path)
    for feature in features:
        fp.append(feature)

    fp.append("1" if is_test_target_partially_disabled_thin_lto else "0")

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

def _get_static_mode_params_for_dynamic_library_libraries(libs):
    linker_inputs = []
    for lib in libs:
        if lib.pic_static_library:
            linker_inputs.append(lib.pic_static_library)
        elif lib.static_library:
            linker_inputs.append(lib.static_library)
        elif lib.interface_library:
            linker_inputs.append(lib.interface_library)
        else:
            linker_inputs.append(lib.dynamic_library)
    return linker_inputs

def _link_native_deps_if_present(ctx, cc_info, cc_toolchain, build_config, target_name, is_test_rule_class = False):
    needs_linking = False
    all_inputs = _all_inputs(cc_info)
    for input in all_inputs:
        needs_linking = needs_linking or _contains_code_to_link(input)

    configured_features = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        unsupported_features = ctx.disabled_features,
        requested_features = ctx.features,
    )

    # Note: the hasattr() call here is necessary for Bazel 7 compatibility.
    if not needs_linking or (hasattr(configured_features, "is_requested") and configured_features.is_requested("disable_fallback_native_deps_linking")):
        return None

    # This does not need to be shareable, but we use this API to specify the
    # custom file root (matching the configuration)
    output_lib = ctx.actions.declare_shareable_artifact(
        paths.join(ctx.label.package, "nativedeps", target_name, "lib" + target_name + ".so"),
        build_config.bin_dir,
    )

    linker_inputs = cc_info.linking_context.linker_inputs.to_list()

    link_opts = []
    for linker_input in linker_inputs:
        for flag in linker_input.user_link_flags:
            link_opts.append(flag)

    linkstamps = []
    for linker_input in linker_inputs:
        linkstamps.extend(linker_input.linkstamps)
    linkstamps_dict = {linkstamp: None for linkstamp in linkstamps}

    build_info_artifacts = _get_build_info(ctx, cc_toolchain) if linkstamps_dict else []
    requested_features = ["static_linking_mode", "native_deps_link"]
    requested_features.extend(ctx.features)
    if not "legacy_whole_archive" in ctx.disabled_features:
        requested_features.append("legacy_whole_archive")
    requested_features = sorted(requested_features)
    feature_config = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = requested_features,
        unsupported_features = ctx.disabled_features,
    )
    partially_disabled_thin_lto = (
        cc_common.is_enabled(
            feature_name = "thin_lto_linkstatic_tests_use_shared_nonlto_backends",
            feature_configuration = feature_config,
        ) and not cc_common.is_enabled(
            feature_name = "thin_lto_all_linkstatic_use_shared_nonlto_backends",
            feature_configuration = feature_config,
        )
    )
    test_only_target = ctx.attr.testonly or is_test_rule_class
    share_native_deps = ctx.fragments.cpp.share_native_deps()

    linker_inputs = _get_static_mode_params_for_dynamic_library_libraries(all_inputs)

    if share_native_deps:
        shared_path = _get_shared_native_deps_path(
            linker_inputs,
            link_opts,
            [linkstamp.file() for linkstamp in linkstamps_dict],
            build_info_artifacts,
            requested_features,
            test_only_target and partially_disabled_thin_lto,
        )
        linked_lib = ctx.actions.declare_shareable_artifact(shared_path + ".so", build_config.bin_dir)
    else:
        linked_lib = output_lib

    cc_common.link(
        name = ctx.label.name,
        actions = ctx.actions,
        linking_contexts = [cc_info.linking_context],
        output_type = "dynamic_library",
        never_link = True,
        native_deps = True,
        feature_configuration = feature_config,
        cc_toolchain = cc_toolchain,
        test_only_target = test_only_target,
        stamp = getattr(ctx.attr, "stamp", 0),
        main_output = linked_lib,
        use_shareable_artifact_factory = True,
        build_config = build_config,
    )

    if (share_native_deps):
        ctx.actions.symlink(
            output = output_lib,
            target_file = linked_lib,
        )
        return output_lib
    else:
        return linked_lib

def _concat(*list_of_lists):
    res = []
    for list in list_of_lists:
        res.extend(list)
    return res
