/*
 * Copyright (C) 2013-2014 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 "WebKitTestServer.h"
#include "WebViewTest.h"
#include <WebCore/SoupVersioning.h>
#include <cstdarg>
#include <wtf/glib/GRefPtr.h>
#include <wtf/glib/GUniquePtr.h>

static WebKitTestServer* kServer;

// These are all here so that they can be changed easily, if necessary.
static const char* kTestHTML =
"<html>\n"
"  <head><link rel=\"stylesheet\" type=\"text/css\" href=\"/extra.css\"></head>\n"
"  <body>\n"
"    <div id=\"styledElement\">Sweet stylez!</div>\n"
"    <div id=\"otherElement\">Blocked stylez!</div>\n"
"  </body>\n"
"</html>";

static const char* kTestCSS =
"div#otherElement {\n"
"  font-weight: bold;\n"
"}\n";

static const char* kInjectedStyleSheet = "#styledElement { font-weight: bold; }";
static const char* kStyleSheetTestScript = "getComputedStyle(document.getElementById('styledElement'))['font-weight']";
static const char* kStyleSheetTestScriptResult = "bold";
static const char* kInjectedScript = "document.write('<div id=\"item\">Generated by a script</div>')";
static const char* kScriptTestScript = "document.getElementById('item').innerText";
static const char* kScriptTestScriptResult = "Generated by a script";
static const char* kScriptTestCSSBlocked = "getComputedStyle(document.getElementById('otherElement'))['font-weight']";
static const char* kScriptTestCSSBlockedResult = "normal";
static const char* kJSONFilter =
"[\n"
"  {\n"
"    \"trigger\": {\n"
"      \"url-filter\": \".*\",\n"
"      \"resource-type\": [\"style-sheet\"]\n"
"    },\n"
"    \"action\": {\n"
"      \"type\": \"block\"\n"
"    }\n"
"  }\n"
"]\n";

static void testWebViewNewWithUserContentManager(Test* test, gconstpointer)
{
    GRefPtr<WebKitUserContentManager> userContentManager1 = adoptGRef(webkit_user_content_manager_new());
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(userContentManager1.get()));
    auto webView1 = Test::adoptView(Test::createWebView(userContentManager1.get()));
    g_assert_true(webkit_web_view_get_user_content_manager(webView1.get()) == userContentManager1.get());

    auto webView2 = Test::adoptView(Test::createWebView());
    g_assert_true(webkit_web_view_get_user_content_manager(webView2.get()) != userContentManager1.get());
}

static bool isStyleSheetInjectedForURLAtPath(WebViewTest* test, const char* path, const char* world = nullptr)
{
    test->loadURI(kServer->getURIForPath(path).data());
    test->waitUntilLoadFinished();

    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = world ? test->runJavaScriptInWorldAndWaitUntilFinished(kStyleSheetTestScript, world, &error.outPtr())
        : test->runJavaScriptAndWaitUntilFinished(kStyleSheetTestScript, &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());

    GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
    return !g_strcmp0(resultString.get(), kStyleSheetTestScriptResult);
}

static bool isScriptInjectedForURLAtPath(WebViewTest* test, const char* path, const char* world = nullptr)
{
    test->loadURI(kServer->getURIForPath(path).data());
    test->waitUntilLoadFinished();

    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = world ? test->runJavaScriptInWorldAndWaitUntilFinished(kScriptTestScript, world, &error.outPtr())
        : test->runJavaScriptAndWaitUntilFinished(kScriptTestScript, &error.outPtr());
    if (javascriptResult) {
        g_assert_no_error(error.get());

        GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
        return !g_strcmp0(resultString.get(), kScriptTestScriptResult);
    }
    return false;
}

static void fillURLListFromPaths(char** list, const char* path, ...)
{
    va_list argumentList;
    va_start(argumentList, path);

    int i = 0;
    while (path) {
        // FIXME: We must use a wildcard for the host here until http://wkbug.com/112476 is fixed.
        // Until that time patterns with port numbers in them will not properly match URLs with port numbers.
        list[i++] = g_strdup_printf("http://*/%s*", path);
        path = va_arg(argumentList, const char*);
    }
}

static void removeOldInjectedContentAndResetLists(WebKitUserContentManager* userContentManager, char** allowList, char** blockList)
{
    webkit_user_content_manager_remove_all_style_sheets(userContentManager);
    webkit_user_content_manager_remove_all_scripts(userContentManager);
    webkit_user_content_manager_remove_all_filters(userContentManager);

    while (*allowList) {
        g_free(*allowList);
        *allowList = 0;
        allowList++;
    }

    while (*blockList) {
        g_free(*blockList);
        *blockList = 0;
        blockList++;
    }
}

static void testUserContentManagerInjectedStyleSheet(WebViewTest* test, gconstpointer)
{
    char* allowList[3] = { 0, 0, 0 };
    char* blockList[3] = { 0, 0, 0 };

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    // Without a allowList or a blockList all URLs should have the injected style sheet.
    static const char* randomPath = "somerandompath";
    g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
    WebKitUserStyleSheet* styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, nullptr);
    webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
    webkit_user_style_sheet_unref(styleSheet);
    g_assert_true(isStyleSheetInjectedForURLAtPath(test, randomPath));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
    styleSheet = webkit_user_style_sheet_new_for_world(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, "WebExtensionTestScriptWorld", nullptr, nullptr);
    webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
    webkit_user_style_sheet_unref(styleSheet);
    g_assert_true(isStyleSheetInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    fillURLListFromPaths(blockList, randomPath, 0);
    styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, blockList);
    webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
    webkit_user_style_sheet_unref(styleSheet);
    g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
    g_assert_true(isStyleSheetInjectedForURLAtPath(test, "someotherrandompath"));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    static const char* inTheAllowList = "intheallowlist";
    static const char* notInAllowList = "notintheallowlist";
    static const char* inTheAllowListAndBlockList = "intheallowlistandblocklist";

    fillURLListFromPaths(allowList, inTheAllowList, inTheAllowListAndBlockList, 0);
    fillURLListFromPaths(blockList, inTheAllowListAndBlockList, 0);
    styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, allowList, blockList);
    webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
    webkit_user_style_sheet_unref(styleSheet);
    g_assert_true(isStyleSheetInjectedForURLAtPath(test, inTheAllowList));
    g_assert_false(isStyleSheetInjectedForURLAtPath(test, inTheAllowListAndBlockList));
    g_assert_false(isStyleSheetInjectedForURLAtPath(test, notInAllowList));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
    styleSheet = webkit_user_style_sheet_new(kInjectedStyleSheet, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_STYLE_LEVEL_USER, nullptr, nullptr);
    webkit_user_content_manager_add_style_sheet(test->m_userContentManager.get(), styleSheet);
    g_assert_true(isStyleSheetInjectedForURLAtPath(test, randomPath));
    webkit_user_content_manager_remove_style_sheet(test->m_userContentManager.get(), styleSheet);
    g_assert_false(isStyleSheetInjectedForURLAtPath(test, randomPath));
    webkit_user_style_sheet_unref(styleSheet);

    // It's important to clean up the environment before other tests.
    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);
}

static void testUserContentManagerInjectedScript(WebViewTest* test, gconstpointer)
{
    char* allowList[3] = { 0, 0, 0 };
    char* blockList[3] = { 0, 0, 0 };

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    // Without a allowList or a blockList all URLs should have the injected script.
    static const char* randomPath = "somerandompath";
    g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
    WebKitUserScript* script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, nullptr);
    webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
    webkit_user_script_unref(script);
    g_assert_true(isScriptInjectedForURLAtPath(test, randomPath));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    g_assert_false(isScriptInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));
    script = webkit_user_script_new_for_world(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, "WebExtensionTestScriptWorld", nullptr, nullptr);
    webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
    webkit_user_script_unref(script);
    g_assert_true(isScriptInjectedForURLAtPath(test, randomPath, "WebExtensionTestScriptWorld"));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    fillURLListFromPaths(blockList, randomPath, 0);
    script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, blockList);
    webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
    webkit_user_script_unref(script);
    g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
    g_assert_true(isScriptInjectedForURLAtPath(test, "someotherrandompath"));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    static const char* inTheAllowList = "intheallowlist";
    static const char* notInAllowList = "notintheallowlist";
    static const char* inTheAllowListAndBlockList = "intheallowlistandblockList";

    fillURLListFromPaths(allowList, inTheAllowList, inTheAllowListAndBlockList, 0);
    fillURLListFromPaths(blockList, inTheAllowListAndBlockList, 0);
    script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, allowList, blockList);
    webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
    webkit_user_script_unref(script);
    g_assert_true(isScriptInjectedForURLAtPath(test, inTheAllowList));
    g_assert_false(isScriptInjectedForURLAtPath(test, inTheAllowListAndBlockList));
    g_assert_false(isScriptInjectedForURLAtPath(test, notInAllowList));

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
    script = webkit_user_script_new(kInjectedScript, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END, nullptr, nullptr);
    webkit_user_content_manager_add_script(test->m_userContentManager.get(), script);
    g_assert_true(isScriptInjectedForURLAtPath(test, randomPath));
    webkit_user_content_manager_remove_script(test->m_userContentManager.get(), script);
    g_assert_false(isScriptInjectedForURLAtPath(test, randomPath));
    webkit_user_script_unref(script);

    // It's important to clean up the environment before other tests.
    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);
}

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

    UserScriptMessageTest()
        : m_userScriptMessage(nullptr)
    {
    }

    ~UserScriptMessageTest()
    {
        if (m_userScriptMessage)
            webkit_javascript_result_unref(m_userScriptMessage);
    }

    bool registerHandler(const char* handlerName, const char* worldName = nullptr)
    {
        return worldName ? webkit_user_content_manager_register_script_message_handler_in_world(m_userContentManager.get(), handlerName, worldName)
            : webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), handlerName);
    }

    void unregisterHandler(const char* handlerName, const char* worldName = nullptr)
    {
        return worldName ? webkit_user_content_manager_unregister_script_message_handler_in_world(m_userContentManager.get(), handlerName, worldName)
            : webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), handlerName);
    }

    static void scriptMessageReceived(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* jsResult, UserScriptMessageTest* test)
    {
        g_signal_handlers_disconnect_by_func(userContentManager, reinterpret_cast<gpointer>(scriptMessageReceived), test);
        if (!test->m_waitForScriptRun)
            g_main_loop_quit(test->m_mainLoop);

        g_assert_null(test->m_userScriptMessage);
        test->m_userScriptMessage = webkit_javascript_result_ref(jsResult);
    }

    WebKitJavascriptResult* waitUntilMessageReceived(const char* handlerName)
    {
        if (m_userScriptMessage) {
            webkit_javascript_result_unref(m_userScriptMessage);
            m_userScriptMessage = nullptr;
        }

        GUniquePtr<char> signalName(g_strdup_printf("script-message-received::%s", handlerName));
        g_signal_connect(m_userContentManager.get(), signalName.get(), G_CALLBACK(scriptMessageReceived), this);

        g_main_loop_run(m_mainLoop);
        g_assert_false(m_waitForScriptRun);
        g_assert_nonnull(m_userScriptMessage);
        return m_userScriptMessage;
    }

    static void runJavaScriptFinished(GObject*, GAsyncResult* result, UserScriptMessageTest* test)
    {
        g_assert_true(test->m_waitForScriptRun);
        test->m_waitForScriptRun = false;
        g_main_loop_quit(test->m_mainLoop);
    }

    WebKitJavascriptResult* postMessageAndWaitUntilReceived(const char* handlerName, const char* javascriptValueAsText, const char* worldName = nullptr)
    {
        GUniquePtr<char> javascriptSnippet(g_strdup_printf("window.webkit.messageHandlers.%s.postMessage(%s);", handlerName, javascriptValueAsText));
        m_waitForScriptRun = true;
        if (worldName)
            webkit_web_view_run_javascript_in_world(m_webView, javascriptSnippet.get(), worldName, nullptr, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptFinished), this);
        else
            webkit_web_view_run_javascript(m_webView, javascriptSnippet.get(), nullptr, reinterpret_cast<GAsyncReadyCallback>(runJavaScriptFinished), this);
        return waitUntilMessageReceived(handlerName);
    }

private:
    WebKitJavascriptResult* m_userScriptMessage;
    bool m_waitForScriptRun { false };
};

static void testUserContentManagerScriptMessageReceived(UserScriptMessageTest* test, gconstpointer)
{
    g_assert_true(test->registerHandler("msg"));

    // Trying to register the same handler a second time must fail.
    g_assert_false(test->registerHandler("msg"));

    test->loadHtml("<html></html>", nullptr);
    test->waitUntilLoadFinished();

    // Check that the "window.webkit.messageHandlers" namespace exists.
    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "y");

    // Check that the "document.webkit.messageHandlers.msg" namespace exists.
    javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "y");

    valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'")));
    g_assert_cmpstr(valueString.get(), ==, "user message");

    // Messages should arrive despite of other handlers being registered.
    g_assert_true(test->registerHandler("anotherHandler"));

    // Check that the "document.webkit.messageHandlers.msg" namespace still exists.
    javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg ? 'y' : 'n';", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "y");

    // Check that the "document.webkit.messageHandlers.anotherHandler" namespace exists.
    javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.anotherHandler ? 'y' : 'n';", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "y");

    valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'")));
    g_assert_cmpstr(valueString.get(), ==, "handler: msg");

    valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("anotherHandler", "'handler: anotherHandler'")));
    g_assert_cmpstr(valueString.get(), ==, "handler: anotherHandler");

    // Unregistering a handler and re-registering again under the same name should work.
    test->unregisterHandler("msg");

    javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr());
    g_assert_null(javascriptResult);
    g_assert_nonnull(error.get());

    // Re-registering a handler that has been unregistered must work
    g_assert_true(test->registerHandler("msg"));
    valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'handler: msg'")));
    g_assert_cmpstr(valueString.get(), ==, "handler: msg");

    test->unregisterHandler("anotherHandler");
}

static void testUserContentManagerScriptMessageInWorldReceived(UserScriptMessageTest* test, gconstpointer)
{
    g_assert_true(test->registerHandler("msg"));

    test->loadHtml("<html></html>", nullptr);
    test->waitUntilLoadFinished();

    // Check that the "window.webkit.messageHandlers" namespace doesn't exist in isolated worlds.
    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = test->runJavaScriptInWorldAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", "WebExtensionTestScriptWorld", &error.outPtr());
    g_assert_null(javascriptResult);
    g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);
    test->unregisterHandler("msg");

    g_assert_true(test->registerHandler("msg", "WebExtensionTestScriptWorld"));

    // Check that the "window.webkit.messageHandlers" namespace exists in the world.
    javascriptResult = test->runJavaScriptInWorldAndWaitUntilFinished("window.webkit.messageHandlers ? 'y' : 'n';", "WebExtensionTestScriptWorld", &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());
    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "y");

    valueString.reset(WebViewTest::javascriptResultToCString(test->postMessageAndWaitUntilReceived("msg", "'user message'", "WebExtensionTestScriptWorld")));
    g_assert_cmpstr(valueString.get(), ==, "user message");

    // Post message in main world should fail.
    javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.webkit.messageHandlers.msg.postMessage('42');", &error.outPtr());
    g_assert_null(javascriptResult);
    g_assert_error(error.get(), WEBKIT_JAVASCRIPT_ERROR, WEBKIT_JAVASCRIPT_ERROR_SCRIPT_FAILED);

    test->unregisterHandler("msg", "WebExtensionTestScriptWorld");
}

#if PLATFORM(GTK)
static void testUserContentManagerScriptMessageFromDOMBindings(UserScriptMessageTest* test, gconstpointer)
{
    g_assert_true(test->registerHandler("dom"));

    test->loadHtml("<html>1</html>", nullptr);
    WebKitJavascriptResult* javascriptResult = test->waitUntilMessageReceived("dom");
    g_assert_nonnull(javascriptResult);
    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    g_assert_cmpstr(valueString.get(), ==, "DocumentLoaded");

    test->unregisterHandler("dom");
}
#endif

static bool isCSSBlockedForURLAtPath(WebViewTest* test, const char* path)
{
    test->loadURI(kServer->getURIForPath(path).data());
    test->waitUntilLoadFinished();

    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(kScriptTestCSSBlocked, &error.outPtr());
    g_assert_nonnull(javascriptResult);
    g_assert_no_error(error.get());

    GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
    return !g_strcmp0(valueString.get(), kScriptTestCSSBlockedResult);
}

static WebKitUserContentFilter* getUserContentFilter(WebViewTest* test)
{
    GUniquePtr<char> filtersPath(g_build_filename(test->dataDirectory(), "filters", nullptr));
    WebKitUserContentFilterStore* store = webkit_user_content_filter_store_new(filtersPath.get());
    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(store));

    struct Data {
        GMainLoop* mainLoop;
        WebKitUserContentFilter* filter;
    };
    Data data { test->m_mainLoop, nullptr, };

    GRefPtr<GBytes> source = adoptGRef(g_bytes_new_static(kJSONFilter, strlen(kJSONFilter)));
    webkit_user_content_filter_store_save(store, "TestFilter", source.get(), nullptr, [](GObject* sourceObject, GAsyncResult* result, void* userData) {
        auto* data = static_cast<Data*>(userData);
        GUniqueOutPtr<GError> error;
        data->filter = webkit_user_content_filter_store_save_finish(WEBKIT_USER_CONTENT_FILTER_STORE(sourceObject), result, &error.outPtr());
        g_assert_nonnull(data->filter);
        g_assert_no_error(error.get());
        g_main_loop_quit(data->mainLoop);
    }, &data);
    g_main_loop_run(data.mainLoop);

    g_object_unref(store);

    g_assert_nonnull(data.filter);
    return data.filter;
}

static void testUserContentManagerContentFilter(WebViewTest* test, gconstpointer)
{
    char* allowList[] = { nullptr, nullptr, nullptr };
    char* blockList[] = { nullptr, nullptr, nullptr };

    removeOldInjectedContentAndResetLists(test->m_userContentManager.get(), allowList, blockList);

    static const char* somePath = "somepath";
    g_assert_false(isCSSBlockedForURLAtPath(test, somePath));

    WebKitUserContentFilter* filter = getUserContentFilter(test);
    webkit_user_content_manager_add_filter(test->m_userContentManager.get(), filter);
    g_assert_true(isCSSBlockedForURLAtPath(test, somePath));

    webkit_user_content_manager_remove_filter(test->m_userContentManager.get(), filter);
    g_assert_false(isCSSBlockedForURLAtPath(test, somePath));

    webkit_user_content_manager_add_filter(test->m_userContentManager.get(), filter);
    g_assert_true(isCSSBlockedForURLAtPath(test, somePath));

    webkit_user_content_manager_remove_filter_by_id(test->m_userContentManager.get(), webkit_user_content_filter_get_identifier(filter));
    g_assert_false(isCSSBlockedForURLAtPath(test, somePath));

    webkit_user_content_filter_unref(filter);
}

#if USE(SOUP2)
static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
static void serverCallback(SoupServer* server, SoupServerMessage* message, const char* path, GHashTable*, gpointer)
#endif
{
    soup_server_message_set_status(message, SOUP_STATUS_OK, nullptr);
    auto* responseBody = soup_server_message_get_response_body(message);
    if (!g_strcmp0(path, "/extra.css"))
        soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, kTestCSS, strlen(kTestCSS));
    else
        soup_message_body_append(responseBody, SOUP_MEMORY_STATIC, kTestHTML, strlen(kTestHTML));
    soup_message_body_complete(responseBody);
}

void beforeAll()
{
    kServer = new WebKitTestServer();
    kServer->run(serverCallback);

    Test::add("WebKitWebView", "new-with-user-content-manager", testWebViewNewWithUserContentManager);
    WebViewTest::add("WebKitUserContentManager", "injected-style-sheet", testUserContentManagerInjectedStyleSheet);
    WebViewTest::add("WebKitUserContentManager", "injected-script", testUserContentManagerInjectedScript);
    UserScriptMessageTest::add("WebKitUserContentManager", "script-message-received", testUserContentManagerScriptMessageReceived);
    UserScriptMessageTest::add("WebKitUserContentManager", "script-message-in-world-received", testUserContentManagerScriptMessageInWorldReceived);
#if PLATFORM(GTK)
    UserScriptMessageTest::add("WebKitUserContentManager", "script-message-from-dom-bindings", testUserContentManagerScriptMessageFromDOMBindings);
#endif
    WebViewTest::add("WebKitUserContentManager", "content-filter", testUserContentManagerContentFilter);
}

void afterAll()
{
    delete kServer;
}
