/*
 * Copyright (C) 2010-2024 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "TestRunner.h"

#include "ActivateFonts.h"
#include "DictionaryFunctions.h"
#include "InjectedBundle.h"
#include "InjectedBundlePage.h"
#include "JSTestRunner.h"
#include "PlatformWebView.h"
#include "TestController.h"
#include <JavaScriptCore/JSCTestRunnerUtils.h>
#include <WebCore/NetworkStorageSession.h>
#include <WebCore/ResourceLoadObserver.h>
#include <WebKit/WKBundle.h>
#include <WebKit/WKBundleBackForwardList.h>
#include <WebKit/WKBundleFrame.h>
#include <WebKit/WKBundleFramePrivate.h>
#include <WebKit/WKBundleNodeHandlePrivate.h>
#include <WebKit/WKBundlePage.h>
#include <WebKit/WKBundlePagePrivate.h>
#include <WebKit/WKBundlePrivate.h>
#include <WebKit/WKBundleScriptWorld.h>
#include <WebKit/WKData.h>
#include <WebKit/WKNumber.h>
#include <WebKit/WKPagePrivate.h>
#include <WebKit/WKRetainPtr.h>
#include <WebKit/WKSerializedScriptValue.h>
#include <WebKit/WKStringPrivate.h>
#include <WebKit/WebKit2_C.h>
#include <wtf/HashMap.h>
#include <wtf/StdLibExtras.h>
#include <wtf/UniqueArray.h>
#include <wtf/text/CString.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/StringBuilder.h>

#if OS(WINDOWS)
#include <shlwapi.h>
#include <wininet.h>
#endif

namespace WTR {

ALLOW_DEPRECATED_DECLARATIONS_BEGIN

Ref<TestRunner> TestRunner::create()
{
    return adoptRef(*new TestRunner);
}

TestRunner::TestRunner()
    : m_userStyleSheetLocation(toWK(""))
{
    platformInitialize();
}

TestRunner::~TestRunner() = default;

JSClassRef TestRunner::wrapperClass()
{
    return JSTestRunner::testRunnerClass();
}

static WKBundlePageRef page()
{
    return InjectedBundle::singleton().page()->page();
}

void TestRunner::display()
{
    WKBundlePageForceRepaint(page());
}

void TestRunner::displayAndTrackRepaints(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "DisplayAndTrackRepaints", callback);
}

static WKRetainPtr<WKDoubleRef> toWK(double value)
{
    return adoptWK(WKDoubleCreate(value));
}

static WKRetainPtr<WKDictionaryRef> createWKDictionary(std::initializer_list<std::pair<const char*, WKRetainPtr<WKTypeRef>>> pairs)
{
    Vector<WKStringRef> keys;
    Vector<WKTypeRef> values;
    Vector<WKRetainPtr<WKStringRef>> strings;
    for (auto& pair : pairs) {
        auto key = toWK(pair.first);
        keys.append(key.get());
        values.append(pair.second.get());
        strings.append(WTFMove(key));
    }
    return adoptWK(WKDictionaryCreate(keys.span().data(), values.span().data(), keys.size()));
}

template<typename T> static WKRetainPtr<WKTypeRef> postSynchronousMessageWithReturnValue(const char* name, const WKRetainPtr<T>& value)
{
    WKTypeRef rawReturnValue = nullptr;
    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), toWK(name).get(), value.get(), &rawReturnValue);
    return adoptWK(rawReturnValue);
}

template<typename T> static bool postSynchronousMessageReturningBoolean(const char* name, const WKRetainPtr<T>& value)
{
    return booleanValue(postSynchronousMessageWithReturnValue(name, value));
}

static bool postSynchronousMessageReturningBoolean(const char* name)
{
    return postSynchronousMessageReturningBoolean(name, WKRetainPtr<WKTypeRef> { });
}

template<typename T> static WKRetainPtr<WKTypeRef> postSynchronousPageMessageWithReturnValue(const char* name, const WKRetainPtr<T>& value)
{
    WKTypeRef rawReturnValue = nullptr;
    WKBundlePagePostSynchronousMessageForTesting(page(), toWK(name).get(), value.get(), &rawReturnValue);
    return adoptWK(rawReturnValue);
}

template<typename T> static bool postSynchronousPageMessageReturningBoolean(const char* name, const WKRetainPtr<T>& value)
{
    return booleanValue(postSynchronousPageMessageWithReturnValue(name, value));
}

static bool postSynchronousPageMessageReturningBoolean(const char* name)
{
    return postSynchronousPageMessageReturningBoolean(name, WKRetainPtr<WKTypeRef> { });
}

static bool postSynchronousPageMessageReturningBoolean(const char* name, JSStringRef string)
{
    return postSynchronousPageMessageReturningBoolean(name, toWK(string));
}

template<typename T> static uint64_t postSynchronousPageMessageReturningUInt64(const char* name, const WKRetainPtr<T>& value)
{
    return uint64Value(postSynchronousPageMessageWithReturnValue(name, value));
}

static uint64_t postSynchronousMessageReturningUInt64(const char* name)
{
    return uint64Value(postSynchronousMessageWithReturnValue(name, WKRetainPtr<WKTypeRef> { }));
}

static bool postSynchronousPageMessageReturningUInt64(const char* name, JSStringRef string)
{
    return postSynchronousPageMessageReturningUInt64(name, toWK(string));
}

bool TestRunner::shouldDumpPixels() const
{
    return postSynchronousMessageReturningBoolean("GetDumpPixels");
}

void TestRunner::setDumpPixels(bool dumpPixels)
{
    postSynchronousMessage("SetDumpPixels", dumpPixels);
}

void TestRunner::dumpAsText(bool dumpPixels)
{
    if (whatToDump() < WhatToDump::MainFrameText)
        setWhatToDump(WhatToDump::MainFrameText);
    setDumpPixels(dumpPixels);
}
    
WhatToDump TestRunner::whatToDump() const
{
    return static_cast<WhatToDump>(postSynchronousMessageReturningUInt64("GetWhatToDump"));
}

void TestRunner::setWhatToDump(WhatToDump whatToDump)
{
    postSynchronousMessage("SetWhatToDump", static_cast<uint64_t>(whatToDump));
}

void TestRunner::setCustomPolicyDelegate(bool enabled, bool permissive)
{
    InjectedBundle::singleton().setCustomPolicyDelegate(enabled, permissive);
}

void TestRunner::skipPolicyDelegateNotifyDone()
{
    postMessage("SkipPolicyDelegateNotifyDone");
}

void TestRunner::waitForPolicyDelegate()
{
    setCustomPolicyDelegate(true);
    waitUntilDone();
}

void TestRunner::waitUntilDownloadFinished()
{
    m_shouldFinishAfterDownload = true;
    waitUntilDone();
}

void TestRunner::waitUntilDone()
{
    RELEASE_ASSERT(InjectedBundle::singleton().isTestRunning());

    setWaitUntilDone(true);
}

void TestRunner::setWaitUntilDone(bool value)
{
    postSynchronousMessage("SetWaitUntilDone", value);
}

bool TestRunner::shouldWaitUntilDone() const
{
    return postSynchronousMessageReturningBoolean("GetWaitUntilDone");
}

void TestRunner::notifyDone()
{
    auto& injectedBundle = InjectedBundle::singleton();
    if (!injectedBundle.isTestRunning())
        return;
    if (!postSynchronousMessageReturningBoolean("ResolveNotifyDone"))
        return;
    if (!injectedBundle.page())
        return;
    injectedBundle.page()->notifyDone();
}

void TestRunner::forceImmediateCompletion()
{
    auto& injectedBundle = InjectedBundle::singleton();
    if (!injectedBundle.isTestRunning())
        return;
    if (!postSynchronousMessageReturningBoolean("ResolveForceImmediateCompletion"))
        return;
    if (!injectedBundle.page())
        return;
    injectedBundle.page()->forceImmediateCompletion();
}

void TestRunner::setShouldDumpFrameLoadCallbacks(bool value)
{
    postSynchronousMessage("SetDumpFrameLoadCallbacks", value);
}

bool TestRunner::shouldDumpFrameLoadCallbacks()
{
    return postSynchronousMessageReturningBoolean("GetDumpFrameLoadCallbacks");
}

unsigned TestRunner::imageCountInGeneralPasteboard() const
{
    return InjectedBundle::singleton().imageCountInGeneralPasteboard();
}

void TestRunner::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
{
    WKBundlePageAddUserScript(page(), toWK(source).get(),
        (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd),
        (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
}

void TestRunner::addUserStyleSheet(JSStringRef source, bool allFrames)
{
    WKBundlePageAddUserStyleSheet(page(), toWK(source).get(),
        (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
}

void TestRunner::keepWebHistory()
{
    InjectedBundle::singleton().postSetAddsVisitedLinks(true);
}

void TestRunner::execCommand(JSStringRef command, JSStringRef, JSStringRef value)
{
    postSynchronousPageMessage("ExecuteCommand", createWKDictionary({
        { "Command", toWK(command) },
        { "Value", toWK(value) },
    }));
}

static std::optional<WKFindOptions> findOptionsFromArray(JSContextRef context, JSValueRef optionsArrayAsValue)
{
    auto optionsArray = JSValueToObject(context, optionsArrayAsValue, nullptr);
    auto length = arrayLength(context, optionsArray);
    WKFindOptions options = 0;
    for (unsigned i = 0; i < length; ++i) {
        auto optionName = createJSString(context, JSObjectGetPropertyAtIndex(context, optionsArray, i, 0));
        if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive"))
            options |= kWKFindOptionsCaseInsensitive;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts"))
            options |= kWKFindOptionsAtWordStarts;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart"))
            options |= kWKFindOptionsTreatMedialCapitalAsWordStart;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards"))
            options |= kWKFindOptionsBackwards;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround"))
            options |= kWKFindOptionsWrapAround;
        else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) {
            // FIXME: No kWKFindOptionsStartInSelection.
        }
    }
    return options;
}

void TestRunner::findString(JSContextRef context, JSStringRef target, JSValueRef optionsArrayAsValue, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "FindString", createWKDictionary({
        { "String", toWK(target) },
        { "FindOptions", adoptWK(WKUInt64Create(findOptionsFromArray(context, optionsArrayAsValue).value_or(WKFindOptions { }))) },
    }), callback);
}

void TestRunner::findStringMatchesInPage(JSContextRef context, JSStringRef target, JSValueRef optionsArrayAsValue)
{
    if (auto options = findOptionsFromArray(context, optionsArrayAsValue)) {
        postPageMessage("FindStringMatches", createWKDictionary({
            { "String", toWK(target) },
            { "FindOptions", toWK(*options) },
        }));
    }
}

void TestRunner::indicateFindMatch(JSContextRef context, uint32_t index)
{
    postPageMessage("IndicateFindMatch", index);
}

void TestRunner::replaceFindMatchesAtIndices(JSContextRef context, JSValueRef matchIndicesAsValue, JSStringRef replacementText, bool selectionOnly)
{
    auto& bundle = InjectedBundle::singleton();
    auto matchIndicesObject = JSValueToObject(context, matchIndicesAsValue, 0);
    auto length = arrayLength(context, matchIndicesObject);

    auto indices = adoptWK(WKMutableArrayCreate());
    for (unsigned i = 0; i < length; ++i) {
        auto value = JSObjectGetPropertyAtIndex(context, matchIndicesObject, i, nullptr);
        if (!JSValueIsNumber(context, value))
            continue;

        auto index = adoptWK(WKUInt64Create(JSValueToNumber(context, value, nullptr)));
        WKArrayAppendItem(indices.get(), index.get());
    }
    WKBundlePageReplaceStringMatches(bundle.page()->page(), indices.get(), toWK(replacementText).get(), selectionOnly);
}

void TestRunner::clearAllDatabases()
{
    postSynchronousMessage("DeleteAllIndexedDatabases", true);
}

void TestRunner::setDatabaseQuota(uint64_t quota)
{
    return WKBundleSetDatabaseQuota(InjectedBundle::singleton().bundle(), quota);
}

void TestRunner::syncLocalStorage()
{
    postSynchronousMessage("SyncLocalStorage", true);
}

bool TestRunner::isCommandEnabled(JSStringRef name)
{
    return postSynchronousPageMessageReturningBoolean("IsCommandEnabled", toWK(name));
}

void TestRunner::preventPopupWindows()
{
    postSynchronousMessage("SetCanOpenWindows", false);
}

void TestRunner::setCustomUserAgent(JSStringRef userAgent)
{
    postSynchronousMessage("SetCustomUserAgent", toWK(userAgent));
}

void TestRunner::setAllowsAnySSLCertificate(bool enabled)
{
    InjectedBundle::singleton().setAllowsAnySSLCertificate(enabled);
    postSynchronousPageMessage("SetAllowsAnySSLCertificate", enabled);
}

void TestRunner::setBackgroundFetchPermission(bool enabled)
{
    postSynchronousPageMessage("SetBackgroundFetchPermission", enabled);
}

JSRetainPtr<JSStringRef>  TestRunner::lastAddedBackgroundFetchIdentifier() const
{
    auto identifier = InjectedBundle::singleton().lastAddedBackgroundFetchIdentifier();
    return WKStringCopyJSString(identifier.get());
}

JSRetainPtr<JSStringRef>  TestRunner::lastRemovedBackgroundFetchIdentifier() const
{
    auto identifier = InjectedBundle::singleton().lastRemovedBackgroundFetchIdentifier();
    return WKStringCopyJSString(identifier.get());
}

JSRetainPtr<JSStringRef> TestRunner::lastUpdatedBackgroundFetchIdentifier() const
{
    auto identifier = InjectedBundle::singleton().lastUpdatedBackgroundFetchIdentifier();
    return WKStringCopyJSString(identifier.get());
}

JSRetainPtr<JSStringRef> TestRunner::backgroundFetchState(JSStringRef identifier)
{
    auto state = InjectedBundle::singleton().backgroundFetchState(toWK(identifier).get());
    return WKStringCopyJSString(state.get());
}

void TestRunner::setShouldSwapToEphemeralSessionOnNextNavigation(bool shouldSwap)
{
    postSynchronousPageMessage("SetShouldSwapToEphemeralSessionOnNextNavigation", shouldSwap);
}

void TestRunner::setShouldSwapToDefaultSessionOnNextNavigation(bool shouldSwap)
{
    postSynchronousPageMessage("SetShouldSwapToDefaultSessionOnNextNavigation", shouldSwap);
}

void TestRunner::addOriginAccessAllowListEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
{
    WKBundleAddOriginAccessAllowListEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
}

void TestRunner::removeOriginAccessAllowListEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
{
    WKBundleRemoveOriginAccessAllowListEntry(InjectedBundle::singleton().bundle(), toWK(sourceOrigin).get(), toWK(destinationProtocol).get(), toWK(destinationHost).get(), allowDestinationSubdomains);
}

bool TestRunner::isPageBoxVisible(JSContextRef context, int pageIndex)
{
    auto frame = WKBundleFrameForJavaScriptContext(context);
    auto& injectedBundle = InjectedBundle::singleton();
    return WKBundleIsPageBoxVisible(injectedBundle.bundle(), frame, pageIndex);
}

void TestRunner::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value)
{
    if (!element || !JSValueIsObject(context, element))
        return;

    WKBundleNodeHandleSetHTMLInputElementValueForUser(adoptWK(WKBundleNodeHandleCreate(context, const_cast<JSObjectRef>(element))).get(), toWK(value).get());
}

void TestRunner::setAudioResult(JSContextRef context, JSValueRef data)
{
    auto& injectedBundle = InjectedBundle::singleton();
    // FIXME (123058): Use a JSC API to get buffer contents once such is exposed.
    injectedBundle.setAudioResult(adoptWK(WKBundleCreateWKDataFromUInt8Array(injectedBundle.bundle(), context, data)).get());
    setWhatToDump(WhatToDump::Audio);
    setDumpPixels(false);
}

unsigned TestRunner::windowCount()
{
    return InjectedBundle::singleton().pageCount();
}

void TestRunner::clearBackForwardList(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "ClearBackForwardList", callback);
}

void TestRunner::makeWindowObject(JSContextRef context)
{
    setGlobalObjectProperty(context, "testRunner", this);
}

void TestRunner::showWebInspector()
{
    postMessage("ShowWebInspector");
}

void TestRunner::closeWebInspector()
{
    WKBundlePageCloseInspectorForTest(page());
}

void TestRunner::evaluateInWebInspector(JSStringRef script)
{
    WKBundlePageEvaluateScriptInInspectorForTest(page(), toWK(script).get());
}

using WorldMap = WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef>>;
static WorldMap& worldMap()
{
    static WorldMap& map = *new WorldMap;
    return map;
}

unsigned TestRunner::worldIDForWorld(WKBundleScriptWorldRef world)
{
    // FIXME: This is the anti-pattern of iterating an entire map. Typically we use a pair of maps or just a vector in a case like this.
    for (auto& mapEntry : worldMap()) {
        if (mapEntry.value == world)
            return mapEntry.key;
    }
    return 0;
}

void TestRunner::evaluateScriptInIsolatedWorld(JSContextRef context, unsigned worldID, JSStringRef script)
{
    // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world
    // that is created once and cached forever.
    WKRetainPtr<WKBundleScriptWorldRef> world;
    if (!worldID)
        world.adopt(WKBundleScriptWorldCreateWorld());
    else {
        WKRetainPtr<WKBundleScriptWorldRef>& worldSlot = worldMap().add(worldID, nullptr).iterator->value;
        if (!worldSlot)
            worldSlot.adopt(WKBundleScriptWorldCreateWorld());
        world = worldSlot;
    }

    auto frame = WKBundleFrameForJavaScriptContext(context);
    ASSERT(frame);

    JSGlobalContextRef jsContext = WKBundleFrameGetJavaScriptContextForWorld(frame, world.get());
    JSEvaluateScript(jsContext, script, 0, 0, 0, 0); 
}

void TestRunner::setPOSIXLocale(JSStringRef locale)
{
    char localeBuf[32];
    JSStringGetUTF8CString(locale, localeBuf, sizeof(localeBuf));
    setlocale(LC_ALL, localeBuf);
}

void TestRunner::setTextDirection(JSContextRef context, JSStringRef direction)
{
    auto frame = WKBundleFrameForJavaScriptContext(context);
    return WKBundleFrameSetTextDirection(frame, toWK(direction).get());
}
    
void TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPage)
{
    InjectedBundle::singleton().postNewBeforeUnloadReturnValue(!shouldStayOnPage);
}

bool TestRunner::didReceiveServerRedirectForProvisionalNavigation() const
{
    return postSynchronousPageMessageReturningBoolean("DidReceiveServerRedirectForProvisionalNavigation");
}

void TestRunner::clearDidReceiveServerRedirectForProvisionalNavigation()
{
    postSynchronousPageMessage("ClearDidReceiveServerRedirectForProvisionalNavigation");
}

void TestRunner::setPageVisibility(JSStringRef state)
{
    InjectedBundle::singleton().setHidden(JSStringIsEqualToUTF8CString(state, "hidden"));
}

void TestRunner::resetPageVisibility()
{
    InjectedBundle::singleton().setHidden(false);
}

struct Callback {
    JSObjectRef callback;
    JSRetainPtr<JSGlobalContextRef> context;
};

using CallbackMap = WTF::HashMap<unsigned, Callback>;
static CallbackMap& callbackMap()
{
    static CallbackMap& map = *new CallbackMap;
    return map;
}

enum {
    DidBeginSwipeCallbackID = 1,
    WillEndSwipeCallbackID,
    DidEndSwipeCallbackID,
    DidRemoveSwipeSnapshotCallbackID,
    TextDidChangeInTextFieldCallbackID,
    TextFieldDidBeginEditingCallbackID,
    TextFieldDidEndEditingCallbackID,
    FirstUIScriptCallbackID = 100
};

static void cacheTestRunnerCallback(JSContextRef context, unsigned index, JSValueRef callback)
{
    if (!callback)
        return;
    if (!JSValueIsObject(context, callback))
        return;
    if (callbackMap().contains(index)) {
        InjectedBundle::singleton().outputText(makeString("FAIL: Tried to install a second TestRunner callback for the same event (id "_s, index, ")\n\n"_s));
        return;
    }
    JSValueProtect(context, callback);
    callbackMap().add(index, Callback { const_cast<JSObjectRef>(callback), JSContextGetGlobalContext(context) });
}

static void callTestRunnerCallback(unsigned index, JSStringRef argument = nullptr)
{
    auto callback = callbackMap().take(index);
    if (!callback.callback)
        return;
    auto context = callback.context.get();

    size_t argumentCount = 0;
    JSValueRef argumentValue { nullptr };
    JSValueRef* arguments { nullptr };
    if (argument) {
        argumentCount = 1;
        argumentValue = JSValueMakeString(context, argument);
        arguments = &argumentValue;
    }

    JSObjectCallAsFunction(context, callback.callback, JSContextGetGlobalObject(context), argumentCount, arguments, 0);
    JSValueUnprotect(context, callback.callback);
}

void TestRunner::clearTestRunnerCallbacks()
{
    for (auto& value : callbackMap().values()) {
        auto context = value.context.get();
        JSValueUnprotect(context, JSValueToObject(context, value.callback, nullptr));
    }
    callbackMap().clear();
}

void TestRunner::accummulateLogsForChannel(JSStringRef)
{
    // FIXME: Implement getting the call to all processes.
}

void TestRunner::addChromeInputField(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "AddChromeInputField", callback);
}

void TestRunner::removeChromeInputField(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "RemoveChromeInputField", callback);
}

void TestRunner::setTextInChromeInputField(JSContextRef context, JSStringRef text, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SetTextInChromeInputField", toWK(text), callback);
}

void TestRunner::selectChromeInputField(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SelectChromeInputField", callback);
}

void TestRunner::getSelectedTextInChromeInputField(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "GetSelectedTextInChromeInputField", callback);
}

void TestRunner::focusWebView(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "FocusWebView", callback);
}

void TestRunner::setBackingScaleFactor(JSContextRef context, double backingScaleFactor, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SetBackingScaleFactor", adoptWK(WKDoubleCreate(backingScaleFactor)), callback);
}

void TestRunner::setWindowIsKey(bool isKey)
{
    InjectedBundle::singleton().postSetWindowIsKey(isKey);
}

void TestRunner::setViewSize(double width, double height)
{
    InjectedBundle::singleton().postSetViewSize(width, height);
}

void TestRunner::setAlwaysAcceptCookies(bool accept)
{
    postSynchronousMessage("SetAlwaysAcceptCookies", accept);
}

void TestRunner::setOnlyAcceptFirstPartyCookies(bool accept)
{
    postSynchronousMessage("SetOnlyAcceptFirstPartyCookies", accept);
}

void TestRunner::removeAllCookies(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "RemoveAllCookies", callback);
}

double TestRunner::preciseTime()
{
    return WallTime::now().secondsSinceEpoch().seconds();
}

void TestRunner::setRenderTreeDumpOptions(unsigned short options)
{
    m_renderTreeDumpOptions = options;
}

void TestRunner::setUserStyleSheetEnabled(bool enabled)
{
    m_userStyleSheetEnabled = enabled;

    auto emptyString = toWK("");
    auto location = enabled ? m_userStyleSheetLocation.get() : emptyString.get();
    auto& injectedBundle = InjectedBundle::singleton();
    WKBundleSetUserStyleSheetLocationForTesting(injectedBundle.bundle(), location);
}

void TestRunner::setUserStyleSheetLocation(JSStringRef location)
{
    m_userStyleSheetLocation = toWK(location);

    if (m_userStyleSheetEnabled)
        setUserStyleSheetEnabled(true);
}

void TestRunner::setTabKeyCyclesThroughElements(bool enabled)
{
    WKBundleSetTabKeyCyclesThroughElements(InjectedBundle::singleton().bundle(), page(), enabled);
}

void TestRunner::setSerializeHTTPLoads()
{
    // WK2 doesn't reorder loads.
}

void TestRunner::dispatchPendingLoadRequests()
{
    // WK2 doesn't keep pending requests.
}

void TestRunner::setCacheModel(int model)
{
    InjectedBundle::singleton().setCacheModel(model);
}

void TestRunner::setAsynchronousSpellCheckingEnabled(bool enabled)
{
    auto& injectedBundle = InjectedBundle::singleton();
    WKBundleSetAsynchronousSpellCheckingEnabledForTesting(injectedBundle.bundle(), enabled);
}

void TestRunner::grantWebNotificationPermission(JSStringRef origin)
{
    postSynchronousPageMessageWithReturnValue("GrantNotificationPermission", toWK(origin));
}

void TestRunner::denyWebNotificationPermission(JSStringRef origin)
{
    postSynchronousPageMessageWithReturnValue("DenyNotificationPermission", toWK(origin));
}

void TestRunner::denyWebNotificationPermissionOnPrompt(JSStringRef origin)
{
    postSynchronousPageMessageWithReturnValue("DenyNotificationPermissionOnPrompt", toWK(origin));
}

void TestRunner::removeAllWebNotificationPermissions()
{
    WKBundleRemoveAllWebNotificationPermissions(InjectedBundle::singleton().bundle(), page());
}

void TestRunner::simulateWebNotificationClick(JSContextRef context, JSValueRef notification)
{
    auto& injectedBundle = InjectedBundle::singleton();

    auto notificationID = adoptWK(WKBundleCopyWebNotificationID(injectedBundle.bundle(), context, notification));
    injectedBundle.postSimulateWebNotificationClick(notificationID.get());
}

void TestRunner::simulateWebNotificationClickForServiceWorkerNotifications()
{
    InjectedBundle::singleton().postSimulateWebNotificationClickForServiceWorkerNotifications();
}

JSRetainPtr<JSStringRef> TestRunner::getBackgroundFetchIdentifier()
{
    auto identifier = InjectedBundle::singleton().getBackgroundFetchIdentifier();
    return WKStringCopyJSString(identifier.get());
}

void TestRunner::abortBackgroundFetch(JSStringRef identifier)
{
    postSynchronousPageMessageWithReturnValue("AbortBackgroundFetch", toWK(identifier));
}

void TestRunner::pauseBackgroundFetch(JSStringRef identifier)
{
    postSynchronousPageMessageWithReturnValue("PauseBackgroundFetch", toWK(identifier));
}

void TestRunner::resumeBackgroundFetch(JSStringRef identifier)
{
    postSynchronousPageMessageWithReturnValue("ResumeBackgroundFetch", toWK(identifier));
}

void TestRunner::simulateClickBackgroundFetch(JSStringRef identifier)
{
    postSynchronousPageMessageWithReturnValue("SimulateClickBackgroundFetch", toWK(identifier));
}

void TestRunner::setGeolocationPermission(bool enabled)
{
    // FIXME: This should be done by frame.
    InjectedBundle::singleton().setGeolocationPermission(enabled);
}

void TestRunner::setScreenWakeLockPermission(bool enabled)
{
    InjectedBundle::singleton().setScreenWakeLockPermission(enabled);
}

bool TestRunner::isGeolocationProviderActive()
{
    return InjectedBundle::singleton().isGeolocationProviderActive();
}

void TestRunner::setMockGeolocationPosition(double latitude, double longitude, double accuracy, std::optional<double> altitude, std::optional<double> altitudeAccuracy, std::optional<double> heading, std::optional<double> speed, std::optional<double> floorLevel)
{
    InjectedBundle::singleton().setMockGeolocationPosition(latitude, longitude, accuracy, altitude, altitudeAccuracy, heading, speed, floorLevel);
}

void TestRunner::setMockGeolocationPositionUnavailableError(JSStringRef message)
{
    InjectedBundle::singleton().setMockGeolocationPositionUnavailableError(toWK(message).get());
}

void TestRunner::setCameraPermission(bool enabled)
{
    InjectedBundle::singleton().setCameraPermission(enabled);
}

void TestRunner::setMicrophonePermission(bool enabled)
{
    InjectedBundle::singleton().setMicrophonePermission(enabled);
}

void TestRunner::setUserMediaPermission(bool enabled)
{
    InjectedBundle::singleton().setCameraPermission(enabled);
    InjectedBundle::singleton().setMicrophonePermission(enabled);
}

void TestRunner::resetUserMediaPermission()
{
    InjectedBundle::singleton().resetUserMediaPermission();
}

bool TestRunner::isDoingMediaCapture() const
{
    return postSynchronousPageMessageReturningBoolean("IsDoingMediaCapture");
}

void TestRunner::delayUserMediaRequestDecision()
{
    InjectedBundle::singleton().delayUserMediaRequestDecision();
}

unsigned TestRunner::userMediaPermissionRequestCount() const
{
    return InjectedBundle::singleton().userMediaPermissionRequestCount();
}

void TestRunner::resetUserMediaPermissionRequestCount()
{
    InjectedBundle::singleton().resetUserMediaPermissionRequestCount();
}

bool TestRunner::callShouldCloseOnWebView(JSContextRef context)
{
    auto frame = WKBundleFrameForJavaScriptContext(context);
    return WKBundleFrameCallShouldCloseOnWebView(frame);
}

void TestRunner::queueBackNavigation(unsigned howFarBackward)
{
    InjectedBundle::singleton().queueBackNavigation(howFarBackward);
}

void TestRunner::queueForwardNavigation(unsigned howFarForward)
{
    InjectedBundle::singleton().queueForwardNavigation(howFarForward);
}

void TestRunner::queueLoad(JSStringRef url, JSStringRef target, bool shouldOpenExternalURLs)
{
    InjectedBundle::singleton().queueLoad(toWK(url).get(), toWK(target).get(), shouldOpenExternalURLs);
}

void TestRunner::queueLoadHTMLString(JSStringRef content, JSStringRef baseURL, JSStringRef unreachableURL)
{
    auto baseURLWK = baseURL ? toWK(baseURL) : WKRetainPtr<WKStringRef>();
    auto unreachableURLWK = unreachableURL ? toWK(unreachableURL) : WKRetainPtr<WKStringRef>();
    InjectedBundle::singleton().queueLoadHTMLString(toWK(content).get(), baseURLWK.get(), unreachableURLWK.get());
}

void TestRunner::stopLoading()
{
    postPageMessage("StopLoading");
}

void TestRunner::dumpFullScreenCallbacks()
{
    postPageMessage("DumpFullScreenCallbacks");
}

void TestRunner::queueReload()
{
    InjectedBundle::singleton().queueReload();
}

void TestRunner::queueLoadingScript(JSStringRef script)
{
    InjectedBundle::singleton().queueLoadingScript(toWK(script).get());
}

void TestRunner::queueNonLoadingScript(JSStringRef script)
{
    InjectedBundle::singleton().queueNonLoadingScript(toWK(script).get());
}

void TestRunner::setRejectsProtectionSpaceAndContinueForAuthenticationChallenges(bool value)
{
    postPageMessage("SetRejectsProtectionSpaceAndContinueForAuthenticationChallenges", value);
}
    
void TestRunner::setHandlesAuthenticationChallenges(bool handlesAuthenticationChallenges)
{
    postPageMessage("SetHandlesAuthenticationChallenges", handlesAuthenticationChallenges);
}

void TestRunner::setShouldLogCanAuthenticateAgainstProtectionSpace(bool value)
{
    postPageMessage("SetShouldLogCanAuthenticateAgainstProtectionSpace", value);
}

void TestRunner::setShouldLogDownloadCallbacks(bool value)
{
    postPageMessage("SetShouldLogDownloadCallbacks", value);
}

void TestRunner::setShouldDownloadContentDispositionAttachments(bool value)
{
    postPageMessage("SetShouldDownloadContentDispositionAttachments", value);
}

void TestRunner::setShouldLogDownloadSize(bool value)
{
    postPageMessage("SetShouldLogDownloadSize", value);
}

void TestRunner::setShouldLogDownloadExpectedSize(bool value)
{
    postPageMessage("SetShouldLogDownloadExpectedSize", value);
}

void TestRunner::setAuthenticationUsername(JSStringRef username)
{
    postPageMessage("SetAuthenticationUsername", toWK(username));
}

void TestRunner::setAuthenticationPassword(JSStringRef password)
{
    postPageMessage("SetAuthenticationPassword", toWK(password));
}

bool TestRunner::secureEventInputIsEnabled() const
{
    return postSynchronousPageMessageReturningBoolean("SecureEventInputIsEnabled");
}

void TestRunner::setBlockAllPlugins(bool shouldBlock)
{
    postPageMessage("SetBlockAllPlugins", shouldBlock);
}

void TestRunner::setPluginSupportedMode(JSStringRef mode)
{
    postPageMessage("SetPluginSupportedMode", toWK(mode));
}

JSValueRef TestRunner::failNextNewCodeBlock(JSContextRef context)
{
    return JSC::failNextNewCodeBlock(context);
}

JSValueRef TestRunner::numberOfDFGCompiles(JSContextRef context, JSValueRef function)
{
    return JSC::numberOfDFGCompiles(context, function);
}

JSValueRef TestRunner::neverInlineFunction(JSContextRef context, JSValueRef function)
{
    return JSC::setNeverInline(context, function);
}

void TestRunner::setShouldDecideNavigationPolicyAfterDelay(bool value)
{
    m_shouldDecideNavigationPolicyAfterDelay = value;
    postPageMessage("SetShouldDecideNavigationPolicyAfterDelay", value);
}

void TestRunner::setShouldDecideResponsePolicyAfterDelay(bool value)
{
    m_shouldDecideResponsePolicyAfterDelay = value;
    postPageMessage("SetShouldDecideResponsePolicyAfterDelay", value);
}

void TestRunner::setNavigationGesturesEnabled(bool value)
{
    postPageMessage("SetNavigationGesturesEnabled", value);
}

void TestRunner::setIgnoresViewportScaleLimits(bool value)
{
    postPageMessage("SetIgnoresViewportScaleLimits", value);
}

void TestRunner::setUseDarkAppearanceForTesting(bool useDarkAppearance)
{
    postPageMessage("SetUseDarkAppearanceForTesting", useDarkAppearance);
}

void TestRunner::setShouldDownloadUndisplayableMIMETypes(bool value)
{
    postPageMessage("SetShouldDownloadUndisplayableMIMETypes", value);
}

void TestRunner::setShouldAllowDeviceOrientationAndMotionAccess(bool value)
{
    postPageMessage("SetShouldAllowDeviceOrientationAndMotionAccess", value);
}

void TestRunner::terminateGPUProcess()
{
    postSynchronousPageMessage("TerminateGPUProcess");
}

void TestRunner::terminateNetworkProcess()
{
    postSynchronousPageMessage("TerminateNetworkProcess");
}

void TestRunner::terminateServiceWorkers()
{
    postSynchronousPageMessage("TerminateServiceWorkers");
}

void TestRunner::setUseSeparateServiceWorkerProcess(bool value)
{
    postSynchronousPageMessage("SetUseSeparateServiceWorkerProcess", value);
}

static unsigned nextUIScriptCallbackID()
{
    static unsigned callbackID = FirstUIScriptCallbackID;
    return callbackID++;
}

void TestRunner::runUIScript(JSContextRef context, JSStringRef script, JSValueRef callback)
{
    unsigned callbackID = nextUIScriptCallbackID();
    cacheTestRunnerCallback(context, callbackID, callback);
    postPageMessage("RunUIProcessScript", createWKDictionary({
        { "Script", toWK(script) },
        { "CallbackID", adoptWK(WKUInt64Create(callbackID)).get() },
    }));
}

void TestRunner::runUIScriptImmediately(JSContextRef context, JSStringRef script, JSValueRef callback)
{
    unsigned callbackID = nextUIScriptCallbackID();
    cacheTestRunnerCallback(context, callbackID, callback);
    postPageMessage("RunUIProcessScriptImmediately", createWKDictionary({
        { "Script", toWK(script) },
        { "CallbackID", adoptWK(WKUInt64Create(callbackID)).get() },
    }));
}

void TestRunner::runUIScriptCallback(unsigned callbackID, JSStringRef result)
{
    callTestRunnerCallback(callbackID, result);
}

void TestRunner::setAllowedMenuActions(JSContextRef context, JSValueRef actions)
{
    auto messageBody = adoptWK(WKMutableArrayCreate());
    auto actionsArray = JSValueToObject(context, actions, nullptr);
    auto length = arrayLength(context, actionsArray);
    for (unsigned i = 0; i < length; ++i) {
        auto value = JSObjectGetPropertyAtIndex(context, actionsArray, i, nullptr);
        WKArrayAppendItem(messageBody.get(), toWKString(context, value).get());
    }
    postPageMessage("SetAllowedMenuActions", messageBody);
}

void TestRunner::installDidBeginSwipeCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, DidBeginSwipeCallbackID, callback);
}

void TestRunner::installWillEndSwipeCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, WillEndSwipeCallbackID, callback);
}

void TestRunner::installDidEndSwipeCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, DidEndSwipeCallbackID, callback);
}

void TestRunner::installDidRemoveSwipeSnapshotCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, DidRemoveSwipeSnapshotCallbackID, callback);
}

void TestRunner::callDidBeginSwipeCallback()
{
    callTestRunnerCallback(DidBeginSwipeCallbackID);
}

void TestRunner::callWillEndSwipeCallback()
{
    callTestRunnerCallback(WillEndSwipeCallbackID);
}

void TestRunner::callDidEndSwipeCallback()
{
    callTestRunnerCallback(DidEndSwipeCallbackID);
}

void TestRunner::callDidRemoveSwipeSnapshotCallback()
{
    callTestRunnerCallback(DidRemoveSwipeSnapshotCallbackID);
}

void TestRunner::clearStatisticsDataForDomain(JSStringRef domain)
{
    postSynchronousMessage("ClearStatisticsDataForDomain", toWK(domain));
}

bool TestRunner::doesStatisticsDomainIDExistInDatabase(unsigned domainID)
{
    return postSynchronousPageMessageReturningBoolean("DoesStatisticsDomainIDExistInDatabase", createWKDictionary({
        { "DomainID", adoptWK(WKUInt64Create(domainID)) }
    }));
}

void TestRunner::setStatisticsEnabled(bool value)
{
    postSynchronousMessage("SetStatisticsEnabled", value);
}

bool TestRunner::isStatisticsEphemeral()
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsEphemeral");
}

void TestRunner::setStatisticsDebugMode(JSContextRef context, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsDebugMode", adoptWK(WKBooleanCreate(value)), completionHandler);
}

void TestRunner::setStatisticsPrevalentResourceForDebugMode(JSContextRef context, JSStringRef hostName, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsPrevalentResourceForDebugMode", toWK(hostName), completionHandler);
}

void TestRunner::setStatisticsLastSeen(JSContextRef context, JSStringRef hostName, double seconds, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsLastSeen", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "Value", toWK(seconds) },
    }), completionHandler);
}

void TestRunner::setStatisticsMergeStatistic(JSContextRef context, JSStringRef hostName, JSStringRef topFrameDomain1, JSStringRef topFrameDomain2, double lastSeen, bool hadUserInteraction, double mostRecentUserInteraction, bool isGrandfathered, bool isPrevalent, bool isVeryPrevalent, unsigned dataRecordsRemoved, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsMergeStatistic", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "TopFrameDomain1", toWK(topFrameDomain1) },
        { "TopFrameDomain2", toWK(topFrameDomain2) },
        { "LastSeen", adoptWK(WKDoubleCreate(lastSeen)) },
        { "HadUserInteraction", adoptWK(WKBooleanCreate(hadUserInteraction)) },
        { "MostRecentUserInteraction", adoptWK(WKDoubleCreate(mostRecentUserInteraction)) },
        { "IsGrandfathered", adoptWK(WKBooleanCreate(isGrandfathered)) },
        { "IsPrevalent", adoptWK(WKBooleanCreate(isPrevalent)) },
        { "IsVeryPrevalent", adoptWK(WKBooleanCreate(isVeryPrevalent)) },
        { "DataRecordsRemoved", adoptWK(WKUInt64Create(dataRecordsRemoved)) },
    }), completionHandler);
}

void TestRunner::setStatisticsExpiredStatistic(JSContextRef context, JSStringRef hostName, unsigned numberOfOperatingDaysPassed, bool hadUserInteraction, bool isScheduledForAllButCookieDataRemoval, bool isPrevalent, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsExpiredStatistic", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "NumberOfOperatingDaysPassed", adoptWK(WKUInt64Create(numberOfOperatingDaysPassed)) },
        { "HadUserInteraction", adoptWK(WKBooleanCreate(hadUserInteraction)) },
        { "IsScheduledForAllButCookieDataRemoval", adoptWK(WKBooleanCreate(isScheduledForAllButCookieDataRemoval)) },
        { "IsPrevalent", adoptWK(WKBooleanCreate(isPrevalent)) }
    }), completionHandler);
}

void TestRunner::setStatisticsPrevalentResource(JSContextRef context, JSStringRef hostName, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsPrevalentResource", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "Value", adoptWK(WKBooleanCreate(value)) },
    }), completionHandler);
}

void TestRunner::setStatisticsVeryPrevalentResource(JSContextRef context, JSStringRef hostName, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsVeryPrevalentResource", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "Value", adoptWK(WKBooleanCreate(value)) },
    }), completionHandler);
}
    
void TestRunner::dumpResourceLoadStatistics()
{
    InjectedBundle::singleton().clearResourceLoadStatistics();
    postSynchronousPageMessage("dumpResourceLoadStatistics");
}

void TestRunner::dumpPolicyDelegateCallbacks()
{
    postMessage("DumpPolicyDelegateCallbacks");
}

bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsPrevalentResource", hostName);
}

bool TestRunner::isStatisticsVeryPrevalentResource(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsVeryPrevalentResource", hostName);
}

bool TestRunner::isStatisticsRegisteredAsSubresourceUnder(JSStringRef subresourceHost, JSStringRef topFrameHost)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsRegisteredAsSubresourceUnder", createWKDictionary({
        { "SubresourceHost", toWK(subresourceHost) },
        { "TopFrameHost", toWK(topFrameHost) },
    }));
}

bool TestRunner::isStatisticsRegisteredAsSubFrameUnder(JSStringRef subFrameHost, JSStringRef topFrameHost)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsRegisteredAsSubFrameUnder", createWKDictionary({
        { "SubFrameHost", toWK(subFrameHost) },
        { "TopFrameHost", toWK(topFrameHost) },
    }));
}

bool TestRunner::isStatisticsRegisteredAsRedirectingTo(JSStringRef hostRedirectedFrom, JSStringRef hostRedirectedTo)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsRegisteredAsRedirectingTo", createWKDictionary({
        { "HostRedirectedFrom", toWK(hostRedirectedFrom) },
        { "HostRedirectedTo", toWK(hostRedirectedTo) },
    }));
}

void TestRunner::setStatisticsHasHadUserInteraction(JSContextRef context, JSStringRef hostName, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsHasHadUserInteraction", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "Value", adoptWK(WKBooleanCreate(value)) },
    }), completionHandler);
}

bool TestRunner::isStatisticsHasHadUserInteraction(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsHasHadUserInteraction", hostName);
}

bool TestRunner::isStatisticsOnlyInDatabaseOnce(JSStringRef subHost, JSStringRef topHost)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsOnlyInDatabaseOnce", createWKDictionary({
        { "SubHost", toWK(subHost) },
        { "TopHost", toWK(topHost) },
    }));
}

void TestRunner::setStatisticsGrandfathered(JSStringRef hostName, bool value)
{
    postSynchronousMessage("SetStatisticsGrandfathered", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "Value", adoptWK(WKBooleanCreate(value)) },
    }));
}

bool TestRunner::isStatisticsGrandfathered(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsGrandfathered", hostName);
}

void TestRunner::setStatisticsSubframeUnderTopFrameOrigin(JSStringRef hostName, JSStringRef topFrameHostName)
{
    postSynchronousMessage("SetStatisticsSubframeUnderTopFrameOrigin", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "TopFrameHostName", toWK(topFrameHostName) },
    }));
}

void TestRunner::setStatisticsSubresourceUnderTopFrameOrigin(JSStringRef hostName, JSStringRef topFrameHostName)
{
    postSynchronousMessage("SetStatisticsSubresourceUnderTopFrameOrigin", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "TopFrameHostName", toWK(topFrameHostName) },
    }));
}

void TestRunner::setStatisticsSubresourceUniqueRedirectTo(JSStringRef hostName, JSStringRef hostNameRedirectedTo)
{
    postSynchronousMessage("SetStatisticsSubresourceUniqueRedirectTo", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "HostNameRedirectedTo", toWK(hostNameRedirectedTo) },
    }));
}


void TestRunner::setStatisticsSubresourceUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom)
{
    postSynchronousMessage("SetStatisticsSubresourceUniqueRedirectFrom", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "HostNameRedirectedFrom", toWK(hostNameRedirectedFrom) },
    }));
}

void TestRunner::setStatisticsTopFrameUniqueRedirectTo(JSStringRef hostName, JSStringRef hostNameRedirectedTo)
{
    postSynchronousMessage("SetStatisticsTopFrameUniqueRedirectTo", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "HostNameRedirectedTo", toWK(hostNameRedirectedTo) },
    }));
}

void TestRunner::setStatisticsTopFrameUniqueRedirectFrom(JSStringRef hostName, JSStringRef hostNameRedirectedFrom)
{
    postSynchronousMessage("SetStatisticsTopFrameUniqueRedirectFrom", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "HostNameRedirectedFrom", toWK(hostNameRedirectedFrom) },
    }));
}

void TestRunner::setStatisticsCrossSiteLoadWithLinkDecoration(JSStringRef fromHost, JSStringRef toHost, bool wasFiltered)
{
    postSynchronousMessage("SetStatisticsCrossSiteLoadWithLinkDecoration", createWKDictionary({
        { "FromHost", toWK(fromHost) },
        { "ToHost", toWK(toHost) },
        { "WasFiltered", adoptWK(WKBooleanCreate(wasFiltered)) },
    }));
}

void TestRunner::setStatisticsTimeToLiveUserInteraction(double seconds)
{
    postSynchronousMessage("SetStatisticsTimeToLiveUserInteraction", seconds);
}

void TestRunner::statisticsNotifyObserver(JSContextRef context, JSValueRef callback)
{
    auto globalContext = JSContextGetGlobalContext(context);
    JSValueProtect(globalContext, callback);
    InjectedBundle::singleton().statisticsNotifyObserver([callback, globalContext = JSRetainPtr { globalContext }] {
        JSContextRef context = globalContext.get();
        JSObjectCallAsFunction(context, JSValueToObject(context, callback, nullptr), JSContextGetGlobalObject(context), 0, nullptr, nullptr);
        JSValueUnprotect(context, callback);
    });
}

void TestRunner::statisticsProcessStatisticsAndDataRecords(JSContextRef context, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsProcessStatisticsAndDataRecords", completionHandler);
}

void TestRunner::statisticsUpdateCookieBlocking(JSContextRef context, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsUpdateCookieBlocking", completionHandler);
}

void TestRunner::setStatisticsTimeAdvanceForTesting(double value)
{
    postSynchronousMessage("StatisticsSetTimeAdvanceForTesting", value);
}

void TestRunner::setStatisticsIsRunningTest(bool value)
{
    postSynchronousMessage("StatisticsSetIsRunningTest", value);
}

void TestRunner::setStatisticsShouldClassifyResourcesBeforeDataRecordsRemoval(bool value)
{
    postSynchronousMessage("StatisticsShouldClassifyResourcesBeforeDataRecordsRemoval", value);
}

void TestRunner::setStatisticsMinimumTimeBetweenDataRecordsRemoval(double seconds)
{
    postSynchronousMessage("SetStatisticsMinimumTimeBetweenDataRecordsRemoval", seconds);
}

void TestRunner::setStatisticsGrandfatheringTime(double seconds)
{
    postSynchronousMessage("SetStatisticsGrandfatheringTime", seconds);
}

void TestRunner::setStatisticsMaxStatisticsEntries(unsigned entries)
{
    postSynchronousMessage("SetMaxStatisticsEntries", entries);
}
    
void TestRunner::setStatisticsPruneEntriesDownTo(unsigned entries)
{
    postSynchronousMessage("SetPruneEntriesDownTo", entries);
}

void TestRunner::statisticsClearInMemoryAndPersistentStoreModifiedSinceHours(JSContextRef context, unsigned hours, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "StatisticsClearInMemoryAndPersistentStore", adoptWK(WKUInt64Create(hours)), callback);
}

void TestRunner::statisticsClearInMemoryAndPersistentStore(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "StatisticsClearInMemoryAndPersistentStore", callback);
}

void TestRunner::statisticsClearThroughWebsiteDataRemoval(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "StatisticsClearThroughWebsiteDataRemoval", callback);
}

void TestRunner::statisticsDeleteCookiesForHost(JSContextRef context, JSStringRef hostName, bool includeHttpOnlyCookies, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "StatisticsDeleteCookiesForHost", createWKDictionary({
        { "HostName", toWK(hostName) },
        { "IncludeHttpOnlyCookies", adoptWK(WKBooleanCreate(includeHttpOnlyCookies)) },
    }), callback);
}

bool TestRunner::isStatisticsHasLocalStorage(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("IsStatisticsHasLocalStorage", hostName);
}

void TestRunner::setStatisticsCacheMaxAgeCap(double seconds)
{
    postSynchronousMessage("SetStatisticsCacheMaxAgeCap", seconds);
}

bool TestRunner::hasStatisticsIsolatedSession(JSStringRef hostName)
{
    return postSynchronousPageMessageReturningBoolean("HasStatisticsIsolatedSession", hostName);
}

void TestRunner::setStatisticsShouldDowngradeReferrer(JSContextRef context, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsShouldDowngradeReferrer", adoptWK(WKBooleanCreate(value)), completionHandler);
}

void TestRunner::setStatisticsShouldBlockThirdPartyCookies(JSContextRef context, bool value, JSValueRef completionHandler, bool onlyOnSitesWithoutUserInteraction, bool onlyUnpartitionedCookies)
{
    auto messageName = "SetStatisticsShouldBlockThirdPartyCookies";
    if (onlyOnSitesWithoutUserInteraction)
        messageName = "SetStatisticsShouldBlockThirdPartyCookiesOnSitesWithoutUserInteraction";
    else if (onlyUnpartitionedCookies)
        messageName = "SetStatisticsShouldBlockThirdPartyCookiesExceptPartitioned";
    postMessageWithAsyncReply(context, messageName, adoptWK(WKBooleanCreate(value)), completionHandler);
}

void TestRunner::setStatisticsFirstPartyWebsiteDataRemovalMode(JSContextRef context, bool value, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "SetStatisticsFirstPartyWebsiteDataRemovalMode", adoptWK(WKBooleanCreate(value)), completionHandler);
}

void TestRunner::statisticsSetToSameSiteStrictCookies(JSContextRef context, JSStringRef hostName, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsSetToSameSiteStrictCookies", toWK(hostName), completionHandler);
}

void TestRunner::statisticsSetFirstPartyHostCNAMEDomain(JSContextRef context, JSStringRef firstPartyURLString, JSStringRef cnameURLString, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsSetFirstPartyHostCNAMEDomain", createWKDictionary({
        { "FirstPartyURL", toWK(firstPartyURLString) },
        { "CNAME", toWK(cnameURLString) },
    }), completionHandler);
}

void TestRunner::statisticsSetThirdPartyCNAMEDomain(JSContextRef context, JSStringRef cnameURLString, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsSetThirdPartyCNAMEDomain", toWK(cnameURLString), completionHandler);
}

void TestRunner::statisticsResetToConsistentState(JSContextRef context, JSValueRef completionHandler)
{
    postMessageWithAsyncReply(context, "StatisticsResetToConsistentState", completionHandler);
}

void TestRunner::installTextDidChangeInTextFieldCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, TextDidChangeInTextFieldCallbackID, callback);
}

void TestRunner::textDidChangeInTextFieldCallback()
{
    callTestRunnerCallback(TextDidChangeInTextFieldCallbackID);
}

void TestRunner::installTextFieldDidBeginEditingCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, TextFieldDidBeginEditingCallbackID, callback);
}

void TestRunner::textFieldDidBeginEditingCallback()
{
    callTestRunnerCallback(TextFieldDidBeginEditingCallbackID);
}

void TestRunner::installTextFieldDidEndEditingCallback(JSContextRef context, JSValueRef callback)
{
    cacheTestRunnerCallback(context, TextFieldDidEndEditingCallbackID, callback);
}

void TestRunner::textFieldDidEndEditingCallback()
{
    callTestRunnerCallback(TextFieldDidEndEditingCallbackID);
}

void TestRunner::getAllStorageAccessEntries(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "GetAllStorageAccessEntries", callback);
}

void TestRunner::setRequestStorageAccessThrowsExceptionUntilReload(bool enabled)
{
    postSynchronousPageMessage("SetRequestStorageAccessThrowsExceptionUntilReload", enabled);
}

void TestRunner::setStorageAccessPermission(JSContextRef context, bool granted, JSStringRef subFrameURL, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SetStorageAccessPermission", createWKDictionary({
        { "Value", adoptWK(WKBooleanCreate(granted)) },
        { "SubFrameURL", toWK(subFrameURL) },
    }), callback);
}

void TestRunner::loadedSubresourceDomains(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "LoadedSubresourceDomains", callback);
}

void TestRunner::reloadFromOrigin()
{
    InjectedBundle::singleton().reloadFromOrigin();
}

void TestRunner::addMockMediaDevice(JSStringRef persistentId, JSStringRef label, const char* type, WKDictionaryRef properties)
{
    postSynchronousMessage("AddMockMediaDevice", createWKDictionary({
        { "PersistentID", toWK(persistentId) },
        { "Label", toWK(label) },
        { "Type", toWK(type) },
        { "Properties", properties },
    }));
}

static WKRetainPtr<WKDictionaryRef> captureDeviceProperties(JSContextRef context, JSValueRef properties)
{
    if (JSValueGetType(context, properties) == kJSTypeUndefined)
        return { };

    Vector<WKRetainPtr<WKStringRef>> strings;
    Vector<WKStringRef> keys;
    Vector<WKTypeRef> values;

    if (auto object = JSValueToObject(context, properties, nullptr)) {
        JSPropertyNameArrayRef propertyNameArray = JSObjectCopyPropertyNames(context, object);
        size_t length = JSPropertyNameArrayGetCount(propertyNameArray);

        for (size_t i = 0; i < length; ++i) {
            JSStringRef jsPropertyName = JSPropertyNameArrayGetNameAtIndex(propertyNameArray, i);
            auto jsPropertyValue = JSObjectGetProperty(context, object, jsPropertyName, 0);

            auto propertyName = toWK(jsPropertyName);
            auto propertyValue = toWKString(context, jsPropertyValue);

            keys.append(propertyName.get());
            values.append(propertyValue.get());
            strings.append(WTFMove(propertyName));
            strings.append(WTFMove(propertyValue));
        }
        JSPropertyNameArrayRelease(propertyNameArray);
    }

    return adoptWK(WKDictionaryCreate(keys.span().data(), values.span().data(), keys.size()));
}

void TestRunner::addMockCameraDevice(JSContextRef context, JSStringRef persistentId, JSStringRef label, JSValueRef properties)
{
    addMockMediaDevice(persistentId, label, "camera", captureDeviceProperties(context, properties).get());
}

void TestRunner::addMockMicrophoneDevice(JSContextRef context, JSStringRef persistentId, JSStringRef label, JSValueRef properties)
{
    addMockMediaDevice(persistentId, label, "microphone", captureDeviceProperties(context, properties).get());
}

void TestRunner::addMockScreenDevice(JSStringRef persistentId, JSStringRef label)
{
    addMockMediaDevice(persistentId, label, "screen", nullptr);
}

void TestRunner::clearMockMediaDevices()
{
    postSynchronousMessage("ClearMockMediaDevices");
}

void TestRunner::removeMockMediaDevice(JSStringRef persistentId)
{
    postSynchronousMessage("RemoveMockMediaDevice", toWK(persistentId));
}

void TestRunner::setMockMediaDeviceIsEphemeral(JSStringRef persistentId, bool isEphemeral)
{
    postSynchronousMessage("SetMockMediaDeviceIsEphemeral", createWKDictionary({
        { "PersistentID", toWK(persistentId) },
        { "IsEphemeral", adoptWK(WKBooleanCreate(isEphemeral)) },
    }));
}

void TestRunner::resetMockMediaDevices()
{
    postSynchronousMessage("ResetMockMediaDevices");
}

void TestRunner::setMockCameraOrientation(unsigned rotation, JSStringRef persistentId)
{
    postSynchronousMessage("SetMockCameraRotation", createWKDictionary({
        { "Rotation", adoptWK(WKUInt64Create(rotation)) },
        { "PersistentID", toWK(persistentId) },
    }));
}

bool TestRunner::isMockRealtimeMediaSourceCenterEnabled()
{
    return postSynchronousMessageReturningBoolean("IsMockRealtimeMediaSourceCenterEnabled");
}

void TestRunner::setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted)
{
    postSynchronousMessage("SetMockCaptureDevicesInterrupted", createWKDictionary({
        { "camera", adoptWK(WKBooleanCreate(isCameraInterrupted)) },
        { "microphone", adoptWK(WKBooleanCreate(isMicrophoneInterrupted)) },
    }));
}

void TestRunner::triggerMockCaptureConfigurationChange(bool forCamera, bool forMicrophone, bool forDisplay)
{
    postSynchronousMessage("TriggerMockCaptureConfigurationChange", createWKDictionary({
        { "camera", adoptWK(WKBooleanCreate(forCamera)) },
        { "microphone", adoptWK(WKBooleanCreate(forMicrophone)) },
        { "display", adoptWK(WKBooleanCreate(forDisplay)) },
    }));
}

void TestRunner::setCaptureState(bool cameraState, bool microphoneState, bool displayState)
{
    postSynchronousMessage("SetCaptureState", createWKDictionary({
        { "camera", adoptWK(WKBooleanCreate(cameraState)) },
        { "microphone", adoptWK(WKBooleanCreate(microphoneState)) },
        { "display", adoptWK(WKBooleanCreate(displayState)) },
    }));
}

#if ENABLE(GAMEPAD)

void TestRunner::connectMockGamepad(unsigned index)
{
    postSynchronousMessage("ConnectMockGamepad", index);
}

void TestRunner::disconnectMockGamepad(unsigned index)
{
    postSynchronousMessage("DisconnectMockGamepad", index);
}

void TestRunner::setMockGamepadDetails(unsigned index, JSStringRef gamepadID, JSStringRef mapping, unsigned axisCount, unsigned buttonCount, bool supportsDualRumble)
{
    postSynchronousMessage("SetMockGamepadDetails", createWKDictionary({
        { "GamepadID", toWK(gamepadID) },
        { "Mapping", toWK(mapping) },
        { "GamepadIndex", adoptWK(WKUInt64Create(index)) },
        { "AxisCount", adoptWK(WKUInt64Create(axisCount)) },
        { "ButtonCount", adoptWK(WKUInt64Create(buttonCount)) },
        { "SupportsDualRumble", adoptWK(WKBooleanCreate(supportsDualRumble)) },
    }));
}

void TestRunner::setMockGamepadAxisValue(unsigned index, unsigned axisIndex, double value)
{
    postSynchronousMessage("SetMockGamepadAxisValue", createWKDictionary({
        { "GamepadIndex", adoptWK(WKUInt64Create(index)) },
        { "AxisIndex", adoptWK(WKUInt64Create(axisIndex)) },
        { "Value", adoptWK(WKDoubleCreate(value)) },
    }));
}

void TestRunner::setMockGamepadButtonValue(unsigned index, unsigned buttonIndex, double value)
{
    postSynchronousMessage("SetMockGamepadButtonValue", createWKDictionary({
        { "GamepadIndex", adoptWK(WKUInt64Create(index)) },
        { "ButtonIndex", adoptWK(WKUInt64Create(buttonIndex)) },
        { "Value", adoptWK(WKDoubleCreate(value)) },
    }));
}

#else

void TestRunner::connectMockGamepad(unsigned)
{
}

void TestRunner::disconnectMockGamepad(unsigned)
{
}

void TestRunner::setMockGamepadDetails(unsigned, JSStringRef, JSStringRef, unsigned, unsigned, bool)
{
}

void TestRunner::setMockGamepadAxisValue(unsigned, unsigned, double)
{
}

void TestRunner::setMockGamepadButtonValue(unsigned, unsigned, double)
{
}

#endif // ENABLE(GAMEPAD)

static WKRetainPtr<WKURLRef> makeOpenPanelURL(WKURLRef baseURL, char* filePath)
{
#if OS(WINDOWS)
    if (!PathIsRelativeA(filePath)) {
        char fileURI[INTERNET_MAX_PATH_LENGTH];
        DWORD fileURILength = INTERNET_MAX_PATH_LENGTH;
        UrlCreateFromPathA(filePath, fileURI, &fileURILength, 0);
        return adoptWK(WKURLCreateWithUTF8CString(fileURI));
    }
#else
    WKRetainPtr<WKURLRef> fileURL;
    if (filePath[0] == '/') {
        fileURL = adoptWK(WKURLCreateWithUTF8CString("file://"));
        baseURL = fileURL.get();
    }
#endif
    return adoptWK(WKURLCreateWithBaseURL(baseURL, filePath));
}

void TestRunner::setOpenPanelFiles(JSContextRef context, JSValueRef filesValue)
{
    if (!JSValueIsArray(context, filesValue))
        return;

    auto files = (JSObjectRef)filesValue;
    auto fileURLs = adoptWK(WKMutableArrayCreate());
    auto filesLength = arrayLength(context, files);
    for (size_t i = 0; i < filesLength; ++i) {
        JSValueRef fileValue = JSObjectGetPropertyAtIndex(context, files, i, nullptr);
        if (!JSValueIsString(context, fileValue))
            continue;

        auto file = createJSString(context, fileValue);
        size_t fileBufferSize = JSStringGetMaximumUTF8CStringSize(file.get()) + 1;
        auto fileBuffer = makeUniqueArray<char>(fileBufferSize);
        JSStringGetUTF8CString(file.get(), fileBuffer.get(), fileBufferSize);

        WKArrayAppendItem(fileURLs.get(), makeOpenPanelURL(m_testURL.get(), fileBuffer.get()).get());
    }

    postPageMessage("SetOpenPanelFileURLs", fileURLs);
}

void TestRunner::setOpenPanelFilesMediaIcon(JSContextRef context, JSValueRef data)
{
#if PLATFORM(IOS_FAMILY)
    // FIXME (123058): Use a JSC API to get buffer contents once such is exposed.
    auto iconData = adoptWK(WKBundleCreateWKDataFromUInt8Array(InjectedBundle::singleton().bundle(), context, data));
    postPageMessage("SetOpenPanelFileURLsMediaIcon", iconData);
#else
    UNUSED_PARAM(context);
    UNUSED_PARAM(data);
#endif
}

void TestRunner::removeAllSessionCredentials(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "RemoveAllSessionCredentials", callback);
}

void TestRunner::clearDOMCache(JSStringRef origin)
{
    postSynchronousMessage("ClearDOMCache", toWK(origin));
}

void TestRunner::clearStorage()
{
    postSynchronousMessage("ClearStorage");
}

void TestRunner::clearDOMCaches()
{
    postSynchronousMessage("ClearDOMCaches");
}

bool TestRunner::hasDOMCache(JSStringRef origin)
{
    return postSynchronousPageMessageReturningBoolean("HasDOMCache", origin);
}

uint64_t TestRunner::domCacheSize(JSStringRef origin)
{
    return postSynchronousPageMessageReturningUInt64("DOMCacheSize", origin);
}

void TestRunner::setAllowStorageQuotaIncrease(bool willIncrease)
{
    postSynchronousPageMessage("SetAllowStorageQuotaIncrease", willIncrease);
}

void TestRunner::setQuota(uint64_t quota)
{
    postSynchronousMessage("SetQuota", quota);
}

void TestRunner::setOriginQuotaRatioEnabled(bool enabled)
{
    postSynchronousPageMessage("SetOriginQuotaRatioEnabled", enabled);
}

void TestRunner::getApplicationManifestThen(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "GetApplicationManifest", callback);
}

void TestRunner::installFakeHelvetica(JSStringRef configuration)
{
    WTR::installFakeHelvetica(toWK(configuration).get());
}

size_t TestRunner::userScriptInjectedCount() const
{
    return InjectedBundle::singleton().userScriptInjectedCount();
}

void TestRunner::injectUserScript(JSStringRef script)
{
    postSynchronousMessage("InjectUserScript", toWK(script));
}

void TestRunner::setServiceWorkerFetchTimeout(double seconds)
{
    postSynchronousMessage("SetServiceWorkerFetchTimeout", seconds);
}

// WebAuthn
void TestRunner::addTestKeyToKeychain(JSStringRef privateKeyBase64, JSStringRef attrLabel, JSStringRef applicationTagBase64)
{
    postSynchronousMessage("AddTestKeyToKeychain", createWKDictionary({
        { "PrivateKey", toWK(privateKeyBase64) },
        { "AttrLabel", toWK(attrLabel) },
        { "ApplicationTag", toWK(applicationTagBase64) },
    }));
}

void TestRunner::cleanUpKeychain(JSStringRef attrLabel, JSStringRef applicationLabelBase64)
{
    if (!applicationLabelBase64) {
        postSynchronousMessage("CleanUpKeychain", createWKDictionary({
            { "AttrLabel", toWK(attrLabel) },
        }));
        return;
    }
    postSynchronousMessage("CleanUpKeychain", createWKDictionary({
        { "AttrLabel", toWK(attrLabel) },
        { "ApplicationLabel", toWK(applicationLabelBase64) },
    }));
}

bool TestRunner::keyExistsInKeychain(JSStringRef attrLabel, JSStringRef applicationLabelBase64)
{
    return postSynchronousMessageReturningBoolean("KeyExistsInKeychain", createWKDictionary({
        { "AttrLabel", toWK(attrLabel) },
        { "ApplicationLabel", toWK(applicationLabelBase64) },
    }));
}

unsigned long TestRunner::serverTrustEvaluationCallbackCallsCount()
{
    return postSynchronousMessageReturningUInt64("ServerTrustEvaluationCallbackCallsCount");
}

void TestRunner::setShouldDismissJavaScriptAlertsAsynchronously(bool shouldDismissAsynchronously)
{
    postSynchronousMessage("ShouldDismissJavaScriptAlertsAsynchronously", shouldDismissAsynchronously);
}

void TestRunner::abortModal()
{
    postSynchronousMessage("AbortModal");
}

void TestRunner::dumpPrivateClickMeasurement()
{
    postSynchronousPageMessage("DumpPrivateClickMeasurement");
}

void TestRunner::clearMemoryCache()
{
    postSynchronousPageMessage("ClearMemoryCache");
}

void TestRunner::clearPrivateClickMeasurement()
{
    postSynchronousPageMessage("ClearPrivateClickMeasurement");
}

void TestRunner::clearPrivateClickMeasurementsThroughWebsiteDataRemoval()
{
    postSynchronousMessage("ClearPrivateClickMeasurementsThroughWebsiteDataRemoval");
}

void TestRunner::setPrivateClickMeasurementOverrideTimerForTesting(bool value)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementOverrideTimerForTesting", value);
}

void TestRunner::markAttributedPrivateClickMeasurementsAsExpiredForTesting()
{
    postSynchronousPageMessage("MarkAttributedPrivateClickMeasurementsAsExpiredForTesting");
}

void TestRunner::setPrivateClickMeasurementEphemeralMeasurementForTesting(bool value)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementEphemeralMeasurementForTesting", value);
}

void TestRunner::simulatePrivateClickMeasurementSessionRestart()
{
    postSynchronousPageMessage("SimulatePrivateClickMeasurementSessionRestart");
}

void TestRunner::setPrivateClickMeasurementTokenPublicKeyURLForTesting(JSStringRef urlString)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementTokenPublicKeyURLForTesting",
        adoptWK(WKURLCreateWithUTF8CString(toWTFString(urlString).utf8().data())));
}

void TestRunner::setPrivateClickMeasurementTokenSignatureURLForTesting(JSStringRef urlString)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementTokenSignatureURLForTesting",
        adoptWK(WKURLCreateWithUTF8CString(toWTFString(urlString).utf8().data())));
}

void TestRunner::setPrivateClickMeasurementAttributionReportURLsForTesting(JSStringRef sourceURLString, JSStringRef destinationURLString)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementAttributionReportURLsForTesting", createWKDictionary({
        { "SourceURLString", toWK(sourceURLString) },
        { "AttributeOnURLString", toWK(destinationURLString) },
    }));
}

void TestRunner::markPrivateClickMeasurementsAsExpiredForTesting()
{
    postSynchronousPageMessage("MarkPrivateClickMeasurementsAsExpiredForTesting");
}

void TestRunner::setPrivateClickMeasurementFraudPreventionValuesForTesting(JSStringRef unlinkableToken, JSStringRef secretToken, JSStringRef signature, JSStringRef keyID)
{
    postSynchronousMessage("SetPCMFraudPreventionValuesForTesting", createWKDictionary({
        { "UnlinkableToken", toWK(unlinkableToken) },
        { "SecretToken", toWK(secretToken) },
        { "Signature", toWK(signature) },
        { "KeyID", toWK(keyID) },
    }));
}

void TestRunner::setPrivateClickMeasurementAppBundleIDForTesting(JSStringRef appBundleID)
{
    postSynchronousPageMessage("SetPrivateClickMeasurementAppBundleIDForTesting",
        toWK(appBundleID));
}

bool TestRunner::hasAppBoundSession()
{
    return postSynchronousPageMessageReturningBoolean("HasAppBoundSession");
}

void TestRunner::clearAppBoundSession()
{
    postSynchronousMessage("ClearAppBoundSession");
}

void TestRunner::setAppBoundDomains(JSContextRef context, JSValueRef originArray, JSValueRef completionHandler)
{
    if (!JSValueIsArray(context, originArray))
        return;

    auto origins = JSValueToObject(context, originArray, nullptr);
    auto originURLs = adoptWK(WKMutableArrayCreate());
    auto originsLength = arrayLength(context, origins);
    for (unsigned i = 0; i < originsLength; ++i) {
        JSValueRef originValue = JSObjectGetPropertyAtIndex(context, origins, i, nullptr);
        if (!JSValueIsString(context, originValue))
            continue;

        auto origin = createJSString(context, originValue);
        size_t originBufferSize = JSStringGetMaximumUTF8CStringSize(origin.get()) + 1;
        auto originBuffer = makeUniqueArray<char>(originBufferSize);
        JSStringGetUTF8CString(origin.get(), originBuffer.get(), originBufferSize);

        WKArrayAppendItem(originURLs.get(), adoptWK(WKURLCreateWithUTF8CString(originBuffer.get())).get());
    }

    postMessageWithAsyncReply(context, "SetAppBoundDomains", originURLs, completionHandler);
}

void TestRunner::setManagedDomains(JSContextRef context, JSValueRef originArray, JSValueRef completionHandler)
{
    if (!JSValueIsArray(context, originArray))
        return;

    auto origins = JSValueToObject(context, originArray, nullptr);
    auto originURLs = adoptWK(WKMutableArrayCreate());
    auto originsLength = arrayLength(context, origins);
    for (unsigned i = 0; i < originsLength; ++i) {
        JSValueRef originValue = JSObjectGetPropertyAtIndex(context, origins, i, nullptr);
        if (!JSValueIsString(context, originValue))
            continue;

        auto origin = createJSString(context, originValue);
        size_t originBufferSize = JSStringGetMaximumUTF8CStringSize(origin.get()) + 1;
        auto originBuffer = makeUniqueArray<char>(originBufferSize);
        JSStringGetUTF8CString(origin.get(), originBuffer.get(), originBufferSize);

        WKArrayAppendItem(originURLs.get(), adoptWK(WKURLCreateWithUTF8CString(originBuffer.get())).get());
    }

    postMessageWithAsyncReply(context, "SetManagedDomains", originURLs, completionHandler);
}

bool TestRunner::didLoadAppInitiatedRequest()
{
    return postSynchronousPageMessageReturningBoolean("DidLoadAppInitiatedRequest");
}

bool TestRunner::didLoadNonAppInitiatedRequest()
{
    return postSynchronousPageMessageReturningBoolean("DidLoadNonAppInitiatedRequest");
}

void TestRunner::setIsSpeechRecognitionPermissionGranted(bool granted)
{
    postSynchronousPageMessage("SetIsSpeechRecognitionPermissionGranted", granted);
}

void TestRunner::setIsMediaKeySystemPermissionGranted(bool granted)
{
    postSynchronousPageMessage("SetIsMediaKeySystemPermissionGranted", granted);
}

void TestRunner::takeViewPortSnapshot(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "TakeViewPortSnapshot", callback);
}

void TestRunner::flushConsoleLogs(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "FlushConsoleLogs", callback);
}

void TestRunner::updatePresentation(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "UpdatePresentation", callback);
}

void TestRunner::waitBeforeFinishingFullscreenExit()
{
    postPageMessage("WaitBeforeFinishingFullscreenExit");
}

void TestRunner::scrollDuringEnterFullscreen()
{
    postPageMessage("ScrollDuringEnterFullscreen");
}

void TestRunner::finishFullscreenExit()
{
    postPageMessage("FinishFullscreenExit");
}

void TestRunner::requestExitFullscreenFromUIProcess()
{
    postPageMessage("RequestExitFullscreenFromUIProcess");
}

void TestRunner::setPageScaleFactor(JSContextRef context, double scaleFactor, long x, long y, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SetPageScaleFactor", createWKDictionary({
        { "scaleFactor", toWK(scaleFactor) },
        { "x", toWK(static_cast<double>(x)) },
        { "y", toWK(static_cast<double>(y)) },
        }), callback);
}

void TestRunner::generateTestReport(JSContextRef context, JSStringRef message, JSStringRef group)
{
    auto frame = WKBundleFrameForJavaScriptContext(context);
    _WKBundleFrameGenerateTestReport(frame, toWK(message).get(), toWK(group).get());
}

void TestRunner::getAndClearReportedWindowProxyAccessDomains(JSContextRef context, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "GetAndClearReportedWindowProxyAccessDomains", callback);
}

void TestRunner::dumpBackForwardList()
{
    postSynchronousPageMessage("DumpBackForwardList");
}

bool TestRunner::shouldDumpBackForwardListsForAllWindows() const
{
    return postSynchronousPageMessageReturningBoolean("ShouldDumpBackForwardListsForAllWindows");
}

void TestRunner::setObscuredContentInsets(JSContextRef context, double top, double right, double bottom, double left, JSValueRef callback)
{
    auto insetValues = adoptWK(WKMutableArrayCreate());
    WKArrayAppendItem(insetValues.get(), adoptWK(WKDoubleCreate(top)).get());
    WKArrayAppendItem(insetValues.get(), adoptWK(WKDoubleCreate(right)).get());
    WKArrayAppendItem(insetValues.get(), adoptWK(WKDoubleCreate(bottom)).get());
    WKArrayAppendItem(insetValues.get(), adoptWK(WKDoubleCreate(left)).get());
    postMessageWithAsyncReply(context, "SetObscuredContentInsets", insetValues, callback);
}

void TestRunner::setResourceMonitorList(JSContextRef context, JSStringRef rulesText, JSValueRef callback)
{
    postMessageWithAsyncReply(context, "SetResourceMonitorList", toWK(rulesText), callback);
}

void TestRunner::dumpChildFrameScrollPositions()
{
    postSynchronousPageMessage("DumpChildFrameScrollPositions");
}

bool TestRunner::shouldDumpAllFrameScrollPositions() const
{
    return postSynchronousPageMessageReturningBoolean("ShouldDumpAllFrameScrollPositions");
}

ALLOW_DEPRECATED_DECLARATIONS_END

} // namespace WTR
