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

"""Utility functions for reading and manipulating Emboss IR."""

import operator

from public import ir_pb2


_FIXED_SIZE_ATTRIBUTE = "fixed_size_in_bits"


def get_attribute(attribute_list, name):
  """Finds name in attribute_list and returns a AttributeValue or None."""
  attribute_value = None
  for attr in attribute_list:
    if attr.name.text == name and not attr.is_default:
      assert attribute_value is None, 'Duplicate attribute "{}".'.format(name)
      attribute_value = attr.value
  return attribute_value


def get_boolean_attribute(attribute_list, name, default_value=None):
  """Returns the boolean value of an attribute, if any, or default_value.

  Arguments:
      attribute_list: A list of attributes to search.
      name: The name of the desired attribute.
      default_value: A value to return if name is not found in attribute_list,
          or the attribute does not have a boolean value.

  Returns:
      The boolean value of the requested attribute, or default_value if the
      requested attribute is not found or has a non-boolean value.
  """
  attribute_value = get_attribute(attribute_list, name)
  if (not attribute_value or
      not attribute_value.expression.HasField("boolean_constant")):
    return default_value
  return attribute_value.expression.boolean_constant.value


def get_integer_attribute(attribute_list, name, default_value=None):
  """Returns the integer value of an attribute, if any, or default_value.

  Arguments:
      attribute_list: A list of attributes to search.
      name: The name of the desired attribute.
      default_value: A value to return if name is not found in attribute_list,
          or the attribute does not have an integer value.

  Returns:
      The integer value of the requested attribute, or default_value if the
      requested attribute is not found or has a non-integer value.
  """
  attribute_value = get_attribute(attribute_list, name)
  if (not attribute_value or
      attribute_value.expression.type.WhichOneof("type") != "integer" or
      not is_constant(attribute_value.expression)):
    return default_value
  return constant_value(attribute_value.expression)


def is_constant(expression, bindings=None):
  return constant_value(expression, bindings) is not None


def is_constant_type(expression_type):
  """Returns True if expression_type is inhabited by a single value."""
  return (expression_type.integer.modulus == "infinity" or
          expression_type.boolean.HasField("value") or
          expression_type.enumeration.HasField("value"))


def constant_value(expression, bindings=None):
  """Evaluates expression with the given bindings."""
  if expression.WhichOneof("expression") == "constant":
    return int(expression.constant.value)
  elif expression.WhichOneof("expression") == "constant_reference":
    # We can't look up the constant reference without the IR, but by the time
    # constant_value is called, the actual values should have been propagated to
    # the type information.
    if expression.type.WhichOneof("type") == "integer":
      assert expression.type.integer.modulus == "infinity"
      return int(expression.type.integer.modular_value)
    elif expression.type.WhichOneof("type") == "boolean":
      assert expression.type.boolean.HasField("value")
      return expression.type.boolean.value
    elif expression.type.WhichOneof("type") == "enumeration":
      assert expression.type.enumeration.HasField("value")
      return int(expression.type.enumeration.value)
    else:
      assert False, "Unexpected expression type {}".format(
          expression.type.WhichOneof("type"))
  elif expression.WhichOneof("expression") == "function":
    return _constant_value_of_function(expression.function, bindings)
  elif expression.WhichOneof("expression") == "field_reference":
    return None
  elif expression.WhichOneof("expression") == "boolean_constant":
    return expression.boolean_constant.value
  elif expression.WhichOneof("expression") == "builtin_reference":
    name = expression.builtin_reference.canonical_name.object_path[0]
    if bindings and name in bindings:
      return bindings[name]
    else:
      return None
  elif expression.WhichOneof("expression") is None:
    return None
  else:
    assert False, "Unexpected expression kind {}".format(
        expression.WhichOneof("expression"))


def _constant_value_of_function(function, bindings):
  """Returns the constant value of evaluating `function`, or None."""
  values = [constant_value(arg, bindings) for arg in function.args]
  # Expressions like `$is_statically_sized && 1 <= $static_size_in_bits <= 64`
  # should return False, not None, if `$is_statically_sized` is false, even
  # though `$static_size_in_bits` is unknown.
  #
  # The easiest way to allow this is to use a three-way logic chart for each;
  # specifically:
  #
  # AND:      True     False    Unknown
  #         +--------------------------
  # True    | True     False    Unknown
  # False   | False    False    False
  # Unknown | Unknown  False    Unknown
  #
  # OR:       True     False    Unknown
  #         +--------------------------
  # True    | True     True     True
  # False   | True     False    Unknown
  # Unknown | True     Unknown  Unknown
  #
  # This raises the question of just how many constant-from-nonconstant
  # expressions Emboss should support.  There are, after all, a vast number of
  # constant expression patterns built from non-constant subexpressions, such as
  # `0 * X` or `X == X` or `3 * X == X + X + X`.  I (bolms@) am not implementing
  # any further special cases because I do not see any practical use for them.
  if function.function == ir_pb2.Function.AND:
    if any(value is False for value in values):
      return False
    elif any(value is None for value in values):
      return None
    else:
      return True
  elif function.function == ir_pb2.Function.OR:
    if any(value is True for value in values):
      return True
    elif any(value is None for value in values):
      return None
    else:
      return False
  elif function.function == ir_pb2.Function.CHOICE:
    if values[0] is None:
      return None
    else:
      return values[1] if values[0] else values[2]
  # Other than the logical operators and choice operator, the result of any
  # function on an unknown value is, itself, considered unknown.
  if any(value is None for value in values):
    return None
  functions = {
      ir_pb2.Function.ADDITION: operator.add,
      ir_pb2.Function.SUBTRACTION: operator.sub,
      ir_pb2.Function.MULTIPLICATION: operator.mul,
      ir_pb2.Function.EQUALITY: operator.eq,
      ir_pb2.Function.INEQUALITY: operator.ne,
      ir_pb2.Function.LESS: operator.lt,
      ir_pb2.Function.LESS_OR_EQUAL: operator.le,
      ir_pb2.Function.GREATER: operator.gt,
      ir_pb2.Function.GREATER_OR_EQUAL: operator.ge,
      # Python's max([1, 2]) == 2; max(1, 2) == 2; max([1]) == 1; but max(1)
      # throws a TypeError ("'int' object is not iterable").
      ir_pb2.Function.MAXIMUM: lambda *x: max(x),
  }
  return functions[function.function](*values)


def _hashable_form_of_name(name):
  return (name.module_file,) + tuple(name.object_path)


def hashable_form_of_reference(reference):
  """Returns a representation of reference that can be used as a dict key.

  Arguments:
    reference: An ir_pb2.Reference or ir_pb2.NameDefinition.

  Returns:
    A tuple of the module_file and object_path.
  """
  return _hashable_form_of_name(reference.canonical_name)


def hashable_form_of_field_reference(field_reference):
  """Returns a representation of field_reference that can be used as a dict key.

  Arguments:
    field_reference: An ir_pb2.FieldReference

  Returns:
    A tuple of tuples of the module_files and object_paths.
  """
  return tuple(_hashable_form_of_name(reference.canonical_name)
               for reference in field_reference.path)


def is_array(type_ir):
  """Returns true if type_ir is an array type."""
  return type_ir.HasField("array_type")


def _find_path_in_structure_field(path, field):
  if not path:
    return field
  return None


def _find_path_in_structure(path, type_definition):
  for field in type_definition.structure.field:
    if field.name.name.text == path[0]:
      return _find_path_in_structure_field(path[1:], field)
  return None


def _find_path_in_enumeration(path, type_definition):
  if len(path) != 1:
    return None
  for value in type_definition.enumeration.value:
    if value.name.name.text == path[0]:
      return value
  return None


def _find_path_in_parameters(path, type_definition):
  if len(path) > 1:
    return None
  for parameter in type_definition.runtime_parameter:
    if parameter.name.name.text == path[0]:
      return parameter
  return None


def _find_path_in_type_definition(path, type_definition):
  """Finds the object with the given path in the given type_definition."""
  if not path:
    return type_definition
  obj = _find_path_in_parameters(path, type_definition)
  if obj:
    return obj
  if type_definition.HasField("structure"):
    obj = _find_path_in_structure(path, type_definition)
  elif type_definition.HasField("enumeration"):
    obj = _find_path_in_enumeration(path, type_definition)
  if obj:
    return obj
  else:
    return _find_path_in_type_list(path, type_definition.subtype)


def _find_path_in_type_list(path, type_list):
  for type_definition in type_list:
    if type_definition.name.name.text == path[0]:
      return _find_path_in_type_definition(path[1:], type_definition)
  return None


def _find_path_in_module(path, module_ir):
  if not path:
    return module_ir
  return _find_path_in_type_list(path, module_ir.type)


def find_object_or_none(name, ir):
  """Finds the object with the given canonical name, if it exists.."""
  if (isinstance(name, ir_pb2.Reference) or
      isinstance(name, ir_pb2.NameDefinition)):
    path = _hashable_form_of_name(name.canonical_name)
  elif isinstance(name, ir_pb2.CanonicalName):
    path = _hashable_form_of_name(name)
  else:
    path = name

  for module in ir.module:
    if module.source_file_name == path[0]:
      return _find_path_in_module(path[1:], module)

  return None


def find_object(name, ir):
  """Finds the IR of the type, field, or value with the given canonical name."""
  result = find_object_or_none(name, ir)
  assert result is not None, "Bad reference {}".format(name)
  return result


def find_parent_object(name, ir):
  """Finds the parent object of the object with the given canonical name."""
  if (isinstance(name, ir_pb2.Reference) or
      isinstance(name, ir_pb2.NameDefinition)):
    path = _hashable_form_of_name(name.canonical_name)
  elif isinstance(name, ir_pb2.CanonicalName):
    path = _hashable_form_of_name(name)
  else:
    path = name
  return find_object(path[:-1], ir)


def get_base_type(type_ir):
  """Returns the base type of the given type.

  Arguments:
    type_ir: IR of a type reference.

  Returns:
    If type_ir corresponds to an atomic type (like "UInt"), returns type_ir.  If
    type_ir corresponds to an array type (like "UInt:8[12]" or "Square[8][8]"),
    returns the type after stripping off the array types ("UInt" or "Square").
  """
  while type_ir.HasField("array_type"):
    type_ir = type_ir.array_type.base_type
  assert type_ir.HasField("atomic_type"), (
      "Unknown kind of type {}".format(type_ir))
  return type_ir


def fixed_size_of_type_in_bits(type_ir, ir):
  """Returns the fixed, known size for the given type, in bits, or None.

  Arguments:
    type_ir: The IR of a type.
    ir: A complete IR, used to resolve references to types.

  Returns:
    size if the size of the type can be determined, otherwise None.
  """
  array_multiplier = 1
  while type_ir.HasField("array_type"):
    if type_ir.array_type.WhichOneof("size") == "automatic":
      return None
    else:
      assert type_ir.array_type.WhichOneof("size") == "element_count", (
          'Expected array size to be "automatic" or "element_count".')
    element_count = type_ir.array_type.element_count
    if not is_constant(element_count):
      return None
    else:
      array_multiplier *= constant_value(element_count)
    assert not type_ir.HasField("size_in_bits"), (
        "TODO(bolms): implement explicitly-sized arrays")
    type_ir = type_ir.array_type.base_type
  assert type_ir.HasField("atomic_type"), "Unexpected type!"
  if type_ir.HasField("size_in_bits"):
    size = constant_value(type_ir.size_in_bits)
  else:
    type_definition = find_object(type_ir.atomic_type.reference, ir)
    size_attr = get_attribute(type_definition.attribute, _FIXED_SIZE_ATTRIBUTE)
    if not size_attr:
      return None
    size = constant_value(size_attr.expression)
  return size * array_multiplier


def field_is_virtual(field_ir):
  """Returns true if the field is virtual."""
  # TODO(bolms): Should there be a more explicit indicator that a field is
  # virtual?
  return not field_ir.HasField("location")


def field_is_read_only(field_ir):
  """Returns true if the field is read-only."""
  # For now, all virtual fields are read-only, and no non-virtual fields are
  # read-only.
  return field_ir.write_method.read_only
