# Copyright 2019 Google LLC
#
# 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
#
#     https://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.

"""Utilities for test code."""

from compiler.util import ir_data_utils


def proto_is_superset(proto, expected_values, path=""):
    """Returns true if every value in expected_values is set in proto.

    This is intended to be used in assertTrue in a unit test, like so:

        self.assertTrue(*proto_is_superset(proto, expected))

    Arguments:
      proto: The proto to check.
      expected_values: The reference proto.
      path: The path to the elements being compared.  Clients can generally leave
        this at default.

    Returns:
      A tuple; the first element is True if the fields set in proto are a strict
      superset of the fields set in expected_values.  The second element is an
      informational string specifying the path of a value found in expected_values
      but not in proto.

      Every atomic field that is set in expected_values must be set to the same
      value in proto; every message field set in expected_values must have a
      matching field in proto, such that proto_is_superset(proto.field,
      expected_values.field) is true.

      For repeated fields in expected_values, each element in the expected_values
      proto must have a corresponding element at the same index in proto; proto
      may have additional elements.
    """
    if path:
        path += "."
    for spec, expected_value in ir_data_utils.get_set_fields(expected_values):
        name = spec.name
        field_path = "{}{}".format(path, name)
        value = getattr(proto, name)
        if expected_values.has_field(name) and not proto.has_field(name):
            return False, "{} missing".format(field_path)
        if spec.is_dataclass:
            if spec.is_sequence:
                if len(expected_value) > len(value):
                    return False, "{}[{}] missing".format(
                        field_path, len(getattr(proto, name))
                    )
                for i in range(len(expected_value)):
                    result = proto_is_superset(
                        value[i], expected_value[i], "{}[{}]".format(field_path, i)
                    )
                    if not result[0]:
                        return result
            else:
                result = proto_is_superset(value, expected_value, field_path)
                if not result[0]:
                    return result
        else:
            # Zero-length repeated fields and not-there repeated fields are "the
            # same."
            if expected_value != value and (
                not spec.is_sequence or len(expected_value)
            ):
                if spec.is_sequence:
                    return False, "{} differs: found {}, expected {}".format(
                        field_path, list(value), list(expected_value)
                    )
                else:
                    return False, "{} differs: found {}, expected {}".format(
                        field_path, value, expected_value
                    )
    return True, ""


def dict_file_reader(file_dict):
    """Returns a callable that retrieves entries from file_dict as files.

    This can be used to call glue.parse_emboss_file with file text declared
    inline.

    Arguments:
        file_dict: A dictionary from "file names" to "contents."

    Returns:
        A callable that can be passed to glue.parse_emboss_file in place of the
        "read" builtin.
    """

    def read(file_name):
        try:
            return file_dict[file_name], None
        except KeyError:
            return None, ["File '{}' not found.".format(file_name)]

    return read
