/*
 * 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 Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2,1 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 "WebViewTest.h"
#include <gio/gunixfdlist.h>
#include <wtf/glib/GRefPtr.h>

static GUniquePtr<char> scriptDialogResult;

#define INPUT_ID "input-id"
#define FORM_ID "form-id"
#define FORM2_ID "form2-id"

#define FORM_SUBMISSION_TEST_ID "form-submission-test-id"

static void checkTitle(WebViewTest* test, GDBusProxy* proxy, const char* expectedTitle)
{
    GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
        proxy,
        "GetTitle",
        g_variant_new("(t)", webkit_web_view_get_page_id(test->m_webView)),
        G_DBUS_CALL_FLAGS_NONE,
        -1, 0, 0));
    g_assert_nonnull(result);

    const char* title;
    g_variant_get(result.get(), "(&s)", &title);
    g_assert_cmpstr(title, ==, expectedTitle);
}

static void testWebExtensionGetTitle(WebViewTest* test, gconstpointer)
{
    test->loadHtml("<html><head><title>WebKitGTK Web Extensions Test</title></head><body></body></html>", "http://bar.com");
    test->waitUntilLoadFinished();

    auto proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "WebKitGTK Web Extensions Test");
}

#if PLATFORM(GTK)
static gboolean inputElementIsUserEdited(GDBusProxy* proxy, uint64_t pageID, const char* elementID)
{
    GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
        proxy,
        "InputElementIsUserEdited",
        g_variant_new("(t&s)", pageID, elementID),
        G_DBUS_CALL_FLAGS_NONE,
        -1, nullptr, nullptr));
    g_assert_nonnull(result);

    gboolean retval;
    g_variant_get(result.get(), "(b)", &retval);
    return retval;
}

static void testWebExtensionInputElementIsUserEdited(WebViewTest* test, gconstpointer)
{
    test->showInWindowAndWaitUntilMapped();
    test->loadHtml("<html><body id='body'><input id='input'></input><textarea id='textarea'></textarea></body></html>", nullptr);
    test->waitUntilLoadFinished();

    auto proxy = test->extensionProxy();

    uint64_t pageID = webkit_web_view_get_page_id(test->m_webView);
    g_assert_false(inputElementIsUserEdited(proxy.get(), pageID, "input"));
    test->runJavaScriptAndWaitUntilFinished("document.getElementById('input').focus()", nullptr);
    test->keyStroke(GDK_KEY_a);
    while (gtk_events_pending())
        gtk_main_iteration();
    GUniquePtr<char> resultString;
    do {
        auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('input').value", nullptr);
        resultString.reset(WebViewTest::javascriptResultToCString(result));
    } while (g_strcmp0(resultString.get(), "a"));
    g_assert_true(inputElementIsUserEdited(proxy.get(), pageID, "input"));

    g_assert_false(inputElementIsUserEdited(proxy.get(), pageID, "textarea"));
    test->runJavaScriptAndWaitUntilFinished("document.getElementById('textarea').focus()", nullptr);
    test->keyStroke(GDK_KEY_b);
    while (gtk_events_pending())
        gtk_main_iteration();
    do {
        auto* result = test->runJavaScriptAndWaitUntilFinished("document.getElementById('textarea').value", nullptr);
        resultString.reset(WebViewTest::javascriptResultToCString(result));
    } while (g_strcmp0(resultString.get(), "b"));
    g_assert_true(inputElementIsUserEdited(proxy.get(), pageID, "textarea"));

    g_assert_false(inputElementIsUserEdited(proxy.get(), pageID, "body"));
}
#endif

static void documentLoadedCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant*, WebViewTest* test)
{
    g_main_loop_quit(test->m_mainLoop);
}

static void testDocumentLoadedSignal(WebViewTest* test, gconstpointer)
{
    auto proxy = test->extensionProxy();

    GDBusConnection* connection = g_dbus_proxy_get_connection(proxy.get());
    guint id = g_dbus_connection_signal_subscribe(connection,
        nullptr,
        "org.webkit.gtk.WebExtensionTest",
        "DocumentLoaded",
        "/org/webkit/gtk/WebExtensionTest",
        nullptr,
        G_DBUS_SIGNAL_FLAGS_NONE,
        reinterpret_cast<GDBusSignalCallback>(documentLoadedCallback),
        test,
        nullptr);
    g_assert_cmpuint(id, !=, 0);

    test->loadHtml("<html><head><title>WebKitGTK Web Extensions Test</title></head><body></body></html>", nullptr);
    g_main_loop_run(test->m_mainLoop);
    g_dbus_connection_signal_unsubscribe(connection, id);
}

static gboolean webProcessTerminatedCallback(WebKitWebView*, WebKitWebProcessTerminationReason reason, WebViewTest* test)
{
    g_assert_cmpuint(reason, ==, WEBKIT_WEB_PROCESS_CRASHED);
    test->quitMainLoop();

    return FALSE;
}

static void testWebKitWebViewProcessCrashed(WebViewTest* test, gconstpointer)
{
    test->loadHtml("<html></html>", nullptr);
    test->waitUntilLoadFinished();

    g_signal_connect_after(test->m_webView, "web-process-terminated",
        G_CALLBACK(webProcessTerminatedCallback), test);

    test->m_expectedWebProcessCrash = true;

    auto proxy = test->extensionProxy();
    GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
        proxy.get(),
        "AbortProcess",
        0,
        G_DBUS_CALL_FLAGS_NONE,
        -1, 0, 0));
    g_assert_null(result);
    g_main_loop_run(test->m_mainLoop);
    test->m_expectedWebProcessCrash = false;
}

static void testWebExtensionWindowObjectCleared(WebViewTest* test, gconstpointer)
{
    test->loadHtml("<html><header></header><body></body></html>", 0);
    test->waitUntilLoadFinished();

    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.echo('Foo');", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "Foo");

    javascriptResult = test->runJavaScriptAndWaitUntilFinished("var f = new GFile('.'); f.path();", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
    GUniquePtr<char> currentDirectory(g_get_current_dir());
    g_assert_cmpstr(valueString.get(), ==, currentDirectory.get());
}

static gboolean scriptDialogCallback(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
{
    g_assert_cmpuint(webkit_script_dialog_get_dialog_type(dialog), ==, WEBKIT_SCRIPT_DIALOG_ALERT);
    scriptDialogResult.reset(g_strdup(webkit_script_dialog_get_message(dialog)));
    return TRUE;
}

static void runJavaScriptInIsolatedWorldFinishedCallback(GDBusProxy* proxy, GAsyncResult* result, WebViewTest* test)
{
    g_dbus_proxy_call_finish(proxy, result, 0);
    g_main_loop_quit(test->m_mainLoop);
}

static void testWebExtensionIsolatedWorld(WebViewTest* test, gconstpointer)
{
    test->loadHtml("<html><header></header><body><div id='console'></div></body></html>", 0);
    test->waitUntilLoadFinished();

    gulong scriptDialogID = g_signal_connect(test->m_webView, "script-dialog", G_CALLBACK(scriptDialogCallback), nullptr);

    static const char* mainWorldScript =
        "top.foo = 'Foo';\n"
        "document.getElementById('console').innerHTML = top.foo;\n"
        "window.open = function () { alert('Main World'); }\n"
        "window.open();";
    test->runJavaScriptAndWaitUntilFinished(mainWorldScript, 0);
    g_assert_cmpstr(scriptDialogResult.get(), ==, "Main World");

    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0);
    g_assert_nonnull(javascriptResult);
    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "Foo");

    static const char* isolatedWorldScript =
        "document.getElementById('console').innerHTML = top.foo;\n"
        "window.open = function () { alert('Isolated World'); }\n"
        "window.open();";
    auto proxy = test->extensionProxy();
    g_dbus_proxy_call(proxy.get(),
        "RunJavaScriptInIsolatedWorld",
        g_variant_new("(t&s)", webkit_web_view_get_page_id(test->m_webView), isolatedWorldScript),
        G_DBUS_CALL_FLAGS_NONE,
        -1, 0,
        reinterpret_cast<GAsyncReadyCallback>(runJavaScriptInIsolatedWorldFinishedCallback),
        test);
    g_main_loop_run(test->m_mainLoop);
    g_assert_cmpstr(scriptDialogResult.get(), ==, "Isolated World");

    // Check that 'top.foo' defined in main world is not visible in isolated world.
    javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0);
    g_assert_nonnull(javascriptResult);
    valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "undefined");

    g_signal_handler_disconnect(test->m_webView, scriptDialogID);
}

#if PLATFORM(GTK)
static gboolean permissionRequestCallback(WebKitWebView*, WebKitPermissionRequest* request, WebViewTest* test)
{
    if (!WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request))
        return FALSE;

    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
    WebKitInstallMissingMediaPluginsPermissionRequest* missingPluginsRequest = WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request);
    g_assert_nonnull(webkit_install_missing_media_plugins_permission_request_get_description(missingPluginsRequest));
    webkit_permission_request_deny(request);
    test->quitMainLoop();

    return TRUE;
}

static void testInstallMissingPluginsPermissionRequest(WebViewTest* test, gconstpointer)
{
    auto proxy = test->extensionProxy();
    GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(proxy.get(), "RemoveAVPluginsFromGSTRegistry",
        nullptr, G_DBUS_CALL_FLAGS_NONE, -1, nullptr, nullptr));

    test->showInWindowAndWaitUntilMapped();

    gulong permissionRequestSignalID = g_signal_connect(test->m_webView, "permission-request", G_CALLBACK(permissionRequestCallback), test);
    // FIXME: the base URI needs to finish with / to work, that shouldn't happen.
    GUniquePtr<char> baseURI(g_strconcat("file://", Test::getResourcesDir(Test::WebKit2Resources).data(), "/", nullptr));
    test->loadHtml("<html><body><video src=\"test.mp4\" autoplay></video></body></html>", baseURI.get());
    g_main_loop_run(test->m_mainLoop);
    g_signal_handler_disconnect(test->m_webView, permissionRequestSignalID);
}
#endif // PLATFORM(GTK)

static void didAssociateFormControlsCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, WebViewTest* test)
{
    const char* formIds;
    g_variant_get(result, "(&s)", &formIds);
    g_assert_true(!g_strcmp0(formIds, FORM_ID FORM2_ID) || !g_strcmp0(formIds, FORM2_ID FORM_ID) || !g_strcmp0(formIds, INPUT_ID));

    test->quitMainLoop();
}

static void testWebExtensionFormControlsAssociated(WebViewTest* test, gconstpointer)
{
    auto proxy = test->extensionProxy();
    GDBusConnection* connection = g_dbus_proxy_get_connection(proxy.get());
    guint id = g_dbus_connection_signal_subscribe(connection,
        nullptr,
        "org.webkit.gtk.WebExtensionTest",
        "FormControlsAssociated",
        "/org/webkit/gtk/WebExtensionTest",
        nullptr,
        G_DBUS_SIGNAL_FLAGS_NONE,
        reinterpret_cast<GDBusSignalCallback>(didAssociateFormControlsCallback),
        test,
        nullptr);
    g_assert_cmpuint(id, !=, 0);

    test->loadHtml("<!DOCTYPE html><head><title>WebKitGTK Web Extensions Test</title></head><div id=\"placeholder\"/>", 0);
    test->waitUntilLoadFinished();

    static const char* addFormScript =
        "var input = document.createElement(\"input\");"
        "input.id = \"" INPUT_ID "\";"
        "input.type = \"password\";"
        "var form = document.createElement(\"form\");"
        "form.id = \"" FORM_ID "\";"
        "form.appendChild(input);"
        "var form2 = document.createElement(\"form\");"
        "form2.id = \"" FORM2_ID "\";"
        "var placeholder = document.getElementById(\"placeholder\");"
        "placeholder.appendChild(form);"
        "placeholder.appendChild(form2);";

    webkit_web_view_run_javascript(test->m_webView, addFormScript, nullptr, nullptr, nullptr);
    g_main_loop_run(test->m_mainLoop);

    static const char* moveFormElementScript =
        "var form = document.getElementById(\"" FORM_ID "\");"
        "var form2 = document.getElementById(\"" FORM2_ID "\");"
        "var input = document.getElementById(\"" INPUT_ID "\");"
        "form.removeChild(input);"
        "form2.appendChild(input);";

    webkit_web_view_run_javascript(test->m_webView, moveFormElementScript, nullptr, nullptr, nullptr);
    g_main_loop_run(test->m_mainLoop);

    g_dbus_connection_signal_unsubscribe(connection, id);
}

class FormSubmissionTest : public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(FormSubmissionTest);

    FormSubmissionTest()
    {
        m_proxy = extensionProxy();
        GDBusConnection* connection = g_dbus_proxy_get_connection(m_proxy.get());

        m_willSendDOMEventCallbackID = g_dbus_connection_signal_subscribe(connection,
            nullptr,
            "org.webkit.gtk.WebExtensionTest",
            "FormSubmissionWillSendDOMEvent",
            "/org/webkit/gtk/WebExtensionTest",
            nullptr,
            G_DBUS_SIGNAL_FLAGS_NONE,
            reinterpret_cast<GDBusSignalCallback>(willSendDOMEventCallback),
            this,
            nullptr);
        g_assert_cmpuint(m_willSendDOMEventCallbackID, !=, 0);

        m_willCompleteCallbackID = g_dbus_connection_signal_subscribe(connection,
            nullptr,
            "org.webkit.gtk.WebExtensionTest",
            "FormSubmissionWillComplete",
            "/org/webkit/gtk/WebExtensionTest",
            nullptr,
            G_DBUS_SIGNAL_FLAGS_NONE,
            reinterpret_cast<GDBusSignalCallback>(willCompleteCallback),
            this,
            nullptr);
        g_assert_cmpuint(m_willCompleteCallbackID, !=, 0);
    }

    ~FormSubmissionTest()
    {
        GDBusConnection* connection = g_dbus_proxy_get_connection(m_proxy.get());
        g_dbus_connection_signal_unsubscribe(connection, m_willSendDOMEventCallbackID);
        g_dbus_connection_signal_unsubscribe(connection, m_willCompleteCallbackID);
    }

    static void testFormSubmissionResult(GVariant* result)
    {
        const char* formID;
        const char* concatenatedTextFieldNames;
        const char* concatenatedTextFieldValues;
        gboolean targetFrameIsMainFrame;
        gboolean sourceFrameIsMainFrame;
        g_variant_get(result, "(&s&s&sbb)", &formID, &concatenatedTextFieldNames, &concatenatedTextFieldValues, &targetFrameIsMainFrame, &sourceFrameIsMainFrame);

        g_assert_cmpstr(formID, ==, FORM_SUBMISSION_TEST_ID);
        g_assert_cmpstr(concatenatedTextFieldNames, ==, "foo,bar,");
        g_assert_cmpstr(concatenatedTextFieldValues, ==, "first,second,");
        g_assert_false(targetFrameIsMainFrame);
        g_assert_true(sourceFrameIsMainFrame);
    }

    static void willSendDOMEventCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, FormSubmissionTest* test)
    {
        test->m_willSendDOMEventCallbackExecuted = true;
        testFormSubmissionResult(result);
    }

    static void willCompleteCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant* result, FormSubmissionTest* test)
    {
        test->m_willCompleteCallbackExecuted = true;
        testFormSubmissionResult(result);
        test->quitMainLoop();
    }

    void runJavaScriptAndWaitUntilFormSubmitted(const char* js)
    {
        webkit_web_view_run_javascript(m_webView, js, nullptr, nullptr, nullptr);
        g_main_loop_run(m_mainLoop);
    }

    GRefPtr<GDBusProxy> m_proxy;
    guint m_willSendDOMEventCallbackID { 0 };
    guint m_willCompleteCallbackID { 0 };
    bool m_willSendDOMEventCallbackExecuted { false };
    bool m_willCompleteCallbackExecuted { false };
};

static void testWebExtensionFormSubmissionSteps(FormSubmissionTest* test, gconstpointer)
{
    test->loadHtml("<form id=\"" FORM_SUBMISSION_TEST_ID "\" target=\"target_frame\">"
        "<input type=\"text\" name=\"foo\" value=\"first\">"
        "<input type=\"text\" name=\"bar\" value=\"second\">"
        "<input type=\"submit\" id=\"submit_button\">"
        "</form>"
        "<iframe name=\"target_frame\"></iframe>", nullptr);
    test->waitUntilLoadFinished();

    static const char* submitFormScript =
        "var form = document.getElementById(\"" FORM_SUBMISSION_TEST_ID "\");"
        "form.submit();";
    test->runJavaScriptAndWaitUntilFormSubmitted(submitFormScript);
    // Submit must not be emitted when the form is submitted via JS.
    // https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
    g_assert_false(test->m_willSendDOMEventCallbackExecuted);
    g_assert_true(test->m_willCompleteCallbackExecuted);
    test->m_willCompleteCallbackExecuted = false;

    static const char* manuallySubmitFormScript =
        "var button = document.getElementById(\"submit_button\");"
        "button.click();";
    test->runJavaScriptAndWaitUntilFormSubmitted(manuallySubmitFormScript);
    g_assert_true(test->m_willSendDOMEventCallbackExecuted);
    g_assert_true(test->m_willCompleteCallbackExecuted);
    test->m_willSendDOMEventCallbackExecuted = false;
    test->m_willCompleteCallbackExecuted = false;

    test->loadHtml("<form id=\"" FORM_SUBMISSION_TEST_ID "\" target=\"target_frame\">"
        "</form>"
        "<iframe name=\"target_frame\"></iframe>", nullptr);
    test->waitUntilLoadFinished();
}

static void webViewPageIDChanged(WebKitWebView* webView, GParamSpec*, bool* pageIDChangedEmitted)
{
    *pageIDChangedEmitted = true;
    g_assert_nonnull(Test::s_dbusConnectionPageMap.get(webkit_web_view_get_page_id(webView)));
}

static void testWebExtensionPageID(WebViewTest* test, gconstpointer)
{
    auto pageID = webkit_web_view_get_page_id(test->m_webView);
    g_assert_cmpuint(pageID, >=, 1);

    bool pageIDChangedEmitted = false;
    g_signal_connect(test->m_webView, "notify::page-id", G_CALLBACK(webViewPageIDChanged), &pageIDChangedEmitted);

    test->loadHtml("<html><head><title>Title1</title></head><body></body></html>", "http://foo.com");
    test->waitUntilLoadFinished();
    g_assert_false(pageIDChangedEmitted);
    g_assert_cmpuint(pageID, ==, webkit_web_view_get_page_id(test->m_webView));
    auto proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title1");

    test->loadHtml("<html><head><title>Title2</title></head><body></body></html>", "http://foo.com/bar");
    test->waitUntilLoadFinished();
    g_assert_false(pageIDChangedEmitted);
    g_assert_cmpuint(pageID, ==, webkit_web_view_get_page_id(test->m_webView));
    checkTitle(test, proxy.get(), "Title2");

    test->loadHtml("<html><head><title>Title3</title></head><body></body></html>", "http://bar.com");
    test->waitUntilLoadFinished();
    g_assert_true(pageIDChangedEmitted);
    pageIDChangedEmitted = false;
    g_assert_cmpuint(pageID, <, webkit_web_view_get_page_id(test->m_webView));
    pageID = webkit_web_view_get_page_id(test->m_webView);
    proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title3");

    test->loadHtml("<html><head><title>Title4</title></head><body></body></html>", "http://bar.com/foo");
    test->waitUntilLoadFinished();
    g_assert_false(pageIDChangedEmitted);
    g_assert_cmpuint(pageID, ==, webkit_web_view_get_page_id(test->m_webView));
    checkTitle(test, proxy.get(), "Title4");

    // Register a custom URI scheme to test history navigation.
    webkit_web_context_register_uri_scheme(test->m_webContext.get(), "foo",
        [](WebKitURISchemeRequest* request, gpointer) {
            SoupURI* uri = soup_uri_new(webkit_uri_scheme_request_get_uri(request));
            GRefPtr<GInputStream> inputStream = adoptGRef(g_memory_input_stream_new());
            char* html = g_strdup_printf("<html><head><title>%s</title></head><body></body></html>", !strcmp(uri->host, "host5") ? "Title5" : "Title6");
            soup_uri_free(uri);
            g_memory_input_stream_add_data(G_MEMORY_INPUT_STREAM(inputStream.get()), html, strlen(html), g_free);
            webkit_uri_scheme_request_finish(request, inputStream.get(), strlen(html), "text/html");
        }, nullptr, nullptr);

    test->loadURI("foo://host5/");
    test->waitUntilLoadFinished();
    g_assert_true(pageIDChangedEmitted);
    pageIDChangedEmitted = false;
    g_assert_cmpuint(pageID, <, webkit_web_view_get_page_id(test->m_webView));
    pageID = webkit_web_view_get_page_id(test->m_webView);
    proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title5");

    test->loadURI("foo://host6/");
    test->waitUntilLoadFinished();
    g_assert_true(pageIDChangedEmitted);
    pageIDChangedEmitted = false;
    g_assert_cmpuint(pageID, <, webkit_web_view_get_page_id(test->m_webView));
    pageID = webkit_web_view_get_page_id(test->m_webView);
    proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title6");

    test->goBack();
    test->waitUntilLoadFinished();
    g_assert_true(pageIDChangedEmitted);
    pageIDChangedEmitted = false;
    g_assert_cmpuint(pageID, >, webkit_web_view_get_page_id(test->m_webView));
    pageID = webkit_web_view_get_page_id(test->m_webView);
    proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title5");

    test->goForward();
    test->waitUntilLoadFinished();
    g_assert_true(pageIDChangedEmitted);
    pageIDChangedEmitted = false;
    g_assert_cmpuint(pageID, <, webkit_web_view_get_page_id(test->m_webView));
    pageID = webkit_web_view_get_page_id(test->m_webView);
    proxy = test->extensionProxy();
    checkTitle(test, proxy.get(), "Title6");
}

class UserMessageTest : public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(UserMessageTest);

    static gboolean webViewUserMessageReceivedCallback(WebKitWebView*, WebKitUserMessage* message, UserMessageTest* test)
    {
        return test->viewUserMessageReceived(message);
    }

    static gboolean webContextUserMessageReceivedCallback(WebKitWebContext*, WebKitUserMessage* message, UserMessageTest* test)
    {
        return test->contextUserMessageReceived(message);
    }

    UserMessageTest()
    {
        g_signal_connect(m_webContext.get(), "user-message-received", G_CALLBACK(webContextUserMessageReceivedCallback), this);
        g_signal_connect(m_webView, "user-message-received", G_CALLBACK(webViewUserMessageReceivedCallback), this);
    }

    ~UserMessageTest()
    {
        g_signal_handlers_disconnect_matched(m_webContext.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
        g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
    }

    WebKitUserMessage* sendMessage(WebKitUserMessage* message, GError** error = nullptr)
    {
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
        m_receivedViewMessage = nullptr;
        webkit_web_view_send_message_to_page(m_webView, message, nullptr, [](GObject*, GAsyncResult* result, gpointer userData) {
            auto* test = static_cast<UserMessageTest*>(userData);
            test->m_receivedViewMessage = adoptGRef(webkit_web_view_send_message_to_page_finish(test->m_webView, result, &test->m_receivedError.outPtr()));
            if (test->m_receivedViewMessage)
                test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(test->m_receivedViewMessage.get()));
            else
                g_assert_nonnull(test->m_receivedError.get());
            test->quitMainLoop();
        }, this);
        g_main_loop_run(m_mainLoop);
        if (error)
            *error = m_receivedError.get();
        return m_receivedViewMessage.get();
    }

    void sendMessageToAllExtensions(WebKitUserMessage* message)
    {
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
        webkit_web_context_send_message_to_all_extensions(m_webContext.get(), message);
    }

    bool viewUserMessageReceived(WebKitUserMessage* message)
    {
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
        if (!g_strcmp0(m_expectedViewMessageName.data(), webkit_user_message_get_name(message))) {
            m_receivedViewMessage = message;
            quitMainLoop();

            return true;
        }

        return false;
    }

    bool contextUserMessageReceived(WebKitUserMessage* message)
    {
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(message));
        if (!g_strcmp0(m_expectedContextMessageName.data(), webkit_user_message_get_name(message))) {
            m_receivedContextMessage = message;
            quitMainLoop();

            return true;
        }

        return false;
    }

    WebKitUserMessage* waitUntilViewMessageReceived(const char* messageName)
    {
        m_expectedViewMessageName = messageName;
        g_main_loop_run(m_mainLoop);
        m_expectedViewMessageName = { };
        return m_receivedViewMessage.get();
    }

    WebKitUserMessage* waitUntilContextMessageReceived(const char* messageName)
    {
        m_expectedContextMessageName = messageName;
        g_main_loop_run(m_mainLoop);
        m_expectedContextMessageName = { };
        return m_receivedContextMessage.get();
    }

    GRefPtr<WebKitUserMessage> m_receivedViewMessage;
    GRefPtr<WebKitUserMessage> m_receivedContextMessage;
    GUniqueOutPtr<GError> m_receivedError;
    CString m_expectedViewMessageName;
    CString m_expectedContextMessageName;
};

static bool readFileDescriptor(int fd, char** contents, gsize* length)
{
    GString* bufferString = g_string_new(nullptr);
    while (true) {
        gchar buffer[4096];
        gssize bytesRead = read(fd, buffer, sizeof(buffer));
        if (bytesRead == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                continue;

            g_string_free(bufferString, TRUE);

            return false;
        }

        if (!bytesRead)
            break;

        g_string_append_len(bufferString, buffer, bytesRead);
    }

    *length = bufferString->len;
    *contents = g_string_free(bufferString, FALSE);

    return true;
}

static void testWebExtensionUserMessages(UserMessageTest* test, gconstpointer)
{
    // Normal message with a reply.
    auto* message = webkit_user_message_new("Test.Hello", g_variant_new("s", "WebProcess"));
    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.Hello");
    auto* parameters = webkit_user_message_get_parameters(message);
    g_assert_nonnull(parameters);
    const char* parameter = nullptr;
    g_variant_get(parameters, "&s", &parameter);
    g_assert_cmpstr(parameter, ==, "WebProcess");
    g_assert_null(webkit_user_message_get_fd_list(message));
    auto* reply = test->sendMessage(message);
    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Hello");
    parameters = webkit_user_message_get_parameters(reply);
    g_assert_nonnull(parameters);
    parameter = nullptr;
    g_variant_get(parameters, "&s", &parameter);
    g_assert_cmpstr(parameter, ==, "UIProcess");
    g_assert_null(webkit_user_message_get_fd_list(reply));

    // Message with no parameters.
    message = webkit_user_message_new("Test.Ping", nullptr);
    g_assert_null(webkit_user_message_get_parameters(message));
    reply = test->sendMessage(message);
    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Pong");
    g_assert_null(webkit_user_message_get_parameters(reply));

    // Message with maybe type in parameters.
    message = webkit_user_message_new("Test.Optional", g_variant_new("(sms)", "Hello", "World"));
    reply = test->sendMessage(message);
    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Optional");
    parameters = webkit_user_message_get_parameters(reply);
    g_assert_nonnull(parameters);
    g_variant_get(parameters, "&s", &parameter);
    g_assert_cmpstr(parameter, ==, "World");
    message = webkit_user_message_new("Test.Optional", g_variant_new("(sms)", "Hello", nullptr));
    reply = test->sendMessage(message);
    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
    g_assert_cmpstr(webkit_user_message_get_name(reply), ==, "Test.Optional");
    parameters = webkit_user_message_get_parameters(reply);
    g_assert_nonnull(parameters);
    g_variant_get(parameters, "&s", &parameter);
    g_assert_cmpstr(parameter, ==, "NULL");

    // Message with file descriptors.
    GUniquePtr<char> filename(g_build_filename(Test::getResourcesDir().data(), "simple.json", nullptr));
    reply = test->sendMessage(webkit_user_message_new("Test.OpenFile", g_variant_new("s", filename.get())));
    g_assert_true(WEBKIT_IS_USER_MESSAGE(reply));
    parameters = webkit_user_message_get_parameters(reply);
    g_assert_nonnull(parameters);
    gint32 handle;
    g_variant_get(parameters, "h", &handle);
    g_assert_cmpint(handle, ==, 0);
    auto* fdList = webkit_user_message_get_fd_list(reply);
    g_assert_true(G_IS_UNIX_FD_LIST(fdList));
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(fdList));
    g_assert_cmpint(g_unix_fd_list_get_length(fdList), ==, 1);
    GUniqueOutPtr<GError> error;
    int fd = g_unix_fd_list_get(fdList, handle, &error.outPtr());
    g_assert_cmpint(fd, !=, -1);
    g_assert_no_error(error.get());
    GUniqueOutPtr<char> fdContents;
    gsize fdContentsLength;
    g_assert_true(readFileDescriptor(fd, &fdContents.outPtr(), &fdContentsLength));
    close(fd);
    GUniqueOutPtr<char> fileContents;
    gsize fileContentsLength;
    g_assert_true(g_file_get_contents(filename.get(), &fileContents.outPtr(), &fileContentsLength, nullptr));
    g_assert_cmpmem(fdContents.get(), fdContentsLength, fileContents.get(), fileContentsLength);

    // Unhandled message.
    GError* messageError = nullptr;
    reply = test->sendMessage(webkit_user_message_new("Test.Invalid", nullptr), &messageError);
    g_assert_null(reply);
    g_assert_error(messageError, WEBKIT_USER_MESSAGE_ERROR, WEBKIT_USER_MESSAGE_UNHANDLED_MESSAGE);

    // Message that is never replied.
    GRefPtr<WebKitWebView> webView = WEBKIT_WEB_VIEW(Test::createWebView(test->m_webContext.get()));
    webkit_web_view_send_message_to_page(webView.get(), webkit_user_message_new("Test.Infinite", nullptr), nullptr,
        [](GObject* object, GAsyncResult* result, gpointer userData) {
            auto* test = static_cast<UserMessageTest*>(userData);
            GUniqueOutPtr<GError> error;
            g_assert_null(webkit_web_view_send_message_to_page_finish(WEBKIT_WEB_VIEW(object), result, &error.outPtr()));
            g_assert_error(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED);
            test->quitMainLoop();
        }, test);
    g_main_loop_run(test->m_mainLoop);

    // Wait for received message.
    test->loadHtml("<html><body></body></html>", nullptr);
    message = test->waitUntilViewMessageReceived("DocumentLoaded");
    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "DocumentLoaded");

    // Reply to a message received from the web process.
    webkit_web_view_send_message_to_page(test->m_webView, webkit_user_message_new("Test.AsyncPing", nullptr), nullptr, nullptr, nullptr);
    message = test->waitUntilViewMessageReceived("Test.Ping");
    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.Ping");
    webkit_user_message_send_reply(message, webkit_user_message_new("Test.Pong", nullptr));
    message = test->waitUntilViewMessageReceived("Test.AsyncPong");
    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "Test.AsyncPong");

    // Create a new page and wait for page created message.
    webView = WEBKIT_WEB_VIEW(Test::createWebView(test->m_webContext.get()));
    webkit_web_view_load_html(webView.get(), "<html><body></body></html>", nullptr);
    message = test->waitUntilContextMessageReceived("PageCreated");
    g_assert_true(WEBKIT_IS_USER_MESSAGE(message));
    g_assert_cmpstr(webkit_user_message_get_name(message), ==, "PageCreated");
    parameters = webkit_user_message_get_parameters(message);
    g_assert_nonnull(parameters);
    guint64 pageID;
    g_variant_get(parameters, "(t)", &pageID);
    g_assert_cmpuint(pageID, ==, webkit_web_view_get_page_id(webView.get()));

    // Request to start a ping to all processes.
    test->sendMessageToAllExtensions(webkit_user_message_new("Test.RequestPing", nullptr));
    // We should received two ping requests.
    GRefPtr<WebKitUserMessage> ping1 = test->waitUntilContextMessageReceived("Ping");
    GRefPtr<WebKitUserMessage> ping2 = test->waitUntilContextMessageReceived("Ping");
    webkit_user_message_send_reply(ping1.get(), webkit_user_message_new("Pong", nullptr));
    test->waitUntilContextMessageReceived("Test.FinishedPingRequest");
    webkit_user_message_send_reply(ping2.get(), webkit_user_message_new("Pong", nullptr));
    test->waitUntilContextMessageReceived("Test.FinishedPingRequest");
}

void beforeAll()
{
    WebViewTest::add("WebKitWebExtension", "dom-document-title", testWebExtensionGetTitle);
#if PLATFORM(GTK)
    WebViewTest::add("WebKitWebExtension", "dom-input-element-is-user-edited", testWebExtensionInputElementIsUserEdited);
#endif
    WebViewTest::add("WebKitWebExtension", "document-loaded-signal", testDocumentLoadedSignal);
    WebViewTest::add("WebKitWebView", "web-process-crashed", testWebKitWebViewProcessCrashed);
    WebViewTest::add("WebKitWebExtension", "window-object-cleared", testWebExtensionWindowObjectCleared);
    WebViewTest::add("WebKitWebExtension", "isolated-world", testWebExtensionIsolatedWorld);
#if PLATFORM(GTK)
    WebViewTest::add("WebKitWebView", "install-missing-plugins-permission-request", testInstallMissingPluginsPermissionRequest);
#endif
    WebViewTest::add("WebKitWebExtension", "form-controls-associated-signal", testWebExtensionFormControlsAssociated);
    FormSubmissionTest::add("WebKitWebExtension", "form-submission-steps", testWebExtensionFormSubmissionSteps);
    WebViewTest::add("WebKitWebExtension", "page-id", testWebExtensionPageID);
    UserMessageTest::add("WebKitWebExtension", "user-messages", testWebExtensionUserMessages);
}

void afterAll()
{
}
