#!/usr/bin/env python3
# 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')
