# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# pylint: disable=import-error,print-statement,relative-import

"""Generates Web Agent API bindings.

The Web Agent API bindings provide a stable, IDL-generated interface for the
Web Agents.

The Web Agents are the high-level services like Autofill,
Autocomplete, Translate, Distiller, Phishing Detector, and others. Web Agents
typically want to introspec the document and rendering infromation to implement
browser features.

The bindings are meant to be as simple and as ephemeral as possible, mostly just
wrapping existing DOM classes. Their primary goal is to avoid leaking the actual
DOM classes to the Web Agents layer.
"""

import os
import posixpath
import sys

from .code_generator import CodeGeneratorBase, render_template
# TODO(dglazkov): Move TypedefResolver to code_generator.py
from .code_generator_v8 import TypedefResolver

sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..',
                             'third_party', 'blink', 'tools'))
from blinkpy.common.name_style_converter import NameStyleConverter

MODULE_PYNAME = os.path.splitext(os.path.basename(__file__))[0] + '.py'

STRING_INCLUDE_PATH = 'platform/wtf/text/WTFString.h'
WEB_AGENT_API_IDL_ATTRIBUTE = 'WebAgentAPI'


def interface_context(idl_interface, type_resolver):
    builder = InterfaceContextBuilder(MODULE_PYNAME, type_resolver)
    builder.set_class_name(idl_interface.name)
    builder.set_inheritance(idl_interface.parent)

    for idl_attribute in idl_interface.attributes:
        builder.add_attribute(idl_attribute)

    for idl_operation in idl_interface.operations:
        builder.add_operation(idl_operation)

    return builder.build()


class TypeResolver(object):
    """Resolves Web IDL types into corresponding C++ types and include paths
       to the generated and existing files."""

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

    def includes_from_interface(self, interface_name):
        interface_info = self.interfaces_info.get(interface_name)
        if interface_info is None:
            raise KeyError('Unknown interface "%s".' % interface_name)
        return set([interface_info['include_path']])

    def _includes_from_type(self, idl_type):
        if idl_type.is_void:
            return set()
        if idl_type.is_primitive_type:
            return set()
        if idl_type.is_string_type:
            return set([STRING_INCLUDE_PATH])

        # TODO(dglazkov): Handle complex/weird types.
        return self.includes_from_interface(idl_type.base_type)

    def includes_from_definition(self, idl_definition):
        return self._includes_from_type(idl_definition.idl_type)

    def type_from_definition(self, idl_definition):
        # TODO(dglazkov): The output of this method must be a reasonable C++
        # type that can be used directly in the jinja2 template.
        return idl_definition.idl_type.base_type

    def base_class_includes(self):
        return set(['platform/heap/Handle.h'])


class MethodOverloadSplitter(object):
    """Because of union and optional types being used as arguments, some
       operations may result in more than one generated method. This class
       contains the logic for spliting an operation into multiple C++ overloads.
    """

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

    def _update_argument_lists(self, argument_lists, idl_types):
        """Given a list of IdlTypes and an existing list of argument lists (yes,
           this is a list of lists), produces a next generation of the list of
           lists. This is where the actual splitting into overloads happens.
        """
        result = []
        for argument_list in argument_lists:
            for idl_type in idl_types:
                new_argument_list = list(argument_list)
                if idl_type is not None:
                    new_argument_list.append(idl_type)
                result.append(new_argument_list)
        return result

    def _enumerate_argument_types(self, idl_argument):
        """Given an IdlArgument, returns a list of types that are included
           in this argument. If optional, the list will include a 'None'."""
        argument_type = idl_argument.idl_type
        # TODO(dglazkov): What should we do with primitive nullable args?
        if (argument_type.is_nullable and
                argument_type.inner_type.is_primitive_type):
            raise ValueError('Primitive nullable types are not supported.')

        idl_types = []
        if idl_argument.is_optional:
            idl_types.append(None)  # None is used to convey optionality.
        if argument_type.is_union_type:
            idl_types = idl_types + argument_type.member_types
        else:
            idl_types.append(argument_type)
        return idl_types

    def split_into_overloads(self):
        """Splits an operation into one or more overloads that correctly reflect
           the WebIDL semantics of the operation arguments. For example,
           running this method on an IdlOperation that represents this WebIDL
           definition:

           void addEventListener(
                DOMString type,
                EventListener? listener,
                optional (AddEventListenerOptions or boolean) options)

            will produce a list of 3 argument lists:

            1) [DOMString, EventListener], since the third argument is optional,
            2) [DOMString, EventListener, AddEventListenerOptions], since the
               third argument is a union type with AddEventListenerOptions as
               one of its member types, and
            3) [DOMString, EventListener, boolean], since the other union member
               type of the third argument is boolean.

            This example is also captured as test in
            MethodOverloadSplitterTest.test_split_add_event_listener.
        """

        argument_lists = [[]]
        for idl_argument in self.idl_operation.arguments:
            idl_types = self._enumerate_argument_types(idl_argument)
            argument_lists = self._update_argument_lists(argument_lists,
                                                         idl_types)
        return argument_lists


class InterfaceContextBuilder(object):
    def __init__(self, code_generator, type_resolver):
        self.result = {'code_generator': code_generator}
        self.type_resolver = type_resolver

    def set_class_name(self, class_name):
        converter = NameStyleConverter(class_name)
        self.result['class_name'] = converter.to_all_cases()
        self._ensure_set('cpp_includes').update(
            self.type_resolver.includes_from_interface(class_name))

    def set_inheritance(self, base_interface):
        if base_interface is None:
            self._ensure_set('header_includes').update(
                self.type_resolver.base_class_includes())
            return
        self.result['base_class'] = base_interface
        self._ensure_set('header_includes').update(
            self.type_resolver.includes_from_interface(base_interface))

    def _ensure_set(self, name):
        return self.result.setdefault(name, set())

    def _ensure_list(self, name):
        return self.result.setdefault(name, [])

    def add_attribute(self, idl_attribute):
        self._ensure_list('attributes').append(
            self.create_attribute(idl_attribute))
        self._ensure_set('cpp_includes').update(
            self.type_resolver.includes_from_definition(idl_attribute))

    def add_operation(self, idl_operation):
        if not idl_operation.name:
            return
        overload_splitter = MethodOverloadSplitter(idl_operation)
        overloads = overload_splitter.split_into_overloads()
        argument_names = [argument.name for argument
                          in idl_operation.arguments]
        for argument_types in overloads:
            arguments = []
            for position, argument_type in enumerate(argument_types):
                arguments.append(
                    self.create_argument(argument_names[position],
                                         argument_type))
            self._ensure_list('methods').append(
                self.create_method(idl_operation, arguments))
            self._ensure_set('cpp_includes').update(
                self.type_resolver.includes_from_definition(idl_operation))

    def create_argument(self, argument_name, argument_type):
        name_converter = NameStyleConverter(argument_name)
        return {
            'name': name_converter.to_snake_case(),
            'type': argument_type.base_type,
        }

    def create_method(self, idl_operation, arguments):
        name_converter = NameStyleConverter(idl_operation.name)
        return_type = self.type_resolver.type_from_definition(idl_operation)
        return {
            'name': name_converter.to_upper_camel_case(),
            'type': return_type,
            'arguments': arguments
        }

    def create_attribute(self, idl_attribute):
        name = idl_attribute.name
        return_type = self.type_resolver.type_from_definition(idl_attribute)
        return {
            'name': name,
            'type': return_type
        }

    def build(self):
        return self.result


class CodeGeneratorWebAgentAPI(CodeGeneratorBase):
    def __init__(self, info_provider, cache_dir, output_dir, snake_case):
        CodeGeneratorBase.__init__(self, MODULE_PYNAME, info_provider,
                                   cache_dir, output_dir, snake_case)
        self.type_resolver = TypeResolver(info_provider.interfaces_info)
        self.typedef_resolver = TypedefResolver(info_provider)

    def get_template(self, file_extension):
        template_filename = 'web_agent_api_interface.%s.tmpl' % file_extension
        return self.jinja_env.get_template(template_filename)

    def generate_file(self, template_context, file_extension):
        template = self.get_template(file_extension)
        path = posixpath.join(
            self.output_dir,
            '%s.%s' % (template_context['class_name']['snake_case'],
                       file_extension))
        text = render_template(template, template_context)
        return (path, text)

    def generate_interface_code(self, interface):
        # TODO(dglazkov): Implement callback interfaces.
        # TODO(dglazkov): Make sure partial interfaces are handled.
        if interface.is_callback or interface.is_partial:
            raise ValueError('Partial or callback interfaces are not supported')

        template_context = interface_context(interface, self.type_resolver)

        return (
            self.generate_file(template_context, 'h'),
            self.generate_file(template_context, 'cc')
        )

    def generate_code(self, definitions, definition_name):
        self.typedef_resolver.resolve(definitions, definition_name)

        # TODO(dglazkov): Implement dictionaries
        if definition_name not in definitions.interfaces:
            return None

        interface = definitions.interfaces[definition_name]
        if WEB_AGENT_API_IDL_ATTRIBUTE not in interface.extended_attributes:
            return None

        return self.generate_interface_code(interface)
