# Copyright 2024 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.
"""Helper functions to allow us to collect data from attr.label_list."""

load(
    "//cc/toolchains:cc_toolchain_info.bzl",
    "ActionTypeSetInfo",
    "ArgsListInfo",
    "FeatureSetInfo",
    "ToolInfo",
)

visibility([
    "//cc/toolchains/...",
    "//tests/rule_based_toolchain/...",
])

def collect_provider(targets, provider):
    """Collects providers from a label list.

    Args:
        targets: (List[Target]) An attribute from attr.label_list
        provider: (provider) The provider to look up
    Returns:
        A list of the providers
    """
    return [target[provider] for target in targets]

def collect_defaultinfo(targets):
    """Collects DefaultInfo from a label list.

    Args:
        targets: (List[Target]) An attribute from attr.label_list
    Returns:
        A list of the associated defaultinfo
    """
    return collect_provider(targets, DefaultInfo)

def _make_collector(provider, field):
    def collector(targets, direct = [], transitive = []):
        # Avoid mutating what was passed in.
        transitive = transitive[:]
        for value in collect_provider(targets, provider):
            transitive.append(getattr(value, field))
        return depset(direct = direct, transitive = transitive)

    return collector

collect_action_types = _make_collector(ActionTypeSetInfo, "actions")
collect_features = _make_collector(FeatureSetInfo, "features")
collect_files = _make_collector(DefaultInfo, "files")

def collect_data(ctx, targets):
    """Collects from a 'data' attribute.

    This is distinguished from collect_files by the fact that data attributes
    attributes include runfiles.

    Args:
        ctx: (Context) The ctx for the current rule
        targets: (List[Target]) A list of files or executables

    Returns:
        A depset containing all files for each of the targets, and all runfiles
        required to run them.
    """
    return ctx.runfiles(transitive_files = collect_files(targets)).merge_all([
        info.default_runfiles
        for info in collect_defaultinfo(targets)
        if info.default_runfiles != None
    ])

def collect_tools(ctx, targets, fail = fail):
    """Collects tools from a label_list.

    Each entry in the label list may either be a cc_tool or a binary.

    Args:
        ctx: (Context) The ctx for the current rule
        targets: (List[Target]) A list of targets. Each of these targets may be
          either a cc_tool or an executable.
        fail: (function) The fail function. Should only be used in tests.

    Returns:
        A List[ToolInfo], with regular executables creating custom tool info.
    """
    tools = []
    for target in targets:
        info = target[DefaultInfo]
        if ToolInfo in target:
            tools.append(target[ToolInfo])
        elif info.files_to_run != None and info.files_to_run.executable != None:
            tools.append(ToolInfo(
                label = target.label,
                exe = info.files_to_run.executable,
                runfiles = collect_data(ctx, [target]),
                execution_requirements = tuple(),
                allowlist_include_directories = depset(),
            ))
        else:
            fail("Expected %s to be a cc_tool or a binary rule" % target.label)

    return tools

def collect_args_lists(targets, label):
    """Collects a label_list of ArgsListInfo into a single ArgsListInfo

    Args:
        targets: (List[Target]) A label_list of targets providing ArgsListInfo
        label: The label to attach to the resulting ArgsListInfo
    Returns:
        An ArgsListInfo that is the result of joining all of the ArgsListInfos
        together.
    """
    args = []
    by_action = {}
    transitive_files = []
    for target in targets:
        args_list = target[ArgsListInfo]
        args.extend(args_list.args)
        transitive_files.extend([args_info.files for args_info in args_list.args])
        for value in args_list.by_action:
            out = by_action.setdefault(
                value.action,
                struct(args = [], transitive_files = [], action = value.action),
            )
            out.args.extend(value.args)
            out.transitive_files.append(value.files)

    return ArgsListInfo(
        label = label,
        args = tuple(args),
        files = depset(transitive = transitive_files),
        allowlist_include_directories = depset(
            transitive = [a.allowlist_include_directories for a in args],
        ),
        by_action = tuple([
            struct(
                action = k,
                args = tuple(v.args),
                files = depset(transitive = v.transitive_files),
            )
            for k, v in by_action.items()
        ]),
    )
