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

"""Module which adds and verifies attributes in Emboss IR.

The main entry point is normalize_and_verify(), which adds attributes and/or
verifies attributes which may have been manually entered.
"""

from compiler.front_end import attributes
from compiler.front_end import type_check
from compiler.util import ir_pb2
from compiler.util import error
from compiler.util import ir_util
from compiler.util import traverse_ir

# The "namespace" attribute is C++-back-end specific, and so should not be used
# by the front end.
_NAMESPACE = "namespace"


# Error messages used by multiple attribute type checkers.
_BAD_TYPE_MESSAGE = "Attribute '{name}' must have {type} value."
_MUST_BE_CONSTANT_MESSAGE = "Attribute '{name}' must have a constant value."


# Attribute type checkers
def _is_constant_boolean(attr, module_source_file):
  """Checks if the given attr is a constant boolean."""
  if not attr.value.expression.type.boolean.HasField("value"):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _BAD_TYPE_MESSAGE.format(name=attr.name.text,
                                                  type="a constant boolean"))]]
  return []


def _is_boolean(attr, module_source_file):
  """Checks if the given attr is a boolean."""
  if attr.value.expression.type.WhichOneof("type") != "boolean":
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _BAD_TYPE_MESSAGE.format(name=attr.name.text,
                                                  type="a boolean"))]]
  return []


def _is_constant_integer(attr, module_source_file):
  """Checks if the given attr is an integer constant expression."""
  if (not attr.value.HasField("expression") or
      attr.value.expression.type.WhichOneof("type") != "integer"):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _BAD_TYPE_MESSAGE.format(name=attr.name.text,
                                                  type="an integer"))]]
  if not ir_util.is_constant(attr.value.expression):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _MUST_BE_CONSTANT_MESSAGE.format(
                             name=attr.name.text))]]
  return []


def _is_string(attr, module_source_file):
  """Checks if the given attr is a string."""
  if not attr.value.HasField("string_constant"):
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         _BAD_TYPE_MESSAGE.format(name=attr.name.text,
                                                  type="a string"))]]
  return []


def _is_valid_byte_order(attr, module_source_file):
  """Checks if the given attr is a valid byte_order."""
  return _is_string_from_list(attr, module_source_file,
                              {"BigEndian", "LittleEndian", "Null"})


def _is_string_from_list(attr, module_source_file, valid_values):
  """Checks if the given attr has one of the valid_values."""
  if attr.value.string_constant.text not in valid_values:
    return [[error.error(module_source_file,
                         attr.value.source_location,
                         "Attribute '{name}' must be '{options}'.".format(
                             name=attr.name.text,
                             options="' or '".join(sorted(valid_values))))]]
  return []


def _is_valid_text_output(attr, module_source_file):
  """Checks if the given attr is a valid text_output."""
  return _is_string_from_list(attr, module_source_file, {"Emit", "Skip"})


# Attributes must be the same type no matter where they occur.
_ATTRIBUTE_TYPES = {
    ("", attributes.ADDRESSABLE_UNIT_SIZE): _is_constant_integer,
    ("", attributes.BYTE_ORDER): _is_valid_byte_order,
    ("", attributes.FIXED_SIZE): _is_constant_integer,
    ("", attributes.IS_INTEGER): _is_constant_boolean,
    ("", attributes.REQUIRES): _is_boolean,
    ("", attributes.STATIC_REQUIREMENTS): _is_boolean,
    ("", attributes.TEXT_OUTPUT): _is_valid_text_output,
    ("cpp", _NAMESPACE): _is_string,
}

_MODULE_ATTRIBUTES = {
    ("", attributes.BYTE_ORDER, True),
    # TODO(bolms): Allow back-end-specific attributes to be specified
    # externally.
    ("cpp", _NAMESPACE, False),
}
_BITS_ATTRIBUTES = {
    ("", attributes.FIXED_SIZE, False),
    ("", attributes.REQUIRES, False),
    ("", attributes.STATIC_REQUIREMENTS, False),
}
_STRUCT_ATTRIBUTES = {
    ("", attributes.FIXED_SIZE, False),
    ("", attributes.BYTE_ORDER, True),
    ("", attributes.REQUIRES, False),
    ("", attributes.STATIC_REQUIREMENTS, False),
}
_ENUM_ATTRIBUTES = {
    ("", attributes.STATIC_REQUIREMENTS, False),
}
_EXTERNAL_ATTRIBUTES = {
    ("", attributes.ADDRESSABLE_UNIT_SIZE, False),
    ("", attributes.FIXED_SIZE, False),
    ("", attributes.IS_INTEGER, False),
    ("", attributes.STATIC_REQUIREMENTS, False),
}
_STRUCT_PHYSICAL_FIELD_ATTRIBUTES = {
    ("", attributes.BYTE_ORDER, False),
    ("", attributes.REQUIRES, False),
    ("", attributes.TEXT_OUTPUT, False),
}
_STRUCT_VIRTUAL_FIELD_ATTRIBUTES = {
    ("", attributes.REQUIRES, False),
    ("", attributes.TEXT_OUTPUT, False),
}


def _construct_integer_attribute(name, value, source_location):
  """Constructs an integer Attribute with the given name and value."""
  attr_value = ir_pb2.AttributeValue(
      expression=ir_pb2.Expression(
          constant=ir_pb2.NumericConstant(value=str(value),
                                          source_location=source_location),
          type=ir_pb2.ExpressionType(
              integer=ir_pb2.IntegerType(modular_value=str(value),
                                         modulus="infinity",
                                         minimum_value=str(value),
                                         maximum_value=str(value))),
          source_location=source_location),
      source_location=source_location)
  return ir_pb2.Attribute(name=ir_pb2.Word(text=name),
                          value=attr_value,
                          source_location=source_location)


def _construct_string_attribute(name, value, source_location):
  """Constructs a string Attribute with the given name and value."""
  attr_value = ir_pb2.AttributeValue(
      string_constant=ir_pb2.String(text=value,
                                    source_location=source_location),
      source_location=source_location)
  return ir_pb2.Attribute(name=ir_pb2.Word(text=name,
                                           source_location=source_location),
                          value=attr_value,
                          source_location=source_location)


def _check_attributes_in_ir(ir):
  """Performs basic checks on all attributes in the given ir.

  This function calls _check_attributes on each attribute list in ir.

  Arguments:
    ir: An ir_pb2.EmbossIr to check.

  Returns:
    A list of lists of error.error, or an empty list if there were no errors.
  """

  def check_module(module, errors):
    errors.extend(_check_attributes(
        module.attribute, _MODULE_ATTRIBUTES, "module '{}'".format(
            module.source_file_name), module.source_file_name))

  def check_type_definition(type_definition, source_file_name, errors):
    if type_definition.HasField("structure"):
      if type_definition.addressable_unit == ir_pb2.TypeDefinition.BYTE:
        errors.extend(_check_attributes(
            type_definition.attribute, _STRUCT_ATTRIBUTES, "struct '{}'".format(
                type_definition.name.name.text), source_file_name))
      elif type_definition.addressable_unit == ir_pb2.TypeDefinition.BIT:
        errors.extend(_check_attributes(
            type_definition.attribute, _BITS_ATTRIBUTES, "bits '{}'".format(
                type_definition.name.name.text), source_file_name))
      else:
        assert False, "Unexpected addressable_unit '{}'".format(
            type_definition.addressable_unit)
    elif type_definition.HasField("enumeration"):
      errors.extend(_check_attributes(
          type_definition.attribute, _ENUM_ATTRIBUTES, "enum '{}'".format(
              type_definition.name.name.text), source_file_name))
    elif type_definition.HasField("external"):
      errors.extend(_check_attributes(
          type_definition.attribute, _EXTERNAL_ATTRIBUTES,
          "external '{}'".format(
              type_definition.name.name.text), source_file_name))

  def check_struct_field(field, source_file_name, errors):
    if ir_util.field_is_virtual(field):
      field_attributes = _STRUCT_VIRTUAL_FIELD_ATTRIBUTES
      field_adjective = "virtual "
    else:
      field_attributes = _STRUCT_PHYSICAL_FIELD_ATTRIBUTES
      field_adjective = ""
    errors.extend(_check_attributes(
        field.attribute, field_attributes,
        "{}struct field '{}'".format(field_adjective, field.name.name.text),
        source_file_name))

  errors = []
  # TODO(bolms): Add a check that only known $default'ed attributes are
  # used.
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Module], check_module,
      parameters={"errors": errors})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.TypeDefinition], check_type_definition,
      parameters={"errors": errors})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Field], check_struct_field,
      parameters={"errors": errors})
  return errors


def _check_attributes(attribute_list, attribute_specs, context_name,
                      module_source_file):
  """Performs basic checks on the given list of attributes.

  Checks the given attribute_list for duplicates, unknown attributes, attributes
  with incorrect type, and attributes whose values are not constant.

  Arguments:
    attribute_list: An iterable of ir_pb2.Attribute.
    attribute_specs: A dict of attribute names to _Attribute structures
      specifying the allowed attributes.
    context_name: A name for the context of these attributes, such as "struct
      'Foo'" or "module 'm.emb'".  Used in error messages.
    module_source_file: The value of module.source_file_name from the module
      containing 'attribute_list'.  Used in error messages.

  Returns:
    A list of lists of error.Errors.  An empty list indicates no errors were
    found.
  """
  errors = []
  already_seen_attributes = {}
  for attr in attribute_list:
    if attr.back_end.text:
      attribute_name = "({}) {}".format(attr.back_end.text, attr.name.text)
    else:
      attribute_name = attr.name.text
    if (attr.name.text, attr.is_default) in already_seen_attributes:
      original_attr = already_seen_attributes[attr.name.text, attr.is_default]
      errors.append([
          error.error(module_source_file,
                      attr.source_location,
                      "Duplicate attribute '{}'.".format(attribute_name)),
          error.note(module_source_file,
                     original_attr.source_location,
                     "Original attribute")])
      continue
    already_seen_attributes[attr.name.text, attr.is_default] = attr

    if ((attr.back_end.text, attr.name.text, attr.is_default) not in
        attribute_specs):
      if attr.is_default:
        error_message = "Attribute '{}' may not be defaulted on {}.".format(
            attribute_name, context_name)
      else:
        error_message = "Unknown attribute '{}' on {}.".format(attribute_name,
                                                               context_name)
      errors.append([error.error(module_source_file,
                                 attr.name.source_location,
                                 error_message)])
    else:
      attribute_check = _ATTRIBUTE_TYPES[attr.back_end.text, attr.name.text]
      errors.extend(attribute_check(attr, module_source_file))
  return errors


def _fixed_size_of_struct_or_bits(struct, unit_size):
  """Returns size of struct in bits or None, if struct is not fixed size."""
  size = 0
  for field in struct.field:
    if not field.HasField("location"):
      # Virtual fields do not contribute to the physical size of the struct.
      continue
    field_start = ir_util.constant_value(field.location.start)
    field_size = ir_util.constant_value(field.location.size)
    if field_start is None or field_size is None:
      # Technically, start + size could be constant even if start and size are
      # not; e.g. if start == x and size == 10 - x, but we don't handle that
      # here.
      return None
      # TODO(bolms): knows_own_size
      # TODO(bolms): compute min/max sizes for variable-sized arrays.
    field_end = field_start + field_size
    if field_end >= size:
      size = field_end
  return size * unit_size


def _verify_size_attributes_on_structure(struct, type_definition,
                                         source_file_name, errors):
  """Verifies size attributes on a struct or bits."""
  fixed_size = _fixed_size_of_struct_or_bits(struct,
                                             type_definition.addressable_unit)
  fixed_size_attr = ir_util.get_attribute(type_definition.attribute,
                                          attributes.FIXED_SIZE)
  if not fixed_size_attr:
    return
  if fixed_size is None:
    errors.append([error.error(
        source_file_name, fixed_size_attr.source_location,
        "Struct is marked as fixed size, but contains variable-location "
        "fields.")])
  elif ir_util.constant_value(fixed_size_attr.expression) != fixed_size:
    errors.append([error.error(
        source_file_name, fixed_size_attr.source_location,
        "Struct is {} bits, but is marked as {} bits.".format(
            fixed_size, ir_util.constant_value(fixed_size_attr.expression)))])


# TODO(bolms): remove [fixed_size]; it is superseded by $size_in_{bits,bytes}
def _add_missing_size_attributes_on_structure(struct, type_definition):
  """Adds missing size attributes on a struct."""
  fixed_size = _fixed_size_of_struct_or_bits(struct,
                                             type_definition.addressable_unit)
  if fixed_size is None:
    return
  fixed_size_attr = ir_util.get_attribute(type_definition.attribute,
                                          attributes.FIXED_SIZE)
  if not fixed_size_attr:
    # TODO(bolms): Use the offset and length of the last field as the
    # source_location of the fixed_size attribute?
    type_definition.attribute.extend([
        _construct_integer_attribute(attributes.FIXED_SIZE, fixed_size,
                                     type_definition.source_location)])


def _field_needs_byte_order(field, type_definition, ir):
  """Returns true if the given field needs a byte_order attribute."""
  if ir_util.field_is_virtual(field):
    # Virtual fields have no physical type, and thus do not need a byte order.
    return False
  field_type = ir_util.find_object(
      ir_util.get_base_type(field.type).atomic_type.reference.canonical_name,
      ir)
  assert field_type is not None
  assert field_type.addressable_unit != ir_pb2.TypeDefinition.NONE
  return field_type.addressable_unit != type_definition.addressable_unit


def _field_may_have_null_byte_order(field, type_definition, ir):
  """Returns true if "Null" is a valid byte order for the given field."""
  # If the field is one unit in length, then byte order does not matter.
  if (ir_util.is_constant(field.location.size) and
      ir_util.constant_value(field.location.size) == 1):
    return True
  unit = type_definition.addressable_unit
  # Otherwise, if the field's type is either a one-unit-sized type or an array
  # of a one-unit-sized type, then byte order does not matter.
  if (ir_util.fixed_size_of_type_in_bits(ir_util.get_base_type(field.type), ir)
      == unit):
    return True
  # In all other cases, byte order does matter.
  return False


def _add_missing_byte_order_attribute_on_field(field, type_definition, ir,
                                               defaults):
  """Adds missing byte_order attributes to fields that need them."""
  if _field_needs_byte_order(field, type_definition, ir):
    byte_order_attr = ir_util.get_attribute(field.attribute,
                                            attributes.BYTE_ORDER)
    if byte_order_attr is None:
      if attributes.BYTE_ORDER in defaults:
        field.attribute.extend([defaults[attributes.BYTE_ORDER]])
      elif _field_may_have_null_byte_order(field, type_definition, ir):
        field.attribute.extend(
            [_construct_string_attribute(attributes.BYTE_ORDER, "Null",
                                         field.source_location)])


def _add_addressable_unit_to_external(external, type_definition):
  """Sets the addressable_unit field for an external TypeDefinition."""
  # Strictly speaking, addressable_unit isn't an "attribute," but it's close
  # enough that it makes sense to handle it with attributes.
  del external  # Unused.
  size = ir_util.get_integer_attribute(type_definition.attribute,
                                       attributes.ADDRESSABLE_UNIT_SIZE)
  if size == 1:
    type_definition.addressable_unit = ir_pb2.TypeDefinition.BIT
  elif size == 8:
    type_definition.addressable_unit = ir_pb2.TypeDefinition.BYTE
  # If the addressable_unit_size is not in (1, 8), it will be caught by
  # _verify_addressable_unit_attribute_on_external, below.


def _verify_byte_order_attribute_on_field(field, type_definition,
                                          source_file_name, ir, errors):
  """Verifies the byte_order attribute on the given field."""
  byte_order_attr = ir_util.get_attribute(field.attribute,
                                          attributes.BYTE_ORDER)
  field_needs_byte_order = _field_needs_byte_order(field, type_definition, ir)
  if byte_order_attr and not field_needs_byte_order:
    errors.append([error.error(
        source_file_name, byte_order_attr.source_location,
        "Attribute 'byte_order' not allowed on field which is not byte order "
        "dependent.")])
  if not byte_order_attr and field_needs_byte_order:
    errors.append([error.error(
        source_file_name, field.source_location,
        "Attribute 'byte_order' required on field which is byte order "
        "dependent.")])
  if (byte_order_attr and byte_order_attr.string_constant.text == "Null" and
      not _field_may_have_null_byte_order(field, type_definition, ir)):
    errors.append([error.error(
        source_file_name, byte_order_attr.source_location,
        "Attribute 'byte_order' may only be 'Null' for one-byte fields.")])


def _verify_requires_attribute_on_field(field, source_file_name, ir, errors):
  """Verifies that [requires] is valid on the given field."""
  requires_attr = ir_util.get_attribute(field.attribute, attributes.REQUIRES)
  if not requires_attr:
    return
  if ir_util.field_is_virtual(field):
    field_expression_type = field.read_transform.type
  else:
    if not field.type.HasField("atomic_type"):
      errors.append([
          error.error(source_file_name, requires_attr.source_location,
                      "Attribute 'requires' is only allowed on integer, "
                      "enumeration, or boolean fields, not arrays."),
          error.note(source_file_name, field.type.source_location,
                     "Field type."),
      ])
      return
    field_type = ir_util.find_object(field.type.atomic_type.reference, ir)
    assert field_type, "Field type should be non-None after name resolution."
    field_expression_type = (
        type_check.unbounded_expression_type_for_physical_type(field_type))
  if field_expression_type.WhichOneof("type") not in (
      "integer", "enumeration", "boolean"):
    errors.append([error.error(
        source_file_name, requires_attr.source_location,
        "Attribute 'requires' is only allowed on integer, enumeration, or "
        "boolean fields.")])


def _verify_addressable_unit_attribute_on_external(external, type_definition,
                                                   source_file_name, errors):
  """Verifies the addressable_unit_size attribute on an external."""
  del external  # Unused.
  addressable_unit_size_attr = ir_util.get_integer_attribute(
      type_definition.attribute, attributes.ADDRESSABLE_UNIT_SIZE)
  if addressable_unit_size_attr is None:
    errors.append([error.error(
        source_file_name, type_definition.source_location,
        "Expected '{}' attribute for external type.".format(
            attributes.ADDRESSABLE_UNIT_SIZE))])
  elif addressable_unit_size_attr not in (1, 8):
    errors.append([
        error.error(source_file_name, type_definition.source_location,
                    "Only values '1' (bit) and '8' (byte) are allowed for the "
                    "'{}' attribute".format(attributes.ADDRESSABLE_UNIT_SIZE))
    ])


def _gather_default_attributes(obj, defaults):
  defaults = defaults.copy()
  for attr in obj.attribute:
    if attr.is_default:
      defaulted_attr = ir_pb2.Attribute()
      defaulted_attr.CopyFrom(attr)
      defaulted_attr.is_default = False
      defaults[attr.name.text] = defaulted_attr
  return {"defaults": defaults}


def _add_missing_attributes_on_ir(ir):
  """Adds missing attributes in a complete IR."""
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.External], _add_addressable_unit_to_external)
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Structure], _add_missing_size_attributes_on_structure,
      incidental_actions={
          ir_pb2.Module: _gather_default_attributes,
          ir_pb2.TypeDefinition: _gather_default_attributes,
          ir_pb2.Field: _gather_default_attributes,
      },
      parameters={"defaults": {}})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Field], _add_missing_byte_order_attribute_on_field,
      incidental_actions={
          ir_pb2.Module: _gather_default_attributes,
          ir_pb2.TypeDefinition: _gather_default_attributes,
          ir_pb2.Field: _gather_default_attributes,
      },
      parameters={"defaults": {}})
  return []


def _verify_field_attributes(field, type_definition, source_file_name, ir,
                             errors):
  _verify_byte_order_attribute_on_field(field, type_definition,
                                        source_file_name, ir, errors)
  _verify_requires_attribute_on_field(field, source_file_name, ir, errors)


def _verify_attributes_on_ir(ir):
  """Verifies attributes in a complete IR."""
  errors = []
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Structure], _verify_size_attributes_on_structure,
      parameters={"errors": errors})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.External], _verify_addressable_unit_attribute_on_external,
      parameters={"errors": errors})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Field], _verify_field_attributes,
      parameters={"errors": errors})
  return errors


def normalize_and_verify(ir):
  """Performs various normalizations and verifications on ir.

  Checks for duplicate attributes.

  Adds fixed_size_in_bits and addressable_unit_size attributes to types when
  they are missing, and checks their correctness when they are not missing.

  Arguments:
    ir: The IR object to normalize.

  Returns:
    A list of validation errors, or an empty list if no errors were encountered.
  """
  errors = _check_attributes_in_ir(ir)
  if errors:
    return errors
  _add_missing_attributes_on_ir(ir)
  return _verify_attributes_on_ir(ir)
