/*
 * Copyright (C) 2012 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "WebProcessTest.h"
#include <JavaScriptCore/JSContextRef.h>
#include <JavaScriptCore/JSRetainPtr.h>
#include <gio/gio.h>
#if USE(GSTREAMER)
#include <gst/gst.h>
#endif
#include <jsc/jsc.h>
#include <stdlib.h>
#include <string.h>
#include <wtf/Deque.h>
#include <wtf/ProcessID.h>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>

#if PLATFORM(GTK)
#include <webkit2/webkit-web-extension.h>
#elif PLATFORM(WPE)
#include <wpe/webkit-web-extension.h>
#endif

static const char introspectionXML[] =
    "<node>"
    " <interface name='org.webkit.gtk.WebExtensionTest'>"
    "  <method name='GetTitle'>"
    "   <arg type='t' name='pageID' direction='in'/>"
    "   <arg type='s' name='title' direction='out'/>"
    "  </method>"
    "  <method name='InputElementIsUserEdited'>"
    "    <arg type='t' name='pageID' direction='in'/>"
    "    <arg type='s' name='elementID' direction='in'/>"
    "    <arg type='b' name='isUserEdited' direction='out'/>"
    "  </method>"
    "  <method name='AbortProcess'>"
    "  </method>"
    "  <method name='RunJavaScriptInIsolatedWorld'>"
    "   <arg type='t' name='pageID' direction='in'/>"
    "   <arg type='s' name='script' direction='in'/>"
    "  </method>"
    "  <method name='GetProcessIdentifier'>"
    "   <arg type='u' name='identifier' direction='out'/>"
    "  </method>"
    "  <method name='RemoveAVPluginsFromGSTRegistry'>"
    "  </method>"
    "  <signal name='DocumentLoaded'/>"
    "  <signal name='FormControlsAssociated'>"
    "   <arg type='s' name='formIds' direction='out'/>"
    "  </signal>"
    "  <signal name='FormSubmissionWillSendDOMEvent'>"
    "    <arg type='s' name='formID' direction='out'/>"
    "    <arg type='s' name='textFieldNames' direction='out'/>"
    "    <arg type='s' name='textFieldValues' direction='out'/>"
    "    <arg type='b' name='targetFrameIsMainFrame' direction='out'/>"
    "    <arg type='b' name='sourceFrameIsMainFrame' direction='out'/>"
    "  </signal>"
    "  <signal name='FormSubmissionWillComplete'>"
    "    <arg type='s' name='formID' direction='out'/>"
    "    <arg type='s' name='textFieldNames' direction='out'/>"
    "    <arg type='s' name='textFieldValues' direction='out'/>"
    "    <arg type='b' name='targetFrameIsMainFrame' direction='out'/>"
    "    <arg type='b' name='sourceFrameIsMainFrame' direction='out'/>"
    "  </signal>"
    "  <signal name='URIChanged'>"
    "   <arg type='s' name='uri' direction='out'/>"
    "  </signal>"
    " </interface>"
    "</node>";


typedef enum {
    DocumentLoadedSignal,
    URIChangedSignal,
    FormControlsAssociatedSignal,
    FormSubmissionWillSendDOMEventSignal,
    FormSubmissionWillCompleteSignal,
} DelayedSignalType;

struct DelayedSignal {
    explicit DelayedSignal(DelayedSignalType type)
        : type(type)
    {
    }

    DelayedSignal(DelayedSignalType type, const char* str)
        : type(type)
        , str(str)
    {
    }

    DelayedSignal(DelayedSignalType type, const char* str, const char* str2, const char* str3, gboolean b, gboolean b2)
        : type(type)
        , str(str)
        , str2(str2)
        , str3(str3)
        , b(b)
        , b2(b2)
    {
    }

    DelayedSignalType type;
    CString str;
    CString str2;
    CString str3;
    gboolean b;
    gboolean b2;
};

Deque<DelayedSignal> delayedSignalsQueue;

static void emitDocumentLoaded(GDBusConnection* connection)
{
    bool ok = g_dbus_connection_emit_signal(
        connection,
        0,
        "/org/webkit/gtk/WebExtensionTest",
        "org.webkit.gtk.WebExtensionTest",
        "DocumentLoaded",
        0,
        0);
    g_assert_true(ok);
}

static void documentLoadedCallback(WebKitWebPage* webPage, WebKitWebExtension* extension)
{
#if PLATFORM(GTK)
    WebKitDOMDocument* document = webkit_web_page_get_dom_document(webPage);
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
    GRefPtr<WebKitDOMDOMWindow> window = adoptGRef(webkit_dom_document_get_default_view(document));
    webkit_dom_dom_window_webkit_message_handlers_post_message(window.get(), "dom", "DocumentLoaded");
    G_GNUC_END_IGNORE_DEPRECATIONS;
#endif

    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
    if (data)
        emitDocumentLoaded(G_DBUS_CONNECTION(data));
    else
        delayedSignalsQueue.append(DelayedSignal(DocumentLoadedSignal));
}

static void emitURIChanged(GDBusConnection* connection, const char* uri)
{
    bool ok = g_dbus_connection_emit_signal(
        connection,
        0,
        "/org/webkit/gtk/WebExtensionTest",
        "org.webkit.gtk.WebExtensionTest",
        "URIChanged",
        g_variant_new("(s)", uri),
        0);
    g_assert_true(ok);
}

static void uriChangedCallback(WebKitWebPage* webPage, GParamSpec* pspec, WebKitWebExtension* extension)
{
    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
    if (data)
        emitURIChanged(G_DBUS_CONNECTION(data), webkit_web_page_get_uri(webPage));
    else
        delayedSignalsQueue.append(DelayedSignal(URIChangedSignal, webkit_web_page_get_uri(webPage)));
}

static gboolean sendRequestCallback(WebKitWebPage*, WebKitURIRequest* request, WebKitURIResponse* redirectResponse, gpointer)
{
    gboolean returnValue = FALSE;
    const char* requestURI = webkit_uri_request_get_uri(request);
    g_assert_nonnull(requestURI);

    if (const char* suffix = g_strrstr(requestURI, "/remove-this/javascript.js")) {
        GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen(suffix)));
        GUniquePtr<char> newURI(g_strdup_printf("%s/javascript.js", prefix.get()));
        webkit_uri_request_set_uri(request, newURI.get());
    } else if (const char* suffix = g_strrstr(requestURI, "/remove-this/javascript-after-redirection.js")) {
        // Redirected from /redirected.js, redirectResponse should be nullptr.
        g_assert_true(WEBKIT_IS_URI_RESPONSE(redirectResponse));
        g_assert_true(g_str_has_suffix(webkit_uri_response_get_uri(redirectResponse), "/redirected.js"));

        GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen(suffix)));
        GUniquePtr<char> newURI(g_strdup_printf("%s/javascript-after-redirection.js", prefix.get()));
        webkit_uri_request_set_uri(request, newURI.get());
    } else if (g_str_has_suffix(requestURI, "/redirected.js")) {
        // Original request, redirectResponse should be nullptr.
        g_assert_null(redirectResponse);
    } else if (g_str_has_suffix(requestURI, "/add-do-not-track-header")) {
        SoupMessageHeaders* headers = webkit_uri_request_get_http_headers(request);
        g_assert_nonnull(headers);
        soup_message_headers_append(headers, "DNT", "1");
    } else if (g_str_has_suffix(requestURI, "/normal-change-request") && !g_strrstr(requestURI, "/redirect-js/")) {
        GUniquePtr<char> prefix(g_strndup(requestURI, strlen(requestURI) - strlen("/normal-change-request")));
        GUniquePtr<char> newURI(g_strdup_printf("%s/request-changed%s", prefix.get(), redirectResponse ? "-on-redirect" : ""));
        webkit_uri_request_set_uri(request, newURI.get());
    } else if (g_str_has_suffix(requestURI, "/http-get-method")) {
        g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "GET");
        g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, SOUP_METHOD_GET);
    } else if (g_str_has_suffix(requestURI, "/http-post-method")) {
        g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, "POST");
        g_assert_cmpstr(webkit_uri_request_get_http_method(request), ==, SOUP_METHOD_POST);
        returnValue = TRUE;
    } else if (g_str_has_suffix(requestURI, "/cancel-this.js"))
        returnValue = TRUE;

    return returnValue;
}

static GVariant* serializeContextMenu(WebKitContextMenu* menu)
{
    GVariantBuilder builder;
    g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
    GList* items = webkit_context_menu_get_items(menu);
    for (GList* it = items; it; it = g_list_next(it))
        g_variant_builder_add(&builder, "u", webkit_context_menu_item_get_stock_action(WEBKIT_CONTEXT_MENU_ITEM(it->data)));
    return g_variant_builder_end(&builder);
}

static GVariant* serializeNode(JSCValue* node)
{
    GVariantBuilder builder;
    g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
    GRefPtr<JSCValue> value = adoptGRef(jsc_value_object_get_property(node, "nodeName"));
    g_variant_builder_add(&builder, "{sv}", "Name", g_variant_new_take_string(jsc_value_to_string(value.get())));
    value = adoptGRef(jsc_value_object_get_property(node, "nodeType"));
    g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_uint32(jsc_value_to_int32(value.get())));
    value = adoptGRef(jsc_value_object_get_property(node, "textContent"));
    g_variant_builder_add(&builder, "{sv}", "Contents", g_variant_new_take_string(jsc_value_to_string(value.get())));
    value = adoptGRef(jsc_value_object_get_property(node, "parentNode"));
    if (jsc_value_is_null(value.get()))
        g_variant_builder_add(&builder, "{sv}", "Parent", g_variant_new_string("ROOT"));
    else {
        value = jsc_value_object_get_property(value.get(), "nodeName");
        g_variant_builder_add(&builder, "{sv}", "Parent", g_variant_new_take_string(jsc_value_to_string(value.get())));
    }
    return g_variant_builder_end(&builder);
}

static gboolean contextMenuCallback(WebKitWebPage* page, WebKitContextMenu* menu, WebKitWebHitTestResult* hitTestResult, gpointer)
{
    const char* pageURI = webkit_web_page_get_uri(page);
    if (!g_strcmp0(pageURI, "ContextMenuTestDefault")) {
        webkit_context_menu_set_user_data(menu, serializeContextMenu(menu));
        return FALSE;
    }

    if (!g_strcmp0(pageURI, "ContextMenuTestCustom")) {
        // Remove Back and Forward, and add Inspector action.
        webkit_context_menu_remove(menu, webkit_context_menu_first(menu));
        webkit_context_menu_remove(menu, webkit_context_menu_first(menu));
        webkit_context_menu_append(menu, webkit_context_menu_item_new_separator());
        webkit_context_menu_append(menu, webkit_context_menu_item_new_from_stock_action(WEBKIT_CONTEXT_MENU_ACTION_INSPECT_ELEMENT));
        webkit_context_menu_set_user_data(menu, serializeContextMenu(menu));
        return TRUE;
    }

    if (!g_strcmp0(pageURI, "ContextMenuTestClear")) {
        webkit_context_menu_remove_all(menu);
        return TRUE;
    }

    if (!g_strcmp0(pageURI, "ContextMenuTestNode")) {
        WebKitDOMNode* node = webkit_web_hit_test_result_get_node(hitTestResult);
        g_assert_true(WEBKIT_DOM_IS_NODE(node));
        auto* frame = webkit_web_page_get_main_frame(page);
        GRefPtr<JSCValue> jsNode = adoptGRef(webkit_frame_get_js_value_for_dom_object(frame, WEBKIT_DOM_OBJECT(node)));
        webkit_context_menu_set_user_data(menu, serializeNode(jsNode.get()));
        return TRUE;
    }

    return FALSE;
}

static void consoleMessageSentCallback(WebKitWebPage* webPage, WebKitConsoleMessage* consoleMessage)
{
    g_assert_nonnull(consoleMessage);
    GRefPtr<GVariant> variant = g_variant_new("(uusus)", webkit_console_message_get_source(consoleMessage),
        webkit_console_message_get_level(consoleMessage), webkit_console_message_get_text(consoleMessage),
        webkit_console_message_get_line(consoleMessage), webkit_console_message_get_source_id(consoleMessage));
    GUniquePtr<char> messageString(g_variant_print(variant.get(), FALSE));
    GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context(webkit_web_page_get_main_frame(webPage)));
    GRefPtr<JSCValue> console = adoptGRef(jsc_context_evaluate(jsContext.get(), "window.webkit.messageHandlers.console", -1));
    g_assert_true(JSC_IS_VALUE(console.get()));
    if (jsc_value_is_object(console.get())) {
        GRefPtr<JSCValue> result = adoptGRef(jsc_value_object_invoke_method(console.get(), "postMessage", G_TYPE_STRING, messageString.get(), G_TYPE_NONE));
        g_assert_true(JSC_IS_VALUE(result.get()));
    }
}

static void emitFormControlsAssociated(GDBusConnection* connection, const char* formIds)
{
    bool ok = g_dbus_connection_emit_signal(
        connection,
        nullptr,
        "/org/webkit/gtk/WebExtensionTest",
        "org.webkit.gtk.WebExtensionTest",
        "FormControlsAssociated",
        g_variant_new("(s)", formIds),
        nullptr);
    g_assert_true(ok);
}

static void formControlsAssociatedForFrameCallback(WebKitWebPage* webPage, GPtrArray* formElements, WebKitFrame* frame, WebKitWebExtension* extension)
{
    GString* formIdsBuilder = g_string_new(nullptr);
    for (guint i = 0; i < formElements->len; ++i) {
        g_assert_true(WEBKIT_DOM_IS_ELEMENT(g_ptr_array_index(formElements, i)));
        GRefPtr<JSCValue> value = adoptGRef(webkit_frame_get_js_value_for_dom_object(frame, WEBKIT_DOM_OBJECT(g_ptr_array_index(formElements, i))));
        g_assert_true(JSC_IS_VALUE(value.get()));
        g_assert_true(jsc_value_is_object(value.get()));
        g_assert_true(jsc_value_object_is_instance_of(value.get(), "Element"));
        GRefPtr<JSCValue> idValue = adoptGRef(jsc_value_object_get_property(value.get(), "id"));
        GUniquePtr<char> elementID(jsc_value_to_string(idValue.get()));
        g_string_append(formIdsBuilder, elementID.get());
    }
    if (!formIdsBuilder->len) {
        g_string_free(formIdsBuilder, TRUE);
        return;
    }
    GUniquePtr<char> formIds(g_string_free(formIdsBuilder, FALSE));
    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
    if (data)
        emitFormControlsAssociated(G_DBUS_CONNECTION(data), formIds.get());
    else
        delayedSignalsQueue.append(DelayedSignal(FormControlsAssociatedSignal, formIds.get()));
}

static void emitFormSubmissionEvent(GDBusConnection* connection, const char* methodName, const char* formID, const char* names, const char* values, gboolean targetFrameIsMainFrame, gboolean sourceFrameIsMainFrame)
{
    bool ok = g_dbus_connection_emit_signal(
        connection,
        nullptr,
        "/org/webkit/gtk/WebExtensionTest",
        "org.webkit.gtk.WebExtensionTest",
        methodName,
        g_variant_new("(sssbb)", formID ? formID : "", names, values, targetFrameIsMainFrame, sourceFrameIsMainFrame),
        nullptr);
    g_assert_true(ok);
}

static void handleFormSubmissionCallback(WebKitWebPage* webPage, DelayedSignalType delayedSignalType, const char* methodName, const char* formID, WebKitFrame* sourceFrame, WebKitFrame* targetFrame, GPtrArray* textFieldNames, GPtrArray* textFieldValues, WebKitWebExtension* extension)
{
    GString* namesBuilder = g_string_new(nullptr);
    for (guint i = 0; i < textFieldNames->len; ++i) {
        auto* name = static_cast<char*>(g_ptr_array_index(textFieldNames, i));
        g_string_append(namesBuilder, name);
        g_string_append_c(namesBuilder, ',');
    }
    GUniquePtr<char> names(g_string_free(namesBuilder, FALSE));

    GString* valuesBuilder = g_string_new(nullptr);
    for (guint i = 0; i < textFieldValues->len; ++i) {
        auto* value = static_cast<char*>(g_ptr_array_index(textFieldValues, i));
        g_string_append(valuesBuilder, value);
        g_string_append_c(valuesBuilder, ',');
    }
    GUniquePtr<char> values(g_string_free(valuesBuilder, FALSE));

    gpointer data = g_object_get_data(G_OBJECT(extension), "dbus-connection");
    if (data)
        emitFormSubmissionEvent(G_DBUS_CONNECTION(data), methodName, formID, names.get(), values.get(), webkit_frame_is_main_frame(targetFrame), webkit_frame_is_main_frame(sourceFrame));
    else
        delayedSignalsQueue.append(DelayedSignal(delayedSignalType, formID, names.get(), values.get(), webkit_frame_is_main_frame(targetFrame), webkit_frame_is_main_frame(sourceFrame)));
}

static void willSubmitFormCallback(WebKitWebPage* webPage, WebKitDOMElement* formElement, WebKitFormSubmissionStep step, WebKitFrame* sourceFrame, WebKitFrame* targetFrame, GPtrArray* textFieldNames, GPtrArray* textFieldValues, WebKitWebExtension* extension)
{
#if PLATFORM(GTK)
    G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
    g_assert_true(WEBKIT_DOM_IS_HTML_FORM_ELEMENT(formElement));
    G_GNUC_END_IGNORE_DEPRECATIONS;
#endif
    GRefPtr<JSCValue> jsFormElement = adoptGRef(webkit_frame_get_js_value_for_dom_object(sourceFrame, WEBKIT_DOM_OBJECT(formElement)));
    g_assert_true(JSC_IS_VALUE(jsFormElement.get()));
    g_assert_true(jsc_value_is_object(jsFormElement.get()));
    g_assert_true(jsc_value_object_is_instance_of(jsFormElement.get(), "HTMLFormElement"));
    GRefPtr<JSCValue> idValue = adoptGRef(jsc_value_object_get_property(jsFormElement.get(), "id"));
    GUniquePtr<char> formID(jsc_value_to_string(idValue.get()));

    switch (step) {
    case WEBKIT_FORM_SUBMISSION_WILL_SEND_DOM_EVENT:
        handleFormSubmissionCallback(webPage, FormSubmissionWillSendDOMEventSignal, "FormSubmissionWillSendDOMEvent", formID.get(), sourceFrame, targetFrame, textFieldNames, textFieldValues, extension);
        break;
    case WEBKIT_FORM_SUBMISSION_WILL_COMPLETE:
        handleFormSubmissionCallback(webPage, FormSubmissionWillCompleteSignal, "FormSubmissionWillComplete", formID.get(), sourceFrame, targetFrame, textFieldNames, textFieldValues, extension);
        break;
    default:
        g_assert_not_reached();
    }
}

static void pageCreatedCallback(WebKitWebExtension* extension, WebKitWebPage* webPage, gpointer)
{
    g_signal_connect(webPage, "document-loaded", G_CALLBACK(documentLoadedCallback), extension);
    g_signal_connect(webPage, "notify::uri", G_CALLBACK(uriChangedCallback), extension);
    g_signal_connect(webPage, "send-request", G_CALLBACK(sendRequestCallback), nullptr);
    g_signal_connect(webPage, "console-message-sent", G_CALLBACK(consoleMessageSentCallback), nullptr);
    g_signal_connect(webPage, "context-menu", G_CALLBACK(contextMenuCallback), nullptr);
    g_signal_connect(webPage, "form-controls-associated-for-frame", G_CALLBACK(formControlsAssociatedForFrameCallback), extension);
    g_signal_connect(webPage, "will-submit-form", G_CALLBACK(willSubmitFormCallback), extension);
}

static char* echoCallback(const char* message)
{
    return g_strdup(message);
}

static void windowObjectCleared(WebKitScriptWorld* world, WebKitWebPage* page, WebKitFrame* frame, gpointer)
{
    GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context_for_script_world(frame, world));
    g_assert_true(JSC_IS_CONTEXT(jsContext.get()));
    GRefPtr<JSCValue> function = adoptGRef(jsc_value_new_function(jsContext.get(), "echo", G_CALLBACK(echoCallback), NULL, NULL, G_TYPE_STRING, 1, G_TYPE_STRING));
    jsc_context_set_value(jsContext.get(), "echo", function.get());

    auto* fileClass = jsc_context_register_class(jsContext.get(), "GFile", nullptr, nullptr, static_cast<GDestroyNotify>(g_object_unref));
    GRefPtr<JSCValue> constructor = adoptGRef(jsc_class_add_constructor(fileClass, "GFile", G_CALLBACK(g_file_new_for_path), nullptr, nullptr, G_TYPE_OBJECT, 1, G_TYPE_STRING));
    jsc_class_add_method(fileClass, "path", G_CALLBACK(g_file_get_path), nullptr, nullptr, G_TYPE_STRING, 0, G_TYPE_NONE);
    jsc_context_set_value(jsContext.get(), "GFile", constructor.get());
}

static WebKitWebPage* getWebPage(WebKitWebExtension* extension, uint64_t pageID, GDBusMethodInvocation* invocation)
{
    WebKitWebPage* page = webkit_web_extension_get_page(extension, pageID);
    if (!page) {
        g_dbus_method_invocation_return_error(
            invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
            "Invalid page ID: %" G_GUINT64_FORMAT, pageID);
        return 0;
    }

    g_assert_cmpuint(webkit_web_page_get_id(page), ==, pageID);
    return page;
}

static void methodCallCallback(GDBusConnection* connection, const char* sender, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData)
{
    if (g_strcmp0(interfaceName, "org.webkit.gtk.WebExtensionTest"))
        return;

    if (!g_strcmp0(methodName, "GetTitle")) {
        uint64_t pageID;
        g_variant_get(parameters, "(t)", &pageID);
        WebKitWebPage* page = getWebPage(WEBKIT_WEB_EXTENSION(userData), pageID, invocation);
        if (!page)
            return;

        GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context(webkit_web_page_get_main_frame(page)));
        GRefPtr<JSCValue> titleValue = adoptGRef(jsc_context_evaluate(jsContext.get(), "document.title", -1));
        GUniquePtr<char> title(jsc_value_to_string(titleValue.get()));
        g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", title.get()));
    } else if (!g_strcmp0(methodName, "InputElementIsUserEdited")) {
        uint64_t pageID;
        const char* elementID;
        g_variant_get(parameters, "(t&s)", &pageID, &elementID);
        WebKitWebPage* page = getWebPage(WEBKIT_WEB_EXTENSION(userData), pageID, invocation);
        if (!page)
            return;

        WebKitDOMDocument* document = webkit_web_page_get_dom_document(page);
        WebKitFrame* frame = webkit_web_page_get_main_frame(page);
        GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context(frame));
        GRefPtr<JSCValue> jsDocument = adoptGRef(webkit_frame_get_js_value_for_dom_object(frame, WEBKIT_DOM_OBJECT(document)));
        GRefPtr<JSCValue> jsInputElement = adoptGRef(jsc_value_object_invoke_method(jsDocument.get(), "getElementById", G_TYPE_STRING, elementID, G_TYPE_NONE));
        WebKitDOMNode* node = webkit_dom_node_for_js_value(jsInputElement.get());
        gboolean isUserEdited = webkit_dom_element_html_input_element_is_user_edited(WEBKIT_DOM_ELEMENT(node));
        g_dbus_method_invocation_return_value(invocation, g_variant_new("(b)", isUserEdited));
    } else if (!g_strcmp0(methodName, "RunJavaScriptInIsolatedWorld")) {
        uint64_t pageID;
        const char* script;
        g_variant_get(parameters, "(t&s)", &pageID, &script);
        WebKitWebPage* page = getWebPage(WEBKIT_WEB_EXTENSION(userData), pageID, invocation);
        if (!page)
            return;

        GRefPtr<WebKitScriptWorld> world = adoptGRef(webkit_script_world_new());
        g_assert_true(webkit_script_world_get_default() != world.get());
        g_assert_true(g_str_has_prefix(webkit_script_world_get_name(world.get()), "UniqueWorld_"));
        WebKitFrame* frame = webkit_web_page_get_main_frame(page);
        GRefPtr<JSCContext> jsContext = adoptGRef(webkit_frame_get_js_context_for_script_world(frame, world.get()));
        GRefPtr<JSCValue> result = adoptGRef(jsc_context_evaluate(jsContext.get(), script, -1));
        g_dbus_method_invocation_return_value(invocation, 0);
    } else if (!g_strcmp0(methodName, "AbortProcess")) {
        abort();
    } else if (!g_strcmp0(methodName, "GetProcessIdentifier")) {
        g_dbus_method_invocation_return_value(invocation,
            g_variant_new("(u)", static_cast<guint32>(getCurrentProcessID())));
    } else if (!g_strcmp0(methodName, "RemoveAVPluginsFromGSTRegistry")) {
#if USE(GSTREAMER)
        gst_init(nullptr, nullptr);
        static const char* avPlugins[] = { "libav", "omx", "vaapi", nullptr };
        GstRegistry* registry = gst_registry_get();
        for (unsigned i = 0; avPlugins[i]; ++i) {
            if (GstPlugin* plugin = gst_registry_find_plugin(registry, avPlugins[i])) {
                gst_registry_remove_plugin(registry, plugin);
                gst_object_unref(plugin);
            }
        }
#endif
        g_dbus_method_invocation_return_value(invocation, nullptr);
    }
}

static const GDBusInterfaceVTable interfaceVirtualTable = {
    methodCallCallback, 0, 0, { 0, }
};

static void busAcquiredCallback(GDBusConnection* connection, const char* name, gpointer userData)
{
    static GDBusNodeInfo* introspectionData = 0;
    if (!introspectionData)
        introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, 0);

    GUniqueOutPtr<GError> error;
    unsigned registrationID = g_dbus_connection_register_object(
        connection,
        "/org/webkit/gtk/WebExtensionTest",
        introspectionData->interfaces[0],
        &interfaceVirtualTable,
        g_object_ref(userData),
        static_cast<GDestroyNotify>(g_object_unref),
        &error.outPtr());
    if (!registrationID)
        g_warning("Failed to register object: %s\n", error->message);

    g_object_set_data(G_OBJECT(userData), "dbus-connection", connection);
    while (delayedSignalsQueue.size()) {
        DelayedSignal delayedSignal = delayedSignalsQueue.takeFirst();
        switch (delayedSignal.type) {
        case DocumentLoadedSignal:
            emitDocumentLoaded(connection);
            break;
        case URIChangedSignal:
            emitURIChanged(connection, delayedSignal.str.data());
            break;
        case FormControlsAssociatedSignal:
            emitFormControlsAssociated(connection, delayedSignal.str.data());
            break;
        case FormSubmissionWillCompleteSignal:
            emitFormSubmissionEvent(connection, "FormSubmissionWillComplete", delayedSignal.str.data(), delayedSignal.str2.data(), delayedSignal.str3.data(), delayedSignal.b, delayedSignal.b2);
            break;
        case FormSubmissionWillSendDOMEventSignal:
            emitFormSubmissionEvent(connection, "FormSubmissionWillSendDOMEvent", delayedSignal.str.data(), delayedSignal.str2.data(), delayedSignal.str3.data(), delayedSignal.b, delayedSignal.b2);
            break;
        }
    }
}

static void registerGResource(void)
{
    GUniquePtr<char> resourcesPath(g_build_filename(WEBKIT_TEST_RESOURCES_DIR, "webkitglib-tests-resources.gresource", nullptr));
    GResource* resource = g_resource_load(resourcesPath.get(), nullptr);
    g_assert_nonnull(resource);

    g_resources_register(resource);
    g_resource_unref(resource);
}

extern "C" void webkit_web_extension_initialize_with_user_data(WebKitWebExtension* extension, GVariant* userData)
{
    WebKitScriptWorld* isolatedWorld = webkit_script_world_new_with_name("WebExtensionTestScriptWorld");
    g_assert_true(WEBKIT_IS_SCRIPT_WORLD(isolatedWorld));
    g_assert_cmpstr(webkit_script_world_get_name(isolatedWorld), ==, "WebExtensionTestScriptWorld");
    g_object_set_data_full(G_OBJECT(extension), "wk-script-world", isolatedWorld, g_object_unref);

    g_signal_connect(extension, "page-created", G_CALLBACK(pageCreatedCallback), extension);
    g_signal_connect(webkit_script_world_get_default(), "window-object-cleared", G_CALLBACK(windowObjectCleared), nullptr);

    registerGResource();

    g_assert_nonnull(userData);
    g_assert_true(g_variant_is_of_type(userData, G_VARIANT_TYPE_UINT32));
    GUniquePtr<char> busName(g_strdup_printf("org.webkit.gtk.WebExtensionTest%u", g_variant_get_uint32(userData)));
    g_bus_own_name(
        G_BUS_TYPE_SESSION,
        busName.get(),
        G_BUS_NAME_OWNER_FLAGS_NONE,
        busAcquiredCallback,
        0, 0,
        g_object_ref(extension),
        static_cast<GDestroyNotify>(g_object_unref));
}
