#!/usr/bin/python
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""This module generates Dart APIs from the IDL database."""

import emitter
import idlnode
import logging
import os
import re
import shutil
from generator import *
from idlnode import IDLType, IDLInterface, resolveTypedef

_logger = logging.getLogger('dartgenerator')

def MergeNodes(node, other):
  node.operations.extend(other.operations)
  for attribute in other.attributes:
    if not node.has_attribute(attribute):
      node.attributes.append(attribute)

  node.constants.extend(other.constants)

class DartGenerator(object):
  """Utilities to generate Dart APIs and corresponding JavaScript."""

  def __init__(self, logging_level=logging.WARNING):
    self._auxiliary_files = {}
    self._dart_templates_re = re.compile(r'[\w.:]+<([\w \.<>:]+)>')
    _logger.setLevel(logging_level)

  def _StripModules(self, type_name):
    return type_name.split('::')[-1]

  def _IsCompoundType(self, database, type_name):
    if IsRegisteredType(type_name):
      return True

    # References a typedef - normally a union type.
    if database.HasTypeDef(type_name):
      return True

    if type_name.endswith('?'):
      return self._IsCompoundType(database, type_name[:-len('?')])

    if type_name.endswith('[]'):
      return self._IsCompoundType(database, type_name[:-len('[]')])

    stripped_type_name = self._StripModules(type_name)
    if (database.HasInterface(stripped_type_name) or
        database.HasDictionary(stripped_type_name)):
      return True

    if database.HasEnum(stripped_type_name):
      return True

    dart_template_match = self._dart_templates_re.match(type_name)
    if dart_template_match:
      # Dart templates
      parent_type_name = type_name[0 : dart_template_match.start(1) - 1]
      sub_type_name = dart_template_match.group(1)
      return (self._IsCompoundType(database, parent_type_name) and
              self._IsCompoundType(database, sub_type_name))
    return False

  def _IsDartType(self, type_name):
    return '.' in type_name

  def LoadAuxiliary(self, auxiliary_dir):
    def Visitor(_, dirname, names):
      for name in names:
        if name.endswith('.dart'):
          name = name[0:-5]  # strip off ".dart"
        self._auxiliary_files[name] = os.path.join(dirname, name)
    os.path.walk(auxiliary_dir, Visitor, None)

  def FilterMembersWithUnidentifiedTypes(self, database):
    """Removes unidentified types.

    Removes constants, attributes, operations and parents with unidentified
    types.
    """

    for interface in database.GetInterfaces():
      def IsIdentified(idl_node):
        node_name = idl_node.id if idl_node.id else 'parent'
        for idl_type in idl_node.all(idlnode.IDLType):
          type_name = idl_type.id
          if (type_name is not None and
              self._IsCompoundType(database, type_name)):
            continue
          # Ignore constructor warnings.
          if not (interface.id in ['Window', 'WorkerContext',
              'WorkerGlobalScope'] and
              type_name.endswith('Constructor')):
            _logger.warn('removing %s in %s which has unidentified type %s' %
                       (node_name, interface.id, type_name))
          return False
        return True

      interface.constants = filter(IsIdentified, interface.constants)
      interface.attributes = filter(IsIdentified, interface.attributes)
      interface.operations = filter(IsIdentified, interface.operations)
      interface.parents = filter(IsIdentified, interface.parents)

  def FilterInterfaces(self, database,
                       and_annotations=[],
                       or_annotations=[],
                       exclude_displaced=[],
                       exclude_suppressed=[]):
    """Filters a database to remove interfaces and members that are missing
    annotations.

    The FremontCut IDLs use annotations to specify implementation
    status in various platforms. For example, if a member is annotated
    with @WebKit, this means that the member is supported by WebKit.

    Args:
      database -- the database to filter
      all_annotations -- a list of annotation names a member has to
        have or it will be filtered.
      or_annotations -- if a member has one of these annotations, it
        won't be filtered even if it is missing some of the
        all_annotations.
      exclude_displaced -- if a member has this annotation and it
        is marked as displaced it will always be filtered.
      exclude_suppressed -- if a member has this annotation and it
        is marked as suppressed it will always be filtered.
    """

    # Filter interfaces and members whose annotations don't match.
    for interface in database.GetInterfaces():
      def HasAnnotations(idl_node):
        """Utility for determining if an IDLNode has all
        the required annotations"""
        for a in exclude_displaced:
          if (a in idl_node.annotations
              and 'via' in idl_node.annotations[a]):
            return False
        for a in exclude_suppressed:
          if (a in idl_node.annotations
              and 'suppressed' in idl_node.annotations[a]):
            return False
        for a in or_annotations:
          if a in idl_node.annotations:
            return True
        if and_annotations == []:
          return False
        for a in and_annotations:
          if a not in idl_node.annotations:
            return False
        return True

      if HasAnnotations(interface):
        interface.constants = filter(HasAnnotations, interface.constants)
        interface.attributes = filter(HasAnnotations, interface.attributes)
        interface.operations = filter(HasAnnotations, interface.operations)
        interface.parents = filter(HasAnnotations, interface.parents)
      else:
        database.DeleteInterface(interface.id)

    self.FilterMembersWithUnidentifiedTypes(database)

  def Generate(self, database, super_database, generate_interface):
    self._database = database

    # Collect interfaces
    interfaces = []
    for interface in database.GetInterfaces():
      if not MatchSourceFilter(interface):
        # Skip this interface since it's not present in the required source
        _logger.info('Omitting interface - %s' % interface.id)
        continue
      interfaces.append(interface)

    # All web_gl constants from WebGLRenderingContextBase, WebGL2RenderingContextBase, WebGLDrawBuffers are generated
    # in a synthesized class WebGL.  Those IDLConstants are in web_gl_constants.
    web_gl_constants = []

    # Render all interfaces into Dart and save them in files.
    for interface in self._PreOrderInterfaces(interfaces):
      interface_name = interface.id
      auxiliary_file = self._auxiliary_files.get(interface_name)
      if auxiliary_file is not None:
        _logger.info('Skipping %s because %s exists' % (
            interface_name, auxiliary_file))
        continue

      _logger.info('Generating %s' % interface.id)
      generate_interface(interface, gl_constants = web_gl_constants)

    # Generate the WEB_GL constants
    web_gl_constants_interface = IDLInterface(None, "WebGL")
    web_gl_constants_interface.constants = web_gl_constants
    self._database._all_interfaces['WebGL'] = web_gl_constants_interface
    generate_interface(web_gl_constants_interface)

  def _PreOrderInterfaces(self, interfaces):
    """Returns the interfaces in pre-order, i.e. parents first."""
    seen = set()
    ordered = []
    def visit(interface):
      if interface.id in seen:
        return
      seen.add(interface.id)
      for parent in interface.parents:
        if IsDartCollectionType(parent.type.id):
          continue
        if self._database.HasInterface(parent.type.id):
          parent_interface = self._database.GetInterface(parent.type.id)
          visit(parent_interface)
      ordered.append(interface)

    for interface in interfaces:
      visit(interface)
    return ordered

  def IsEventTarget(self, database, interface):
    if interface.id == 'EventTarget':
      return True
    for parent in interface.parents:
      parent_name = parent.type.id
      if database.HasInterface(parent_name):
        parent_interface = database.GetInterface(parent.type.id)
        if self.IsEventTarget(database, parent_interface):
          return True
    return False

  def FixEventTargets(self, database):
    for interface in database.GetInterfaces():
      if self.IsEventTarget(database, interface):
        # Add as an attribute for easy querying in generation code.
        interface.ext_attrs['EventTarget'] = None
      elif 'EventTarget' in interface.ext_attrs:
        # Create fake EventTarget parent interface for interfaces that have
        # 'EventTarget' extended attribute.
        ast = [('Annotation', [('Id', 'WebKit')]),
               ('InterfaceType', ('ScopedName', 'EventTarget'))]
        interface.parents.append(idlnode.IDLParentInterface(ast))

  def AddMissingArguments(self, database):
    ARG = idlnode.IDLArgument([('Type', ('ScopedName', 'object')), ('Id', 'arg')])
    for interface in database.GetInterfaces():
      for operation in interface.operations:
        call_with = operation.ext_attrs.get('CallWith', [])
        if not(isinstance(call_with, list)):
          call_with = [call_with]
        constructor_with = operation.ext_attrs.get('ConstructorCallWith', [])
        if not(isinstance(constructor_with, list)):
          constructor_with = [constructor_with]
        call_with = call_with + constructor_with

        if 'ScriptArguments' in call_with:
          operation.arguments.append(ARG)

  def CleanupOperationArguments(self, database):
    for interface in database.GetInterfaces():
      for operation in interface.operations:
        # TODO(terry): Hack to remove 3rd arguments in setInterval/setTimeout.
        if ((operation.id == 'setInterval' or operation.id == 'setTimeout') and \
            operation.arguments[0].type.id == 'any'):
          operation.arguments.pop(2)

        # Massage any operation argument type that is IDLEnum to String.
        for index, argument in enumerate(operation.arguments):
          type_name = argument.type.id
          if database.HasEnum(type_name):
            operation.arguments[index].type = IDLType('DOMString')

