# 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 verifies attributes in an Emboss IR.

The main entry point is check_attributes_in_ir(), which checks attributes in an
IR.
"""

from compiler.util import error
from compiler.util import ir_pb2
from compiler.util import ir_util
from compiler.util import traverse_ir


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


def _attribute_name_for_errors(attr):
  if attr.back_end.text:
    return f"({attr.back_end.text}) {attr.name.text}"
  else:
    return attr.name.text


# 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=_attribute_name_for_errors(attr),
                             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=_attribute_name_for_errors(attr),
                             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=_attribute_name_for_errors(attr),
                             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=_attribute_name_for_errors(attr)))]]
  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=_attribute_name_for_errors(attr),
                             type="a string"))]]
  return []


# Provide more readable names for these functions when used in attribute type
# specifiers.
BOOLEAN_CONSTANT = _is_constant_boolean
BOOLEAN = _is_boolean
INTEGER_CONSTANT = _is_constant_integer
STRING = _is_string


def string_from_list(valid_values):
  """Checks if the given attr has one of the valid_values."""
  def _string_from_list(attr, module_source_file):
    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=_attribute_name_for_errors(attr),
                               options="' or '".join(sorted(valid_values))))]]
    return []
  return _string_from_list


def check_attributes_in_ir(ir,
                           *,
                           back_end=None,
                           types=None,
                           module_attributes=None,
                           struct_attributes=None,
                           bits_attributes=None,
                           enum_attributes=None,
                           enum_value_attributes=None,
                           external_attributes=None,
                           structure_virtual_field_attributes=None,
                           structure_physical_field_attributes=None):
  """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.
    back_end: A string specifying the attribute qualifier to check (such as
        `cpp` for `[(cpp) namespace = "foo"]`), or None to check unqualified
        attributes.  

        Attributes with a different qualifier will not be checked.
    types: A map from attribute names to validators, such as:
        {
            "maximum_bits": attribute_util.INTEGER_CONSTANT,
            "requires": attribute_util.BOOLEAN,
        }
    module_attributes: A set of (attribute_name, is_default) tuples specifying
        the attributes that are allowed at module scope.
    struct_attributes: A set of (attribute_name, is_default) tuples specifying
        the attributes that are allowed at `struct` scope.
    bits_attributes: A set of (attribute_name, is_default) tuples specifying
        the attributes that are allowed at `bits` scope.
    enum_attributes: A set of (attribute_name, is_default) tuples specifying
        the attributes that are allowed at `enum` scope.
    enum_value_attributes: A set of (attribute_name, is_default) tuples
        specifying the attributes that are allowed at the scope of enum values.
    external_attributes: A set of (attribute_name, is_default) tuples
        specifying the attributes that are allowed at `external` scope.
    structure_virtual_field_attributes: A set of (attribute_name, is_default)
        tuples specifying the attributes that are allowed at the scope of
        virtual fields (`let` fields) in structures (both `struct` and `bits`).
    structure_physical_field_attributes: A set of (attribute_name, is_default)
        tuples specifying the attributes that are allowed at the scope of
        physical fields in structures (both `struct` and `bits`).

  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, types, back_end, 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, types, back_end, 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, types, back_end, 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, types, back_end, enum_attributes,
          "enum '{}'".format(
              type_definition.name.name.text), source_file_name))
    elif type_definition.HasField("external"):
      errors.extend(_check_attributes(
          type_definition.attribute, types, back_end, 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 = structure_virtual_field_attributes
      field_adjective = "virtual "
    else:
      field_attributes = structure_physical_field_attributes
      field_adjective = ""
    errors.extend(_check_attributes(
        field.attribute, types, back_end, field_attributes,
        "{}struct field '{}'".format(field_adjective, field.name.name.text),
        source_file_name))

  def check_enum_value(value, source_file_name, errors):
    errors.extend(_check_attributes(
        value.attribute, types, back_end, enum_value_attributes,
        "enum value '{}'".format(value.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})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.EnumValue], check_enum_value,
      parameters={"errors": errors})
  return errors


def _check_attributes(attribute_list, types, back_end, 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.
    back_end: The qualifier for attributes to check, or None.
    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.
  """
  if attribute_specs is None:
    attribute_specs = []
  errors = []
  already_seen_attributes = {}
  for attr in attribute_list:
    if attr.back_end.text:
      if attr.back_end.text != back_end:
        continue
    else:
      if back_end is not None:
        continue
    attribute_name = _attribute_name_for_errors(attr)
    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.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:
      errors.extend(types[attr.name.text](attr, module_source_file))
  return errors


def gather_default_attributes(obj, defaults):
  """Gathers default attributes for an IR object

  This is designed to be able to be used as-is as an incidental action in an IR
  traversal to accumulate defaults for child nodes.

  Arguments:
    defaults: A dict of `{ "defaults": { attr.name.text: attr } }`

  Returns:
    A dict of `{ "defaults": { attr.name.text: attr } }` with any defaults
    provided by `obj` added/overridden.
  """
  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}
