# 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,protected-access

"""Unit tests for code_generator_web_agent_api.py."""

import unittest

from .code_generator_web_agent_api import InterfaceContextBuilder
from .code_generator_web_agent_api import MethodOverloadSplitter
from .code_generator_web_agent_api import STRING_INCLUDE_PATH
from .code_generator_web_agent_api import TypeResolver
from .idl_definitions import IdlArgument
from .idl_definitions import IdlAttribute
from .idl_definitions import IdlOperation
from .idl_types import IdlType
from .idl_types import IdlNullableType
from .idl_types import IdlUnionType
from .idl_types import PRIMITIVE_TYPES
from .idl_types import STRING_TYPES


# TODO(dglazkov): Convert to use actual objects, not stubs.
# See http://crbug.com/673214 for more details.
class IdlTestingHelper(object):
    """A collection of stub makers and helper utils to make testing code
    generation easy."""

    def make_stub_idl_argument(self, name, idl_type, is_optional=False):
        idl_argument = IdlArgument()
        idl_argument.name = name
        idl_argument.idl_type = idl_type
        idl_argument.is_optional = is_optional
        return idl_argument

    def make_stub_idl_attribute(self, name, return_type):
        idl_attribute_stub = IdlAttribute()
        idl_attribute_stub.name = name
        idl_attribute_stub.idl_type = IdlType(return_type)
        return idl_attribute_stub

    def make_stub_idl_operation(self, name, return_type):
        idl_operation_stub = IdlOperation()
        idl_operation_stub.name = name
        idl_operation_stub.idl_type = IdlType(return_type)
        return idl_operation_stub

    def make_stub_idl_type(self, base_type):
        return IdlType(base_type)

    def make_stub_interfaces_info(self, classes_to_paths):
        result = {}
        for class_name, path in classes_to_paths.items():
            result[class_name] = {'include_path': path}
        return result


class TypeResolverTest(unittest.TestCase):

    def test_includes_from_type_should_filter_primitive_types(self):
        helper = IdlTestingHelper()
        type_resolver = TypeResolver({})
        for primitive_type in PRIMITIVE_TYPES:
            idl_type = helper.make_stub_idl_type(primitive_type)
            self.assertEqual(
                type_resolver._includes_from_type(idl_type), set())

    def test_includes_from_type_should_filter_void(self):
        type_resolver = TypeResolver({})
        helper = IdlTestingHelper()
        idl_type = helper.make_stub_idl_type('void')
        self.assertEqual(
            type_resolver._includes_from_type(idl_type), set())

    def test_includes_from_type_should_handle_string(self):
        type_resolver = TypeResolver({})
        helper = IdlTestingHelper()
        for string_type in STRING_TYPES:
            idl_type = helper.make_stub_idl_type(string_type)
            self.assertEqual(
                type_resolver._includes_from_type(idl_type),
                set([STRING_INCLUDE_PATH]))


class MethodOverloadSplitterTest(unittest.TestCase):

    def test_enumerate_argument_types(self):
        splitter = MethodOverloadSplitter(IdlOperation())
        nullable_and_primitive = IdlArgument()
        nullable_and_primitive.idl_type = IdlNullableType(IdlType('double'))
        with self.assertRaises(ValueError):
            splitter._enumerate_argument_types(nullable_and_primitive)

        argument = IdlArgument()
        foo_type = IdlType('Foo')
        bar_type = IdlType('Bar')

        argument.idl_type = foo_type
        self.assertEqual(
            splitter._enumerate_argument_types(argument), [foo_type])

        argument.is_optional = True
        self.assertEqual(
            splitter._enumerate_argument_types(argument), [None, foo_type])

        argument.is_optional = False
        argument.idl_type = IdlUnionType([foo_type, bar_type])
        self.assertEqual(
            splitter._enumerate_argument_types(argument), [foo_type, bar_type])

        argument.is_optional = True
        self.assertEqual(
            splitter._enumerate_argument_types(argument),
            [None, foo_type, bar_type])

    def test_update_argument_lists(self):
        splitter = MethodOverloadSplitter(IdlOperation())
        foo_type = IdlType('Foo')
        bar_type = IdlType('Bar')
        baz_type = IdlType('Baz')
        qux_type = IdlType('Qux')

        result = splitter._update_argument_lists([[]], [foo_type])
        self.assertEqual(result, [[foo_type]])

        result = splitter._update_argument_lists([[]], [foo_type, bar_type])
        self.assertEqual(result, [[foo_type], [bar_type]])

        existing_list = [[foo_type]]
        result = splitter._update_argument_lists(existing_list, [bar_type])
        self.assertEqual(result, [[foo_type, bar_type]])

        existing_list = [[foo_type]]
        result = splitter._update_argument_lists(existing_list,
                                                 [None, bar_type])
        self.assertEqual(result, [[foo_type], [foo_type, bar_type]])

        existing_list = [[foo_type]]
        result = splitter._update_argument_lists(existing_list,
                                                 [bar_type, baz_type])
        self.assertEqual(result, [[foo_type, bar_type], [foo_type, baz_type]])

        existing_list = [[foo_type], [qux_type]]
        result = splitter._update_argument_lists(existing_list,
                                                 [bar_type, baz_type])
        self.assertEqual(result, [
            [foo_type, bar_type],
            [foo_type, baz_type],
            [qux_type, bar_type],
            [qux_type, baz_type],
        ])

        existing_list = [[foo_type], [qux_type]]
        result = splitter._update_argument_lists(existing_list,
                                                 [None, bar_type, baz_type])
        self.assertEqual(result, [
            [foo_type],
            [foo_type, bar_type],
            [foo_type, baz_type],
            [qux_type],
            [qux_type, bar_type],
            [qux_type, baz_type],
        ])

        existing_list = [[foo_type, qux_type]]
        result = splitter._update_argument_lists(existing_list,
                                                 [bar_type, baz_type])
        self.assertEqual(result, [
            [foo_type, qux_type, bar_type],
            [foo_type, qux_type, baz_type],
        ])

    def test_split_into_overloads(self):
        helper = IdlTestingHelper()
        type_double = IdlType('double')
        type_foo = IdlType('foo')
        type_double_or_foo = IdlUnionType([type_double, type_foo])
        idl_operation = IdlOperation()

        idl_operation.arguments = []
        splitter = MethodOverloadSplitter(idl_operation)
        result = splitter.split_into_overloads()
        self.assertEqual(result, [[]])

        idl_operation.arguments = [
            helper.make_stub_idl_argument(None, type_double, True)
        ]
        splitter = MethodOverloadSplitter(idl_operation)
        result = splitter.split_into_overloads()
        self.assertEqual(result, [[], [type_double]])

        idl_operation.arguments = [
            helper.make_stub_idl_argument(None, type_double_or_foo)
        ]
        splitter = MethodOverloadSplitter(idl_operation)
        result = splitter.split_into_overloads()
        self.assertEqual(result, [[type_double], [type_foo]])

    def test_split_add_event_listener(self):
        """Tests how EventTarget.addEventListener is split into respective
           overloads. From:

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

           produces: """

        helper = IdlTestingHelper()
        type_dom_string = IdlType('DOMString')
        type_listener = IdlType('EventListener')
        type_options = IdlType('AddEventListenerOptions')
        type_boolean = IdlType('boolean')
        type_union = IdlUnionType([type_options, type_boolean])
        idl_operation = IdlOperation()
        idl_operation.arguments = [
            helper.make_stub_idl_argument('type', type_dom_string),
            helper.make_stub_idl_argument('listener', type_listener),
            helper.make_stub_idl_argument('options', type_union,
                                          is_optional=True)]
        splitter = MethodOverloadSplitter(idl_operation)
        result = splitter.split_into_overloads()
        self.assertEqual(
            result,
            [[type_dom_string, type_listener],
             [type_dom_string, type_listener, type_options],
             [type_dom_string, type_listener, type_boolean]])


class InterfaceContextBuilderTest(unittest.TestCase):

    def test_empty(self):
        builder = InterfaceContextBuilder('test', TypeResolver({}))

        self.assertEqual({'code_generator': 'test'}, builder.build())

    def test_set_name(self):
        helper = IdlTestingHelper()
        builder = InterfaceContextBuilder(
            'test', TypeResolver(helper.make_stub_interfaces_info({
                'foo': 'path_to_foo',
            })))

        builder.set_class_name('foo')
        self.assertEqual({
            'code_generator': 'test',
            'cpp_includes': set(['path_to_foo']),
            'class_name': {
                'snake_case': 'foo',
                'macro_case': 'FOO',
                'upper_camel_case': 'Foo'
            },
        }, builder.build())

    def test_set_inheritance(self):
        helper = IdlTestingHelper()
        builder = InterfaceContextBuilder(
            'test', TypeResolver(helper.make_stub_interfaces_info({
                'foo': 'path_to_foo',
            })))
        builder.set_inheritance('foo')
        self.assertEqual({
            'base_class': 'foo',
            'code_generator': 'test',
            'header_includes': set(['path_to_foo']),
        }, builder.build())

        builder = InterfaceContextBuilder('test', TypeResolver({}))
        builder.set_inheritance(None)
        self.assertEqual({
            'code_generator': 'test',
            'header_includes': set(['platform/heap/Handle.h']),
        }, builder.build())

    def test_add_attribute(self):
        helper = IdlTestingHelper()
        builder = InterfaceContextBuilder(
            'test', TypeResolver(helper.make_stub_interfaces_info({
                'foo': 'path_to_foo',
                'bar': 'path_to_bar'
            })))

        attribute = helper.make_stub_idl_attribute('foo', 'bar')
        builder.add_attribute(attribute)
        self.assertEqual({
            'code_generator': 'test',
            'cpp_includes': set(['path_to_bar']),
            'attributes': [{'name': 'foo', 'type': 'bar'}],
        }, builder.build())

    def test_add_method(self):
        helper = IdlTestingHelper()
        builder = InterfaceContextBuilder(
            'test', TypeResolver(helper.make_stub_interfaces_info({
                'foo': 'path_to_foo',
                'bar': 'path_to_bar',
                'garply': 'path_to_garply',
            })))

        operation = helper.make_stub_idl_operation('foo', 'bar')
        builder.add_operation(operation)
        self.assertEqual({
            'code_generator': 'test',
            'cpp_includes': set(['path_to_bar']),
            'methods': [{
                'arguments': [],
                'name': 'Foo',
                'type': 'bar'
            }],
        }, builder.build())

        operation = helper.make_stub_idl_operation('quux', 'garply')
        operation.arguments = [
            helper.make_stub_idl_argument('barBaz', IdlType('qux'))
        ]
        builder.add_operation(operation)
        self.assertEqual({
            'code_generator': 'test',
            'cpp_includes': set(['path_to_bar', 'path_to_garply']),
            'methods': [
                {
                    'arguments': [],
                    'name': 'Foo',
                    'type': 'bar'
                },
                {
                    'arguments': [
                        {'name': 'bar_baz', 'type': 'qux'}
                    ],
                    'name': 'Quux',
                    'type': 'garply'
                }
            ],
        }, builder.build())
