# 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 public import ir_pb2


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_pb2.Message):
      if isinstance(proto.field_specs[name], ir_pb2.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_pb2.Optional) or
           len(expected_value))):
        if isinstance(proto.field_specs[name], ir_pb2.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
