# 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


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 name, expected_value in expected_values.raw_fields.items():
    field_path = "{}{}".format(path, name)
    value = getattr(proto, name)
    if issubclass(proto.field_specs[name].type, ir_data.Message):
      if isinstance(proto.field_specs[name], ir_data.Repeated):
        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:
        if (expected_values.HasField(name) and
            not proto.HasField(name)):
          return False, "{} missing".format(field_path)
        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
          (isinstance(proto.field_specs[name], ir_data.Optional) or
           len(expected_value))):
        if isinstance(proto.field_specs[name], ir_data.Repeated):
          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
