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