# Copyright 2020 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.

import web_idl

from . import name_style
from .blink_v8_bridge import blink_class_name
from .code_node import EmptyNode
from .code_node import ListNode
from .code_node import SequenceNode
from .code_node import TextNode
from .code_node_cxx import CxxClassDefNode
from .code_node_cxx import CxxFuncDeclNode
from .code_node_cxx import CxxFuncDefNode
from .code_node_cxx import CxxNamespaceNode
from .codegen_accumulator import CodeGenAccumulator
from .codegen_context import CodeGenContext
from .codegen_utils import collect_forward_decls_and_include_headers
from .codegen_utils import component_export
from .codegen_utils import component_export_header
from .codegen_utils import enclose_with_header_guard
from .codegen_utils import make_copyright_header
from .codegen_utils import make_forward_declarations
from .codegen_utils import make_header_include_directives
from .codegen_utils import write_code_node_to_file
from .mako_renderer import MakoRenderer
from .package_initializer import package_initializer
from .path_manager import PathManager
from .task_queue import TaskQueue

# IDL callback interface and IDL callback function share a lot by their nature,
# so this module uses some implementations from IDL callback function.
from .callback_function import make_callback_invocation_function
from .callback_function import make_invoke_and_report_function
from .callback_function import make_is_runnable_or_throw_exception
from .callback_function import make_nameclient_implementation

# IDL legacy callback interface is mostly the same as IDL interface, so this
# module uses some implementations from IDL interface
from .interface import FN_INSTALL_INTERFACE_TEMPLATE
from .interface import FN_INSTALL_UNCONDITIONAL_PROPS
from .interface import PropInstallMode
from .interface import constant_name
from .interface import make_constant_constant_def
from .interface import make_install_interface_template
from .interface import make_install_properties
from .interface import make_property_entries_and_callback_defs
from .interface import make_wrapper_type_info


def make_factory_methods(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    func_def = CxxFuncDefNode(
        name="Create",
        arg_decls=["v8::Local<v8::Object> callback_object"],
        return_type="${class_name}*",
        static=True)
    func_def.set_base_template_vars(cg_context.template_bindings())

    func_def.body.append(
        TextNode("return MakeGarbageCollected<${class_name}>("
                 "callback_object);"))

    return func_def, None


def make_constructors(cg_context):
    assert isinstance(cg_context, CodeGenContext)

    decls = ListNode([
        CxxFuncDefNode(
            name=cg_context.class_name,
            arg_decls=["v8::Local<v8::Object> callback_object"],
            return_type="",
            explicit=True,
            member_initializer_list=[
                "${base_class_name}(callback_object, kSingleOperation)",
            ]),
        CxxFuncDeclNode(name="~${class_name}",
                        arg_decls=[],
                        return_type="",
                        override=True,
                        default=True),
    ])

    return decls, None


def generate_callback_interface(callback_interface_identifier):
    assert isinstance(callback_interface_identifier, web_idl.Identifier)

    web_idl_database = package_initializer().web_idl_database()
    callback_interface = web_idl_database.find(callback_interface_identifier)

    path_manager = PathManager(callback_interface)
    assert path_manager.api_component == path_manager.impl_component
    api_component = path_manager.api_component
    for_testing = callback_interface.code_generator_info.for_testing

    # Class names
    class_name = blink_class_name(callback_interface)

    cg_context = CodeGenContext(callback_interface=callback_interface,
                                class_name=class_name,
                                base_class_name="CallbackInterfaceBase")