# Copyright 2015 Google Inc. All Rights Reserved.
# coding=utf-8
#
# 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
#
#     http://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.
"""Create contexts to be used by Jinja template generation.

Extract the relevant information from the IdlParser objects and store them in
dicts that will be used by Jinja in JS bindings generation.
"""

from idl_definitions import IdlTypedef
from idl_types import IdlPromiseType
from idl_types import IdlSequenceType
from name_conversion import capitalize_function_name
from name_conversion import convert_to_cobalt_constant_name
from name_conversion import convert_to_cobalt_enumeration_value
from name_conversion import convert_to_cobalt_name
from name_conversion import get_interface_name
from overload_context import get_overload_contexts
from v8_attributes import is_constructor_attribute
from v8_interface import method_overloads_by_name


def is_object_type(idl_type):
  return str(idl_type) == 'object'


def is_any_type(idl_type):
  return idl_type.name == 'Any'


def is_sequence_type(idl_type):
  return isinstance(idl_type, IdlSequenceType)


def is_promise_type(idl_type):
  return isinstance(idl_type, IdlPromiseType)


def idl_literal_to_cobalt_literal(idl_type, idl_literal):
  """Map IDL literal to the corresponding cobalt value."""
  if idl_literal.is_null and not idl_type.is_interface_type:
    return 'base::nullopt'
  if idl_type.is_enum:
    return convert_to_cobalt_enumeration_value(idl_type, idl_literal.value)
  return str(idl_literal)


def get_dictionary_default_value(idl_type, idl_literal, name):
  """Mapping to cobalt value filtering for dictionary acceptable values."""
  if is_any_type(idl_type) and not idl_literal.is_null:
    raise ValueError('Unsupported default value in dictionary: '
                     '\'%s %s = %s\'. Only null default is supported.' %
                     (idl_type, name, idl_literal))
  return idl_literal_to_cobalt_literal(idl_type, idl_literal)


def idl_primitive_type_to_cobalt(idl_type):
  """Map IDL primitive type to C++ type."""
  type_map = {
      'boolean': 'bool',
      'byte': 'int8_t',
      'octet': 'uint8_t',
      'short': 'int16_t',
      'unsigned short': 'uint16_t',
      'long': 'int32_t',
      'long long': 'int64_t',
      'unsigned long': 'uint32_t',
      'unsigned long long': 'uint64_t',
      'float': 'float',
      'unrestricted float': 'float',
      'double': 'double',
      'unrestricted double': 'double',
  }
  assert idl_type.is_primitive_type, 'Expected primitive type.'
  return type_map[idl_type.base_type]


def cobalt_type_is_optional(idl_type):
  """Return True iff the idl_type should be wrapped by a base::optional<>.

  Returns:
    (bool): Whether the cobalt type should be wrapped in base::optional<>.
  Args:
    idl_type: An idl_types.IdlType object.

  The Cobalt type for interfaces and callback functions are scoped_refptr, so
  they can already be assigned a NULL value. Other types, such as primitives,
  strings, and unions, need to be wrapped by base::optional<>, in which case
  the IDL null value will map to base::nullopt_t.
  """

  # These never need base::optional<>
  if (idl_type.is_interface_type or idl_type.is_callback_function or
      idl_type.is_callback_interface or is_object_type(idl_type) or
      is_any_type(idl_type)):
    return False

  # We consider a union type to be nullable if either the entire union is
  # nullable, or one of its member types are.
  return (idl_type.is_nullable or
          (idl_type.is_union_type and
           (idl_union_type_has_nullable_member(idl_type))))


def get_optional_arguments(arguments):
  """Create optional arguments list."""
  return [argument for argument in arguments if argument['is_optional']]


def get_non_optional_arguments(arguments):
  """Create non optional arguments list."""
  return [
      argument for argument in arguments
      if not argument['is_optional'] and not argument['is_variadic']
  ]


def get_num_default_arguments(optional_arguments):
  """Return the number of default arguments."""
  num_default_arguments = 0

  for argument in optional_arguments:
    if argument['default_value'] is not None:
      num_default_arguments += 1

  return num_default_arguments


def get_variadic_argument(arguments):
  """Return the variadic argument."""
  length = len(arguments)

  if length > 0 and arguments[length - 1]['is_variadic']:
    return arguments[length - 1]
  else:
    return []


def idl_union_type_has_nullable_member(idl_type):
  """Return True iff the idl_type is a union with a nullable member."""
  assert idl_type.is_union_type, 'Expected union type.'
  for member in idl_type.member_types:
    if member.is_nullable:
      return True
    elif member.is_union_type and idl_union_type_has_nullable_member(member):
      return True
  return False


def get_conversion_flags(idl_type, extended_attributes):
  """Build an expression setting a bitmask of flags used for conversion."""
  assert not isinstance(idl_type, IdlTypedef)
  flags = []
  # Flags must correspond to the enumeration in
  # scripts/javascriptcore/conversion_helpers.h
  if (idl_type.is_numeric_type and not idl_type.is_integer_type and
      not idl_type.base_type.startswith('unrestricted ')):
    flags.append('kConversionFlagRestricted')
  if idl_type.is_nullable and not cobalt_type_is_optional(idl_type.inner_type):
    # Other types use base::optional<> so there is no need for a flag to check
    # if null values are allowed.
    flags.append('kConversionFlagNullable')
  if idl_type.is_string_type:
    if extended_attributes.get('TreatNullAs', '') == 'EmptyString':
      flags.append('kConversionFlagTreatNullAsEmptyString')
    elif extended_attributes.get('TreatUndefinedAs', '') == 'EmptyString':
      flags.append('kConversionFlagTreatUndefinedAsEmptyString')

  if extended_attributes.has_key('Clamp'):
    flags.append('kConversionFlagClamped')

  if flags:
    return '(%s)' % ' | '.join(flags)
  else:
    return 'kNoConversionFlags'


class ContextBuilder(object):
  """Build jinja2 contexts (python dicts) for use in bindings generation."""

  def __init__(self, info_provider):
    self.info_provider = info_provider

  def resolve_typedef(self, idl_type):
    idl_type = idl_type.resolve_typedefs(self.info_provider.typedefs)
    if isinstance(idl_type, IdlTypedef):
      idl_type = idl_type.idl_type
    return idl_type

  def idl_sequence_type_to_cobalt(self, idl_type):
    """Map IDL sequence type to C++ sequence type implementation."""
    assert is_sequence_type(idl_type), 'Expected sequence type.'
    element_idl_type = idl_type.element_type
    assert not is_object_type(element_idl_type), 'Object type not supported.'
    assert (not element_idl_type.is_callback_function and
            not idl_type.is_callback_interface), 'Callback types not supported.'
    element_cobalt_type = self.idl_type_to_cobalt_type(
        self.resolve_typedef(element_idl_type))
    return '::cobalt::script::Sequence< %s >' % element_cobalt_type

  def idl_union_type_to_cobalt(self, idl_type):
    """Map IDL union type to C++ union type implementation."""
    # Flatten the union type. Order matters for our implementation.
    assert idl_type.is_union_type, 'Expected union type.'
    flattened_types = []
    for member in idl_type.member_types:
      member = self.resolve_typedef(member)
      if member.is_nullable:
        member = member.inner_type

      if member.is_union_type:
        flattened_types.extend(self.idl_union_type_to_cobalt(member))
      else:
        flattened_types.append(member)

    cobalt_types = [self.idl_type_to_cobalt_type(t) for t in flattened_types]
    return '::cobalt::script::UnionType%d<%s >' % (len(cobalt_types),
                                                   ', '.join(cobalt_types))

  def idl_type_to_cobalt_type(self, idl_type):
    """Map IDL type to C++ type."""
    assert not isinstance(idl_type, IdlTypedef)
    cobalt_type = None
    if idl_type.is_primitive_type:
      cobalt_type = idl_primitive_type_to_cobalt(idl_type)
    elif idl_type.is_string_type:
      cobalt_type = 'std::string'
    elif idl_type.is_callback_interface:
      cobalt_type = '::cobalt::script::CallbackInterfaceTraits<%s >' % (
          get_interface_name(idl_type))
    elif idl_type.is_interface_type:
      cobalt_type = 'scoped_refptr<%s>' % get_interface_name(idl_type)
    elif idl_type.is_union_type:
      cobalt_type = self.idl_union_type_to_cobalt(idl_type)
    elif idl_type.is_enum:
      cobalt_type = idl_type.name
    elif is_sequence_type(idl_type):
      cobalt_type = self.idl_sequence_type_to_cobalt(idl_type)
    elif idl_type.name == 'void':
      cobalt_type = 'void'
    elif is_object_type(idl_type):
      cobalt_type = '::cobalt::script::OpaqueHandle'
    elif is_any_type(idl_type):
      cobalt_type = '::cobalt::script::ValueHandle'
    elif idl_type.is_dictionary:
      cobalt_type = get_interface_name(idl_type)
    elif is_promise_type(idl_type):
      cobalt_type = '::cobalt::script::NativePromise'

    assert cobalt_type, 'Unsupported idl_type %s' % idl_type

    if cobalt_type_is_optional(idl_type):
      cobalt_type = 'base::optional<%s >' % cobalt_type

    return cobalt_type

  def typed_object_to_cobalt_type(self, interface, typed_object):
    """Map type of IDL TypedObject to C++ type."""
    idl_type = self.resolve_typedef(typed_object.idl_type)
    if idl_type.is_callback_function:
      cobalt_type = interface.name + '::' + get_interface_name(idl_type)
    else:
      cobalt_type = self.idl_type_to_cobalt_type(idl_type)
    if getattr(typed_object, 'is_variadic', False):
      cobalt_type = 'std::vector<%s>' % cobalt_type
    return cobalt_type

  def typed_object_to_arg_type(self, interface, typed_object):
    """Map type of IDL TypedObject to C++ type that is a function argument."""
    base_type = self.typed_object_to_cobalt_type(interface, typed_object)

    idl_type = typed_object.idl_type
    if (idl_type.is_callback_function or idl_type.is_object_type or
        idl_type.is_callback_interface):
      return base_type + '*'
    if is_any_type(idl_type):
      return 'const ::cobalt::script::ScriptValue<%s>*' % base_type
    if idl_type.is_string_type or idl_type.is_interface_type:
      return 'const %s&' % base_type
    return base_type

  def argument_context(self, interface, argument):
    """Create template values for method/constructor arguments."""
    return {
        'idl_type_object':
            argument.idl_type,
        'name':
            argument.name,
        'type':
            self.typed_object_to_cobalt_type(interface, argument),
        'arg_type':
            self.typed_object_to_arg_type(interface, argument),
        'conversion_flags':
            get_conversion_flags(
                self.resolve_typedef(argument.idl_type),
                argument.extended_attributes),
        'is_optional':
            argument.is_optional,
        'is_variadic':
            argument.is_variadic,
        'default_value':
            idl_literal_to_cobalt_literal(argument.idl_type,
                                          argument.default_value)
            if argument.default_value else None,
    }

  def partial_context(self, interface, operation):
    """Create partial template values for generating bindings."""
    arguments = [
        self.argument_context(interface, a) for a in operation.arguments
    ]
    optional_arguments = get_optional_arguments(arguments)
    num_default_arguments = get_num_default_arguments(optional_arguments)
    return {
        'arguments':
            arguments,
        'non_optional_arguments':
            get_non_optional_arguments(arguments),
        'optional_arguments':
            optional_arguments,
        'num_default_arguments':
            num_default_arguments,
        'variadic_argument':
            get_variadic_argument(arguments),
        'has_non_default_optional_arguments':
            len(optional_arguments) > num_default_arguments,
    }

  def constructor_context(self, interface, constructor):
    """Create template values for generating constructor bindings."""
    context = {
        'call_with':
            interface.extended_attributes.get('ConstructorCallWith', None),
        'raises_exception': (interface.extended_attributes.get(
            'RaisesException', None) == 'Constructor'),
    }

    context.update(self.partial_context(interface, constructor))
    return context

  def method_context(self, interface, operation):
    """Create template values for generating method bindings."""
    context = {
        'idl_name':
            operation.name,
        'name':
            capitalize_function_name(operation.name),
        'type':
            self.typed_object_to_cobalt_type(interface, operation),
        'is_static':
            operation.is_static,
        'call_with':
            operation.extended_attributes.get('CallWith', None),
        'raises_exception':
            operation.extended_attributes.has_key('RaisesException'),
        'conditional':
            operation.extended_attributes.get('Conditional', None),
        'unsupported':
            'NotSupported' in operation.extended_attributes,
    }

    context.update(self.partial_context(interface, operation))
    return context

  def stringifier_context(self, interface):
    """Create template values for generating stringifier."""
    if not interface.stringifier:
      return None
    if interface.stringifier.attribute:
      cobalt_name = convert_to_cobalt_name(interface.stringifier.attribute.name)
    elif interface.stringifier.operation:
      cobalt_name = capitalize_function_name(
          interface.stringifier.operation.name)
    else:
      cobalt_name = 'AnonymousStringifier'
    return {
        'name': cobalt_name,
    }

  def special_method_context(self, interface, operation):
    """Create template values for getter and setter bindings."""
    if not operation or not operation.specials:
      return None

    assert operation.arguments
    is_indexed = str(operation.arguments[0].idl_type) == 'unsigned long'
    is_named = str(operation.arguments[0].idl_type) == 'DOMString'

    assert len(operation.specials) == 1
    special_type = operation.specials[0]
    assert special_type in ('getter', 'setter', 'deleter')

    function_suffix = {
        'getter': 'Getter',
        'setter': 'Setter',
        'deleter': 'Deleter',
    }

    if operation.name:
      cobalt_name = capitalize_function_name(operation.name)
    elif is_indexed:
      cobalt_name = 'AnonymousIndexed%s' % function_suffix[special_type]
    else:
      assert is_named
      cobalt_name = 'AnonymousNamed%s' % function_suffix[special_type]

    context = {
        'name':
            cobalt_name,
        'raises_exception':
            operation.extended_attributes.has_key('RaisesException'),
    }

    if special_type in ('getter', 'deleter'):
      context['type'] = self.typed_object_to_cobalt_type(interface, operation)
    else:
      value_argument = operation.arguments[1]
      context['type'] = self.typed_object_to_cobalt_type(
          interface, value_argument)
      context['conversion_flags'] = get_conversion_flags(
          self.resolve_typedef(value_argument.idl_type),
          value_argument.extended_attributes)

    return context

  def attribute_context(self, interface, attribute, definitions):
    """Create template values for attribute bindings."""
    cobalt_name = attribute.extended_attributes.get(
        'ImplementedAs', convert_to_cobalt_name(attribute.name))
    context = {
        'idl_name':
            attribute.name,
        'getter_function_name':
            cobalt_name,
        'setter_function_name':
            'set_' + cobalt_name,
        'type':
            self.typed_object_to_cobalt_type(interface, attribute),
        'is_static':
            attribute.is_static,
        'is_read_only':
            attribute.is_read_only,
        'call_with':
            attribute.extended_attributes.get('CallWith', None),
        'raises_exception':
            attribute.extended_attributes.has_key('RaisesException'),
        'conversion_flags':
            get_conversion_flags(
                self.resolve_typedef(attribute.idl_type),
                attribute.extended_attributes),
        'conditional':
            attribute.extended_attributes.get('Conditional', None),
        'unsupported':
            'NotSupported' in attribute.extended_attributes,
    }
    forwarded_attribute_name = attribute.extended_attributes.get('PutForwards')
    if forwarded_attribute_name:
      assert attribute.idl_type.is_interface_type, (
          'PutForwards must be declared on a property of interface type.')
      assert attribute.is_read_only, (
          'PutForwards must be on a readonly attribute.')
      forwarded_interface = definitions.interfaces[get_interface_name(
          attribute.idl_type)]
      matching_attributes = [
          a for a in forwarded_interface.attributes
          if a.name == forwarded_attribute_name
      ]
      assert len(matching_attributes) == 1
      context['put_forwards'] = self.attribute_context(
          forwarded_interface, matching_attributes[0], definitions)
    context[
        'has_setter'] = not attribute.is_read_only or forwarded_attribute_name
    if is_constructor_attribute(attribute):
      context['is_constructor_attribute'] = True
      context['interface_name'] = get_interface_name(attribute.idl_type)
      # Blink's IDL parser uses the convention that attributes ending with
      # 'ConstructorConstructor' are for Named Constructors.
      context['is_named_constructor_attribute'] = (
          attribute.idl_type.name.endswith('ConstructorConstructor'))
    return context

  def enumeration_context(self, enumeration):
    """Create template values for IDL enumeration type bindings."""
    return {
        'enumeration_name':
            enumeration.name,
        'value_pairs': [(convert_to_cobalt_enumeration_value(
            enumeration.name, value), value,) for value in enumeration.values],
    }

  def constant_context(self, constant):
    """Create template values for IDL constant bindings."""
    assert constant.idl_type.is_primitive_type, ('Only primitive types can be '
                                                 'declared as constants.')
    return {
        'name': convert_to_cobalt_constant_name(constant.name),
        'idl_name': constant.name,
        'value': constant.value,
        'can_use_compile_assert': constant.idl_type.is_integer_type,
        'unsupported': 'NotSupported' in constant.extended_attributes,
    }

  def get_method_contexts(self, expression_generator, interface):
    """Return a list of overload contexts for generating method bindings.

    The 'overloads' key of the overload_contexts will be the list of
    method_contexts that are overloaded to this name. In the case that
    a function is not overloaded, the length of this list will be one.

    Arguments:
        expression_generator: An ExpressionGenerator object.
        interface: an IdlInterface object
    Returns:
        [overload_contexts]
    """

    # Get the method contexts for all operations.
    methods = [
        self.method_context(interface, operation)
        for operation in interface.operations if operation.name
    ]

    # Create overload sets for static and non-static methods seperately.
    # Each item in the list is a pair of (name, [method_contexts]) where for
    # each method_context m in the list, m['name'] == name.
    static_method_overloads = method_overloads_by_name(
        [m for m in methods if m['is_static']])
    non_static_method_overloads = method_overloads_by_name(
        [m for m in methods if not m['is_static']])
    static_overload_contexts = get_overload_contexts(expression_generator, [
        contexts for _, contexts in static_method_overloads
    ])
    non_static_overload_contexts = get_overload_contexts(
        expression_generator,
        [contexts for _, contexts in non_static_method_overloads])

    # Set is_static on each of these appropriately.
    for context in static_overload_contexts:
      context['is_static'] = True
    for context in non_static_overload_contexts:
      context['is_static'] = False

    # Append the lists and add the idl_name of the operation to the
    # top-level overload context.
    overload_contexts = static_overload_contexts + non_static_overload_contexts
    for context in overload_contexts:
      context['idl_name'] = context['overloads'][0]['idl_name']
      context['conditional'] = context['overloads'][0]['conditional']
      context['unsupported'] = context['overloads'][0]['unsupported']
      for overload in context['overloads']:
        assert context['conditional'] == overload['conditional'], (
            'All overloads must have the same conditional.')
      for overload in context['overloads']:
        assert context['unsupported'] == overload['unsupported'], (
            'All overloads must have the value for NotSupported.')

    return overload_contexts

  def get_constructor_context(self, expression_generator, interface):
    """Return an overload_context for generating constructor bindings.

    The 'overloads' key for the overloads_context will be a list of
    constructor_contexts representing all constructor overloads. In the
    case that the constructor is not overloaded, the length of this list
    will be one.
    The overload_context also has a 'length' key which can be used to
    specify the 'length' property for the constructor.

    Arguments:
        expression_generator: An ExpressionGenerator object.
        interface: An IdlInterface object.
    Returns:
        overload_context
    """

    constructors = [
        self.constructor_context(interface, constructor)
        for constructor in interface.constructors
    ]
    if not constructors:
      return None
    else:
      overload_contexts = get_overload_contexts(expression_generator,
                                                [constructors])
      assert len(overload_contexts) == 1, (
          'Expected exactly one overload context for constructor.')
      return overload_contexts[0]

  def get_dictionary_member_context(self, dictionary, dictionary_member):
    """Returns a jinja context for a dictionary member.

    Arguments:
        dictionary: An IdlDictionary object
        dictionary_member: An IdlDictionaryMember object.
    Returns:
      dictionary_member_context (dict)
    """
    return {
        'idl_type_object':
            dictionary_member.idl_type,
        'name':
            convert_to_cobalt_name(dictionary_member.name),
        'is_script_value':
            is_any_type(dictionary_member.idl_type),
        'idl_name':
            dictionary_member.name,
        'type':
            self.typed_object_to_cobalt_type(dictionary, dictionary_member),
        'arg_type':
            self.typed_object_to_arg_type(dictionary, dictionary_member),
        'conversion_flags':
            get_conversion_flags(
                self.resolve_typedef(dictionary_member.idl_type),
                dictionary_member.extended_attributes),
        'default_value':
            get_dictionary_default_value(dictionary_member.idl_type,
                                         dictionary_member.default_value,
                                         dictionary_member.name)
            if dictionary_member.default_value else None,
    }
