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

"""apple_common.link_multi_arch_static_library Starlark implementation"""

load("@_builtins//:common/objc/compilation_support.bzl", "compilation_support")
load(":common/cc/cc_info.bzl", "CcInfo")
load(":common/cc/cc_common.bzl", "cc_common")

apple_common = _builtins.toplevel.apple_common
objc_internal = _builtins.internal.objc_internal

def _link_multi_arch_static_library(ctx, split_target_triplets):
    """Links a (potentially multi-architecture) static library targeting Apple platforms.

    Rule context is a required parameter due to usage of the cc_common.configure_features API.

    Args:
        ctx: The Starlark rule context.
        split_target_triplets: Dict for split transition keys and target triplet struct (arch,
          platform, environment). These values come from Java (see AppleStarlarkCommon.java) and are
          in place due to no available Starlark API for these values.

    Returns:
        A Starlark struct containing the following attributes:
            - objc: The Objc provider containing transitive linking information.
            - output_groups: OutputGroupInfo provider from transitive CcInfo validation_artifacts.
            - outputs: List of structs containing the following attributes:
                - library: Artifact representing a linked static library.
                - architecture: Linked static library architecture (e.g. 'arm64', 'x86_64').
                - platform: Linked static library target Apple platform (e.g. 'ios', 'macos').
                - environment: Linked static library environment (e.g. 'device', 'simulator').
    """
    linking_info_migration = ctx.fragments.objc.linking_info_migration
    split_deps = ctx.split_attr.deps
    split_avoid_deps = ctx.split_attr.avoid_deps
    child_configs_and_toolchains = ctx.split_attr._child_configuration_dummy

    outputs = []
    sdk_dylib = []
    sdk_framework = []
    weak_sdk_framework = []

    for split_transition_key, child_toolchain in child_configs_and_toolchains.items():
        cc_toolchain = child_toolchain[cc_common.CcToolchainInfo]
        common_variables = compilation_support.build_common_variables(
            ctx = ctx,
            toolchain = cc_toolchain,
            use_pch = True,
            deps = split_deps[split_transition_key],
        )

        avoid_objc_providers = []
        avoid_cc_providers = []
        avoid_cc_linking_contexts = []

        if len(split_avoid_deps.keys()):
            for dep in split_avoid_deps[split_transition_key]:
                if apple_common.Objc in dep:
                    avoid_objc_providers.append(dep[apple_common.Objc])
                if CcInfo in dep:
                    avoid_cc_providers.append(dep[CcInfo])
                    avoid_cc_linking_contexts.append(dep[CcInfo].linking_context)

        name = ctx.label.name + "-" + cc_toolchain.target_gnu_system_name + "-fl"

        if not linking_info_migration:
            objc_provider = common_variables.objc_provider.subtract_subtrees(
                avoid_objc_providers = avoid_objc_providers,
                avoid_cc_providers = avoid_cc_providers,
            )
            linking_outputs = compilation_support.register_fully_link_action(
                name = name,
                linking_info_migration = linking_info_migration,
                common_variables = common_variables,
                objc_provider = objc_provider,
            )
            sdk_dylib.append(objc_provider.sdk_dylib)
            sdk_framework.append(objc_provider.sdk_framework)
            weak_sdk_framework.append(objc_provider.weak_sdk_framework)
        else:
            cc_linking_context = objc_internal.subtract_linking_contexts(
                ctx = ctx,
                linking_contexts = common_variables.objc_linking_context.cc_linking_contexts,
                avoid_dep_linking_contexts = avoid_cc_linking_contexts,
            )
            linking_outputs = compilation_support.register_fully_link_action(
                name = name,
                linking_info_migration = linking_info_migration,
                common_variables = common_variables,
                cc_linking_context = cc_linking_context,
            )
            objc_provider = apple_common.new_objc_provider()

        output = {
            "library": linking_outputs.library_to_link.static_library,
        }

        if split_target_triplets != None:
            target_triplet = split_target_triplets.get(split_transition_key)
            output["platform"] = target_triplet.platform
            output["architecture"] = target_triplet.architecture
            output["environment"] = target_triplet.environment

        outputs.append(struct(**output))

    if not linking_info_migration:
        objc_provider = apple_common.new_objc_provider(
            sdk_dylib = depset(transitive = sdk_dylib),
            sdk_framework = depset(transitive = sdk_framework),
            weak_sdk_framework = depset(transitive = weak_sdk_framework),
        )

    header_tokens = []
    for _, deps in split_deps.items():
        for dep in deps:
            if CcInfo in dep:
                header_tokens.append(dep[CcInfo].compilation_context.validation_artifacts)

    output_groups = {"_validation": depset(transitive = header_tokens)}

    return struct(
        outputs = outputs,
        objc = objc_provider,
        output_groups = OutputGroupInfo(**output_groups),
    )

linking_support = struct(
    link_multi_arch_static_library = _link_multi_arch_static_library,
)
