# 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_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
