# Copyright (C) 2013 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Generate template values for methods.

Extends IdlArgument with property |default_cpp_value|.
Extends IdlTypeBase and IdlUnionType with property |union_arguments|.

Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
"""

from idl_definitions import IdlArgument, IdlOperation
from idl_types import IdlTypeBase, IdlUnionType, inherits_interface
from v8_globals import includes
import v8_types
import v8_utilities
from v8_utilities import (has_extended_attribute_value, is_unforgeable,
                          is_legacy_interface_type_checking)


# Methods with any of these require custom method registration code in the
# interface's configure*Template() function.
CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES = frozenset([
    'DoNotCheckSecurity',
    'DoNotCheckSignature',
])


def use_local_result(method):
    extended_attributes = method.extended_attributes
    idl_type = method.idl_type
    return (has_extended_attribute_value(method, 'CallWith', 'ScriptState') or
            'ImplementedInPrivateScript' in extended_attributes or
            'RaisesException' in extended_attributes or
            idl_type.is_union_type or
            idl_type.is_explicit_nullable)


def method_context(interface, method, is_visible=True):
    arguments = method.arguments
    extended_attributes = method.extended_attributes
    idl_type = method.idl_type
    is_static = method.is_static
    name = method.name

    if is_visible:
        idl_type.add_includes_for_type(extended_attributes)

    this_cpp_value = cpp_value(interface, method, len(arguments))

    is_implemented_in_private_script = 'ImplementedInPrivateScript' in extended_attributes
    if is_implemented_in_private_script:
        includes.add('bindings/core/v8/PrivateScriptRunner.h')
        includes.add('core/frame/LocalFrame.h')
        includes.add('platform/ScriptForbiddenScope.h')

    # [OnlyExposedToPrivateScript]
    is_only_exposed_to_private_script = 'OnlyExposedToPrivateScript' in extended_attributes

    is_call_with_script_arguments = has_extended_attribute_value(method, 'CallWith', 'ScriptArguments')
    if is_call_with_script_arguments:
        includes.update(['bindings/core/v8/ScriptCallStack.h',
                         'core/inspector/ScriptArguments.h'])
    is_call_with_script_state = has_extended_attribute_value(method, 'CallWith', 'ScriptState')
    is_call_with_this_value = has_extended_attribute_value(method, 'CallWith', 'ThisValue')
    if is_call_with_script_state or is_call_with_this_value:
        includes.add('bindings/core/v8/ScriptState.h')

    # [CheckSecurity]
    is_do_not_check_security = 'DoNotCheckSecurity' in extended_attributes
    is_check_security_for_receiver = (
        has_extended_attribute_value(interface, 'CheckSecurity', 'Receiver') and
        not is_do_not_check_security)
    is_check_security_for_return_value = (
        has_extended_attribute_value(method, 'CheckSecurity', 'ReturnValue'))
    if is_check_security_for_receiver or is_check_security_for_return_value:
        includes.add('bindings/core/v8/BindingSecurity.h')

    is_custom_element_callbacks = 'CustomElementCallbacks' in extended_attributes
    if is_custom_element_callbacks:
        includes.add('core/dom/custom/CustomElementProcessingStack.h')

    is_raises_exception = 'RaisesException' in extended_attributes
    is_custom_call_prologue = has_extended_attribute_value(method, 'Custom', 'CallPrologue')
    is_custom_call_epilogue = has_extended_attribute_value(method, 'Custom', 'CallEpilogue')
    is_post_message = 'PostMessage' in extended_attributes
    if is_post_message:
        includes.add('bindings/core/v8/SerializedScriptValueFactory.h')
        includes.add('core/dom/DOMArrayBuffer.h')
        includes.add('core/dom/MessagePort.h')
        includes.add('core/frame/ImageBitmap.h')

    if 'LenientThis' in extended_attributes:
        raise Exception('[LenientThis] is not supported for operations.')

    if 'RuntimeEnabled' in extended_attributes:
        includes.add('platform/RuntimeEnabledFeatures.h')

    if 'OriginTrialEnabled' in extended_attributes:
        includes.add('core/inspector/ConsoleMessage.h')
        includes.add('core/origin_trials/OriginTrials.h')

    argument_contexts = [
        argument_context(interface, method, argument, index, is_visible=is_visible)
        for index, argument in enumerate(arguments)]

    return {
        'activity_logging_world_list': v8_utilities.activity_logging_world_list(method),  # [ActivityLogging]
        'arguments': argument_contexts,
        'argument_declarations_for_private_script':
            argument_declarations_for_private_script(interface, method),
        'cpp_type': (v8_types.cpp_template_type('Nullable', idl_type.cpp_type)
                     if idl_type.is_explicit_nullable else idl_type.cpp_type),
        'cpp_value': this_cpp_value,
        'cpp_type_initializer': idl_type.cpp_type_initializer,
        'custom_registration_extended_attributes':
            CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES.intersection(
                extended_attributes.iterkeys()),
        'deprecate_as': v8_utilities.deprecate_as(method),  # [DeprecateAs]
        'exposed_test': v8_utilities.exposed(method, interface),  # [Exposed]
        # TODO(yukishiino): Retire has_custom_registration flag.  Should be
        # replaced with V8DOMConfiguration::PropertyLocationConfiguration.
        'has_custom_registration':
            v8_utilities.has_extended_attribute(
                method, CUSTOM_REGISTRATION_EXTENDED_ATTRIBUTES),
        'has_exception_state':
            is_raises_exception or
            is_check_security_for_receiver or
            any(argument for argument in arguments
                if (argument.idl_type.name == 'SerializedScriptValue' or
                    argument_conversion_needs_exception_state(method, argument))),
        'has_optional_argument_without_default_value':
            any(True for argument_context in argument_contexts
                if argument_context['is_optional_without_default_value']),
        'idl_type': idl_type.base_type,
        'is_origin_trial_enabled': v8_utilities.origin_trial_enabled_function(method) or v8_utilities.origin_trial_enabled_function(interface),  # [OriginTrialEnabled]
        'is_call_with_execution_context': has_extended_attribute_value(method, 'CallWith', 'ExecutionContext'),
        'is_call_with_script_arguments': is_call_with_script_arguments,
        'is_call_with_script_state': is_call_with_script_state,
        'is_call_with_this_value': is_call_with_this_value,
        'is_check_security_for_receiver': is_check_security_for_receiver,
        'is_check_security_for_return_value': is_check_security_for_return_value,
        'is_custom': 'Custom' in extended_attributes and
            not (is_custom_call_prologue or is_custom_call_epilogue),
        'is_custom_call_prologue': is_custom_call_prologue,
        'is_custom_call_epilogue': is_custom_call_epilogue,
        'is_custom_element_callbacks': is_custom_element_callbacks,
        'is_do_not_check_security': is_do_not_check_security,
        'is_do_not_check_signature': 'DoNotCheckSignature' in extended_attributes,
        'is_explicit_nullable': idl_type.is_explicit_nullable,
        'is_implemented_in_private_script': is_implemented_in_private_script,
        'is_partial_interface_member':
            'PartialInterfaceImplementedAs' in extended_attributes,
        'is_per_world_bindings': 'PerWorldBindings' in extended_attributes,
        'is_post_message': is_post_message,
        'is_raises_exception': is_raises_exception,
        'is_static': is_static,
        'is_unforgeable': is_unforgeable(interface, method),
        'is_variadic': arguments and arguments[-1].is_variadic,
        'measure_as': v8_utilities.measure_as(method, interface),  # [MeasureAs]
        'name': name,
        'number_of_arguments': len(arguments),
        'number_of_required_arguments': len([
            argument for argument in arguments
            if not (argument.is_optional or argument.is_variadic)]),
        'number_of_required_or_variadic_arguments': len([
            argument for argument in arguments
            if not argument.is_optional]),
        'on_instance': v8_utilities.on_instance(interface, method),
        'on_interface': v8_utilities.on_interface(interface, method),
        'on_prototype': v8_utilities.on_prototype(interface, method),
        'only_exposed_to_private_script': is_only_exposed_to_private_script,
        'origin_trial_enabled': v8_utilities.origin_trial_enabled_function(method),  # [OriginTrialEnabled]
        'origin_trial_enabled_per_interface': v8_utilities.origin_trial_enabled_function(interface),  # [OriginTrialEnabled]
        'private_script_v8_value_to_local_cpp_value': idl_type.v8_value_to_local_cpp_value(
            extended_attributes, 'v8Value', 'cppValue', isolate='scriptState->isolate()', bailout_return_value='false'),
        'property_attributes': property_attributes(interface, method),
        'returns_promise': method.returns_promise,
        'runtime_enabled_function': v8_utilities.runtime_enabled_function_name(method),  # [RuntimeEnabled]
        'should_be_exposed_to_script': not (is_implemented_in_private_script and is_only_exposed_to_private_script),
        'use_output_parameter_for_result': idl_type.use_output_parameter_for_result,
        'use_local_result': use_local_result(method),
        'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
        'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
        'visible': is_visible,
        'world_suffixes': ['', 'ForMainWorld'] if 'PerWorldBindings' in extended_attributes else [''],  # [PerWorldBindings],
    }


def argument_context(interface, method, argument, index, is_visible=True):
    extended_attributes = argument.extended_attributes
    idl_type = argument.idl_type
    if is_visible:
        idl_type.add_includes_for_type(extended_attributes)
    this_cpp_value = cpp_value(interface, method, index)
    is_variadic_wrapper_type = argument.is_variadic and idl_type.is_wrapper_type

    # [LegacyInterfaceTypeChecking]
    has_type_checking_interface = (
        not is_legacy_interface_type_checking(interface, method) and
        idl_type.is_wrapper_type)

    if ('ImplementedInPrivateScript' in extended_attributes and
            not idl_type.is_wrapper_type and
            not idl_type.is_basic_type):
        raise Exception('Private scripts supports only primitive types and DOM wrappers.')

    set_default_value = argument.set_default_value
    this_cpp_type = idl_type.cpp_type_args(extended_attributes=extended_attributes,
                                           raw_type=True,
                                           used_as_variadic_argument=argument.is_variadic)
    context = {
        'cpp_type': (
            v8_types.cpp_template_type('Nullable', this_cpp_type)
            if idl_type.is_explicit_nullable and not argument.is_variadic
            else this_cpp_type),
        'cpp_value': this_cpp_value,
        # FIXME: check that the default value's type is compatible with the argument's
        'set_default_value': set_default_value,
        'enum_type': idl_type.enum_type,
        'enum_values': idl_type.enum_values,
        'handle': '%sHandle' % argument.name,
        # FIXME: remove once [Default] removed and just use argument.default_value
        'has_default': 'Default' in extended_attributes or set_default_value,
        'has_type_checking_interface': has_type_checking_interface,
        # Dictionary is special-cased, but arrays and sequences shouldn't be
        'idl_type': idl_type.base_type,
        'idl_type_object': idl_type,
        'index': index,
        'is_callback_function': idl_type.is_callback_function,
        'is_callback_interface': idl_type.is_callback_interface,
        # FIXME: Remove generic 'Dictionary' special-casing
        'is_dictionary': idl_type.is_dictionary or idl_type.base_type == 'Dictionary',
        'is_explicit_nullable': idl_type.is_explicit_nullable,
        'is_nullable': idl_type.is_nullable,
        'is_optional': argument.is_optional,
        'is_variadic': argument.is_variadic,
        'is_variadic_wrapper_type': is_variadic_wrapper_type,
        'is_wrapper_type': idl_type.is_wrapper_type,
        'name': argument.name,
        'private_script_cpp_value_to_v8_value': idl_type.cpp_value_to_v8_value(
            argument.name, isolate='scriptState->isolate()',
            creation_context='scriptState->context()->Global()'),
        'use_permissive_dictionary_conversion': 'PermissiveDictionaryConversion' in extended_attributes,
        'v8_set_return_value': v8_set_return_value(interface.name, method, this_cpp_value),
        'v8_set_return_value_for_main_world': v8_set_return_value(interface.name, method, this_cpp_value, for_main_world=True),
        'v8_value_to_local_cpp_value': v8_value_to_local_cpp_value(method, argument, index),
    }
    context.update({
        'is_optional_without_default_value':
            context['is_optional'] and
            not context['has_default'] and
            not context['is_dictionary'] and
            not context['is_callback_interface'],
    })
    return context


def argument_declarations_for_private_script(interface, method):
    argument_declarations = ['LocalFrame* frame']
    argument_declarations.append('%s* holderImpl' % interface.name)
    argument_declarations.extend(['%s %s' % (argument.idl_type.cpp_type_args(
        used_as_rvalue_type=True), argument.name) for argument in method.arguments])
    if method.idl_type.name != 'void':
        argument_declarations.append('%s* %s' % (method.idl_type.cpp_type, 'result'))
    return argument_declarations


################################################################################
# Value handling
################################################################################

def cpp_value(interface, method, number_of_arguments):
    def cpp_argument(argument):
        idl_type = argument.idl_type
        if idl_type.name == 'EventListener':
            return argument.name
        if (idl_type.name in ['NodeFilter', 'NodeFilterOrNull',
                              'XPathNSResolver', 'XPathNSResolverOrNull']):
            # FIXME: remove this special case
            return '%s.release()' % argument.name
        return argument.name

    # Truncate omitted optional arguments
    arguments = method.arguments[:number_of_arguments]
    cpp_arguments = []
    if 'ImplementedInPrivateScript' in method.extended_attributes:
        cpp_arguments.append('toLocalFrame(toFrameIfNotDetached(info.GetIsolate()->GetCurrentContext()))')
        cpp_arguments.append('impl')

    if method.is_constructor:
        call_with_values = interface.extended_attributes.get('ConstructorCallWith')
    else:
        call_with_values = method.extended_attributes.get('CallWith')
    cpp_arguments.extend(v8_utilities.call_with_arguments(call_with_values))

    # Members of IDL partial interface definitions are implemented in C++ as
    # static member functions, which for instance members (non-static members)
    # take *impl as their first argument
    if ('PartialInterfaceImplementedAs' in method.extended_attributes and
            'ImplementedInPrivateScript' not in method.extended_attributes and
            not method.is_static):
        cpp_arguments.append('*impl')
    cpp_arguments.extend(cpp_argument(argument) for argument in arguments)

    if 'ImplementedInPrivateScript' in method.extended_attributes:
        if method.idl_type.name != 'void':
            cpp_arguments.append('&result')
    elif ('RaisesException' in method.extended_attributes or
          (method.is_constructor and
           has_extended_attribute_value(interface, 'RaisesException', 'Constructor'))):
        cpp_arguments.append('exceptionState')

    # If a method returns an IDL dictionary or union type, the return value is
    # passed as an argument to impl classes.
    idl_type = method.idl_type
    if idl_type and idl_type.use_output_parameter_for_result:
        cpp_arguments.append('result')

    if method.name == 'Constructor':
        base_name = 'create'
    elif method.name == 'NamedConstructor':
        base_name = 'createForJSConstructor'
    elif 'ImplementedInPrivateScript' in method.extended_attributes:
        base_name = '%sMethod' % method.name
    else:
        base_name = v8_utilities.cpp_name(method)

    cpp_method_name = v8_utilities.scoped_name(interface, method, base_name)
    return '%s(%s)' % (cpp_method_name, ', '.join(cpp_arguments))


def v8_set_return_value(interface_name, method, cpp_value, for_main_world=False):
    idl_type = method.idl_type
    extended_attributes = method.extended_attributes
    if not idl_type or idl_type.name == 'void':
        # Constructors and void methods don't have a return type
        return None

    if ('ImplementedInPrivateScript' in extended_attributes and
            not idl_type.is_wrapper_type and
            not idl_type.is_basic_type):
        raise Exception('Private scripts supports only primitive types and DOM wrappers.')

    release = False
    # [CallWith=ScriptState], [RaisesException]
    if use_local_result(method):
        if idl_type.is_explicit_nullable:
            # result is of type Nullable<T>
            cpp_value = 'result.get()'
        else:
            cpp_value = 'result'
        release = idl_type.release

    script_wrappable = 'impl' if inherits_interface(interface_name, 'Node') else ''
    return idl_type.v8_set_return_value(cpp_value, extended_attributes, script_wrappable=script_wrappable, release=release, for_main_world=for_main_world, is_static=method.is_static)


def v8_value_to_local_cpp_variadic_value(method, argument, index, return_promise):
    assert argument.is_variadic
    idl_type = argument.idl_type
    this_cpp_type = idl_type.cpp_type

    if method.returns_promise:
        check_expression = 'exceptionState.hadException()'
    else:
        check_expression = 'exceptionState.throwIfNeeded()'

    if idl_type.is_dictionary or idl_type.is_union_type:
        vector_type = 'HeapVector'
    else:
        vector_type = 'Vector'

    return {
        'assign_expression': 'toImplArguments<%s<%s>>(info, %s, exceptionState)' % (vector_type, this_cpp_type, index),
        'check_expression': check_expression,
        'cpp_type': this_cpp_type,
        'cpp_name': argument.name,
        'declare_variable': False,
    }


def v8_value_to_local_cpp_value(method, argument, index, return_promise=False, restricted_float=False):
    extended_attributes = argument.extended_attributes
    idl_type = argument.idl_type
    name = argument.name
    if argument.is_variadic:
        return v8_value_to_local_cpp_variadic_value(method, argument, index, return_promise)
    return idl_type.v8_value_to_local_cpp_value(extended_attributes, 'info[%s]' % index,
                                                name, index=index, declare_variable=False,
                                                use_exception_state=method.returns_promise,
                                                restricted_float=restricted_float)


################################################################################
# Auxiliary functions
################################################################################

# [NotEnumerable], [Unforgeable]
def property_attributes(interface, method):
    extended_attributes = method.extended_attributes
    property_attributes_list = []
    if 'NotEnumerable' in extended_attributes:
        property_attributes_list.append('v8::DontEnum')
    if is_unforgeable(interface, method):
        property_attributes_list.append('v8::ReadOnly')
        property_attributes_list.append('v8::DontDelete')
    return property_attributes_list


def argument_set_default_value(argument):
    idl_type = argument.idl_type
    default_value = argument.default_value
    if not default_value:
        return None
    if idl_type.is_dictionary:
        if not argument.default_value.is_null:
            raise Exception('invalid default value for dictionary type')
        return None
    if idl_type.is_array_or_sequence_type:
        if default_value.value != '[]':
            raise Exception('invalid default value for sequence type: %s' % default_value.value)
        # Nothing to do when we set an empty sequence as default value, but we
        # need to return non-empty value so that we don't generate method calls
        # without this argument.
        return '/* Nothing to do */'
    if idl_type.is_union_type:
        if argument.default_value.is_null:
            if not idl_type.includes_nullable_type:
                raise Exception('invalid default value for union type: null for %s'
                                % idl_type.name)
            # Union container objects are "null" initially.
            return '/* null default value */'
        if isinstance(default_value.value, basestring):
            member_type = idl_type.string_member_type
        elif isinstance(default_value.value, (int, float)):
            member_type = idl_type.numeric_member_type
        elif isinstance(default_value.value, bool):
            member_type = idl_type.boolean_member_type
        else:
            member_type = None
        if member_type is None:
            raise Exception('invalid default value for union type: %r for %s'
                            % (default_value.value, idl_type.name))
        member_type_name = (member_type.inner_type.name
                            if member_type.is_nullable else
                            member_type.name)
        return '%s.set%s(%s)' % (argument.name, member_type_name,
                                 member_type.literal_cpp_value(default_value))
    return '%s = %s' % (argument.name,
                        idl_type.literal_cpp_value(default_value))

IdlArgument.set_default_value = property(argument_set_default_value)


def method_returns_promise(method):
    return method.idl_type and method.idl_type.name == 'Promise'

IdlOperation.returns_promise = property(method_returns_promise)


def argument_conversion_needs_exception_state(method, argument):
    idl_type = argument.idl_type
    return (idl_type.v8_conversion_needs_exception_state or
            argument.is_variadic or
            (method.returns_promise and idl_type.is_string_type))
