# 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 for working with args."""

load(":variables.bzl", "get_type")

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

def get_action_type(args_list, action_type):
    """Returns the corresponding entry in ArgsListInfo.by_action.

    Args:
        args_list: (ArgsListInfo) The args list to look through
        action_type: (ActionTypeInfo) The action type to look up.
    Returns:
        The information corresponding to this action type.

    """
    for args in args_list.by_action:
        if args.action == action_type:
            return args

    return struct(action = action_type, args = tuple(), files = depset([]))

def validate_nested_args(*, nested_args, variables, actions, label, fail = fail):
    """Validates the typing for an nested_args invocation.

    Args:
        nested_args: (NestedArgsInfo) The nested_args to validate
        variables: (Dict[str, VariableInfo]) A mapping from variable name to
          the metadata (variable type and valid actions).
        actions: (List[ActionTypeInfo]) The actions we require these variables
          to be valid for.
        label: (Label) The label of the rule we're currently validating.
          Used for error messages.
        fail: The fail function. Use for testing only.
    """
    stack = [(nested_args, {})]

    for _ in range(9999999):
        if not stack:
            break
        nested_args, overrides = stack.pop()
        if nested_args.iterate_over != None or nested_args.unwrap_options:
            # Make sure we don't keep using the same object.
            overrides = dict(**overrides)

        if nested_args.iterate_over != None:
            type = get_type(
                name = nested_args.iterate_over,
                variables = variables,
                overrides = overrides,
                actions = actions,
                args_label = label,
                nested_label = nested_args.label,
                fail = fail,
            )
            if type["name"] == "list":
                # Rewrite the type of the thing we iterate over from a List[T]
                # to a T.
                overrides[nested_args.iterate_over] = type["elements"]
            elif type["name"] == "option" and type["elements"]["name"] == "list":
                # Rewrite Option[List[T]] to T.
                overrides[nested_args.iterate_over] = type["elements"]["elements"]
            else:
                fail("Attempting to iterate over %s, but it was not a list - it was a %s" % (nested_args.iterate_over, type["repr"]))

        # 1) Validate variables marked with after_option_unwrap = False.
        # 2) Unwrap Option[T] to T as required.
        # 3) Validate variables marked with after_option_unwrap = True.
        for after_option_unwrap in [False, True]:
            for var_name, requirements in nested_args.requires_types.items():
                for requirement in requirements:
                    if requirement.after_option_unwrap == after_option_unwrap:
                        type = get_type(
                            name = var_name,
                            variables = variables,
                            overrides = overrides,
                            actions = actions,
                            args_label = label,
                            nested_label = nested_args.label,
                            fail = fail,
                        )
                        if type["name"] not in requirement.valid_types:
                            fail("{msg}, but {var_name} has type {type}".format(
                                var_name = var_name,
                                msg = requirement.msg,
                                type = type["repr"],
                            ))

            # Only unwrap the options after the first iteration of this loop.
            if not after_option_unwrap:
                for var in nested_args.unwrap_options:
                    type = get_type(
                        name = var,
                        variables = variables,
                        overrides = overrides,
                        actions = actions,
                        args_label = label,
                        nested_label = nested_args.label,
                        fail = fail,
                    )
                    if type["name"] == "option":
                        overrides[var] = type["elements"]

        for child in nested_args.nested:
            stack.append((child, overrides))
