# 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 front_end import attributes
from front_end import type_check
from public import ir_pb2
from util import error
from util import ir_util
from 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)
