/*
 * Copyright (C) 2010-2020 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 "InjectedBundle.h"

#include "ActivateFonts.h"
#include "DictionaryFunctions.h"
#include "InjectedBundlePage.h"
#include "WebCoreTestSupport.h"
#include <JavaScriptCore/Options.h>
#include <WebKit/WKBundle.h>
#include <WebKit/WKBundlePage.h>
#include <WebKit/WKBundlePagePrivate.h>
#include <WebKit/WKBundlePrivate.h>
#include <WebKit/WKRetainPtr.h>
#include <WebKit/WebKit2_C.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/Vector.h>

namespace WTR {

static void handleTextDidChangeInTextField(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef, const void* context)
{
    static_cast<InjectedBundle*>(const_cast<void*>(context))->textDidChangeInTextField();
}

static void handleTextFieldDidBeginEditing(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef, const void* context)
{
    static_cast<InjectedBundle*>(const_cast<void*>(context))->textFieldDidBeginEditing();
}

static void handleTextFieldDidEndEditing(WKBundlePageRef, WKBundleNodeHandleRef, WKBundleFrameRef, const void* context)
{
    static_cast<InjectedBundle*>(const_cast<void*>(context))->textFieldDidEndEditing();
}

InjectedBundle& InjectedBundle::singleton()
{
    static InjectedBundle& shared = *new InjectedBundle;
    return shared;
}

void InjectedBundle::didCreatePage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
{
    static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didCreatePage(page);
}

void InjectedBundle::willDestroyPage(WKBundleRef bundle, WKBundlePageRef page, const void* clientInfo)
{
    static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->willDestroyPage(page);
}

void InjectedBundle::didReceiveMessage(WKBundleRef bundle, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
{
    static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessage(messageName, messageBody);
}

void InjectedBundle::didReceiveMessageToPage(WKBundleRef bundle, WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
{
    static_cast<InjectedBundle*>(const_cast<void*>(clientInfo))->didReceiveMessageToPage(page, messageName, messageBody);
}

void InjectedBundle::initialize(WKBundleRef bundle, WKTypeRef initializationUserData)
{
    m_bundle = bundle;

    WKBundleClientV1 client = {
        { 1, this },
        didCreatePage,
        willDestroyPage,
        nullptr,
        didReceiveMessage,
        didReceiveMessageToPage
    };
    WKBundleSetClient(m_bundle.get(), &client.base);
    WKBundleSetServiceWorkerProxyCreationCallback(m_bundle.get(), WebCoreTestSupport::setupNewlyCreatedServiceWorker);
    platformInitialize(initializationUserData);
    WebCoreTestSupport::populateJITOperations();

    activateFonts();
}

void InjectedBundle::didCreatePage(WKBundlePageRef page)
{
    bool isMainPage = m_pages.isEmpty();
    m_pages.append(makeUnique<InjectedBundlePage>(page));

    setUpInjectedBundleClients(page);

    if (!isMainPage)
        return;

    WKTypeRef result = nullptr;
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    WKBundlePostSynchronousMessage(m_bundle.get(), toWK("Initialization").get(), nullptr, &result);
    ALLOW_DEPRECATED_DECLARATIONS_END
    auto initializationDictionary = adoptWK(dictionaryValue(result));

    if (booleanValue(initializationDictionary.get(), "ResumeTesting"))
        beginTesting(initializationDictionary.get(), BegingTestingMode::Resume);
}

void InjectedBundle::willDestroyPage(WKBundlePageRef page)
{
    m_pages.removeFirstMatching([page](auto& current) {
        return current->page() == page;
    });
}

void InjectedBundle::setUpInjectedBundleClients(WKBundlePageRef page)
{
    WKBundlePageFormClientV2 formClient = {
        { 2, this },
        handleTextFieldDidBeginEditing,
        handleTextFieldDidEndEditing,
        handleTextDidChangeInTextField,
        0, // textDidChangeInTextArea
        0, // shouldPerformActionInTextField
        0, // willSubmitForm
        0, // willSendSubmitEvent
        0, // didFocusTextField
        0, // shouldNotifyOnFormChanges
        0, // didAssociateFormControls
    };
    WKBundlePageSetFormClient(page, &formClient.base);
}

InjectedBundlePage* InjectedBundle::page() const
{
    // It might be better to have the UI process send over a reference to the main
    // page instead of just assuming it's the first non-suspended one.
    for (auto& page : m_pages) {
        if (!WKBundlePageIsSuspended(page->page()))
            return page.get();
    }
    return m_pages[0].get();
}

WKBundlePageRef InjectedBundle::pageRef() const
{
    auto page = this->page();
    return page ? page->page() : nullptr;
}

void InjectedBundle::didReceiveMessage(WKStringRef, WKTypeRef)
{
    WKBundlePostMessage(m_bundle.get(), toWK("Error").get(), toWK("Unknown").get());
}

static void postGCTask(void* context)
{
    auto page = reinterpret_cast<WKBundlePageRef>(context);
    InjectedBundle::singleton().reportLiveDocuments(page);
    WKRelease(page);
}

void InjectedBundle::reportLiveDocuments(WKBundlePageRef page)
{
    // Release memory again, after the GC and timer fire. This is necessary to clear entries from CachedResourceLoader's m_documentResources in some scenarios.
    WKBundleReleaseMemory(m_bundle.get());

    const bool excludeDocumentsInPageGroup = true;
    WKBundlePagePostMessage(page, toWK("LiveDocuments").get(), adoptWK(WKBundleGetLiveDocumentURLsForTesting(m_bundle.get(), excludeDocumentsInPageGroup)).get());
}

void InjectedBundle::didReceiveMessageToPage(WKBundlePageRef page, WKStringRef messageName, WKTypeRef messageBody)
{
    if (WKStringIsEqualToUTF8CString(messageName, "BeginTest")) {
        ASSERT(messageBody);
        auto messageBodyDictionary = dictionaryValue(messageBody);
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
        m_accessibilityIsolatedTreeMode = booleanValue(messageBodyDictionary, "IsAccessibilityIsolatedTreeEnabled");
#endif
        WKBundlePagePostMessage(page, toWK("Ack").get(), toWK("BeginTest").get());
        beginTesting(messageBodyDictionary, BegingTestingMode::New);
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "Reset")) {
        ASSERT(messageBody);
        auto messageBodyDictionary = dictionaryValue(messageBody);
        if (auto options = stringValue(messageBodyDictionary, "JSCOptions"))
            JSC::Options::setOptions(toWTFString(options).utf8().data());
        if (booleanValue(messageBodyDictionary, "ShouldGC"))
            WKBundleGarbageCollectJavaScriptObjects(m_bundle.get());

        auto allowedHostsValue = value(messageBodyDictionary, "AllowedHosts");
        if (allowedHostsValue && WKGetTypeID(allowedHostsValue) == WKArrayGetTypeID()) {
            m_allowedHosts.clear();
            auto array = static_cast<WKArrayRef>(allowedHostsValue);
            for (size_t i = 0, size = WKArrayGetSize(array); i < size; ++i)
                m_allowedHosts.append(toWTFString(WKArrayGetItemAtIndex(array, i)));
        }

        m_state = Idle;
        m_dumpPixels = false;
        m_pixelResultIsPending = false;

        setlocale(LC_ALL, "");
        TestRunner::removeAllWebNotificationPermissions();

        InjectedBundle::page()->resetAfterTest();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "GetLiveDocuments")) {
        const bool excludeDocumentsInPageGroup = false;
        postPageMessage("LiveDocuments", adoptWK(WKBundleGetLiveDocumentURLsForTesting(m_bundle.get(), excludeDocumentsInPageGroup)));
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CheckForWorldLeaks")) {
        WKBundleReleaseMemory(m_bundle.get());

        WKRetain(page); // Balanced by the release in postGCTask.
        WKBundlePageCallAfterTasksAndTimers(page, postGCTask, (void*)page);
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallAddChromeInputFieldCallback")) {
        m_testRunner->callAddChromeInputFieldCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallRemoveChromeInputFieldCallback")) {
        m_testRunner->callRemoveChromeInputFieldCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallSetTextInChromeInputFieldCallback")) {
        m_testRunner->callSetTextInChromeInputFieldCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallSelectChromeInputFieldCallback")) {
        m_testRunner->callSelectChromeInputFieldCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallGetSelectedTextInChromeInputFieldCallback")) {
        ASSERT(messageBody);
        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
        auto jsString = toJS(static_cast<WKStringRef>(messageBody));
        m_testRunner->callGetSelectedTextInChromeInputFieldCallback(jsString.get());
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallFocusWebViewCallback")) {
        m_testRunner->callFocusWebViewCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallSetBackingScaleFactorCallback")) {
        m_testRunner->callSetBackingScaleFactorCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidBeginSwipeCallback")) {
        m_testRunner->callDidBeginSwipeCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallWillEndSwipeCallback")) {
        m_testRunner->callWillEndSwipeCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidEndSwipeCallback")) {
        m_testRunner->callDidEndSwipeCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveSwipeSnapshotCallback")) {
        m_testRunner->callDidRemoveSwipeSnapshotCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidClearStatisticsInMemoryAndPersistentStore")) {
        m_testRunner->statisticsCallClearInMemoryAndPersistentStoreCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidClearStatisticsThroughWebsiteDataRemoval")) {
        m_testRunner->statisticsCallClearThroughWebsiteDataRemovalCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetShouldDowngradeReferrer")) {
        m_testRunner->statisticsCallDidSetShouldDowngradeReferrerCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetShouldBlockThirdPartyCookies")) {
        m_testRunner->statisticsCallDidSetShouldBlockThirdPartyCookiesCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetFirstPartyWebsiteDataRemovalMode")) {
        m_testRunner->statisticsCallDidSetFirstPartyWebsiteDataRemovalModeCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetToSameSiteStrictCookies")) {
        m_testRunner->statisticsCallDidSetToSameSiteStrictCookiesCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetFirstPartyHostCNAMEDomain")) {
        m_testRunner->statisticsCallDidSetFirstPartyHostCNAMEDomainCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetThirdPartyCNAMEDomain")) {
        m_testRunner->statisticsCallDidSetThirdPartyCNAMEDomainCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidResetStatisticsToConsistentState")) {
        m_testRunner->statisticsCallDidResetToConsistentStateCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetBlockCookiesForHost")) {
        m_testRunner->statisticsCallDidSetBlockCookiesForHostCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetStatisticsDebugMode")) {
        m_testRunner->statisticsCallDidSetDebugModeCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetPrevalentResourceForDebugMode")) {
        m_testRunner->statisticsCallDidSetPrevalentResourceForDebugModeCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetLastSeen")) {
        m_testRunner->statisticsCallDidSetLastSeenCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidMergeStatistic")) {
        m_testRunner->statisticsCallDidSetMergeStatisticCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetExpiredStatistic")) {
        m_testRunner->statisticsCallDidSetExpiredStatisticCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetPrevalentResource")) {
        m_testRunner->statisticsCallDidSetPrevalentResourceCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetVeryPrevalentResource")) {
        m_testRunner->statisticsCallDidSetVeryPrevalentResourceCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetHasHadUserInteraction")) {
        m_testRunner->statisticsCallDidSetHasHadUserInteractionCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidReceiveAllStorageAccessEntries")) {
        ASSERT(messageBody);
        ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID());

        WKArrayRef domainsArray = static_cast<WKArrayRef>(messageBody);
        auto size = WKArrayGetSize(domainsArray);
        Vector<String> domains;
        domains.reserveInitialCapacity(size);
        for (size_t i = 0; i < size; ++i) {
            auto item = WKArrayGetItemAtIndex(domainsArray, i);
            if (item && WKGetTypeID(item) == WKStringGetTypeID())
                domains.append(toWTFString(static_cast<WKStringRef>(item)));
        }

        m_testRunner->callDidReceiveAllStorageAccessEntriesCallback(domains);
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "CallDidReceiveLoadedSubresourceDomains")) {
        ASSERT(messageBody);
        ASSERT(WKGetTypeID(messageBody) == WKArrayGetTypeID());

        WKArrayRef domainsArray = static_cast<WKArrayRef>(messageBody);
        auto size = WKArrayGetSize(domainsArray);
        Vector<String> domains;
        domains.reserveInitialCapacity(size);
        for (size_t i = 0; i < size; ++i) {
            auto item = WKArrayGetItemAtIndex(domainsArray, i);
            if (item && WKGetTypeID(item) == WKStringGetTypeID())
                domains.uncheckedAppend(toWTFString(static_cast<WKStringRef>(item)));
        }

        m_testRunner->callDidReceiveLoadedSubresourceDomainsCallback(WTFMove(domains));
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidRemoveAllSessionCredentialsCallback")) {
        m_testRunner->callDidRemoveAllSessionCredentialsCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "NotifyDownloadDone")) {
        if (m_testRunner->shouldFinishAfterDownload())
            m_testRunner->notifyDone();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "NotifyDone")) {
        InjectedBundle::page()->dump();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallUISideScriptCallback")) {
        auto messageBodyDictionary = dictionaryValue(messageBody);
        auto callbackID = uint64Value(messageBodyDictionary, "CallbackID");
        auto resultString = stringValue(messageBodyDictionary, "Result");
        m_testRunner->runUIScriptCallback(callbackID, toJS(resultString).get());
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "WorkQueueProcessedCallback")) {
        if (!topLoadingFrame() && !m_testRunner->shouldWaitUntilDone())
            InjectedBundle::page()->dump();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataDeletionForRegistrableDomainsFinished")) {
        m_testRunner->statisticsDidModifyDataRecordsCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "WebsiteDataScanForRegistrableDomainsFinished")) {
        m_testRunner->statisticsDidScanDataRecordsCallback();
        return;
    }
    
    if (WKStringIsEqualToUTF8CString(messageName, "DidGetApplicationManifest")) {
        m_testRunner->didGetApplicationManifest();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "PerformCustomMenuAction")) {
        m_testRunner->performCustomMenuAction();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "CallDidSetAppBoundDomains")) {
        m_testRunner->didSetAppBoundDomainsCallback();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "ForceImmediateCompletion")) {
        m_testRunner->forceImmediateCompletion();
        return;
    }

    if (WKStringIsEqualToUTF8CString(messageName, "ViewPortSnapshotTaken")) {
        ASSERT(messageBody);
        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
        m_testRunner->viewPortSnapshotTaken(static_cast<WKStringRef>(messageBody));
        return;
    }

    postPageMessage("Error", "Unknown");
}

void InjectedBundle::beginTesting(WKDictionaryRef settings, BegingTestingMode testingMode)
{
    m_state = Testing;

    m_dumpPixels = booleanValue(settings, "DumpPixels");
    m_timeout = Seconds::fromMilliseconds(uint64Value(settings, "Timeout"));
    m_dumpJSConsoleLogInStdErr = booleanValue(settings, "DumpJSConsoleLogInStdErr");

    m_pixelResult.clear();
    m_repaintRects.clear();

    m_testRunner = TestRunner::create();
    m_gcController = GCController::create();
    m_eventSendingController = EventSendingController::create();
    m_textInputController = TextInputController::create();
#if ENABLE(ACCESSIBILITY)
    m_accessibilityController = AccessibilityController::create();
#if ENABLE(ACCESSIBILITY_ISOLATED_TREE)
    m_accessibilityController->setIsolatedTreeMode(m_accessibilityIsolatedTreeMode);
#endif
#endif

#if PLATFORM(IOS_FAMILY)
    WKBundlePageSetUseTestingViewportConfiguration(page()->page(), !booleanValue(settings, "UseFlexibleViewport"));
#endif

#if PLATFORM(COCOA)
    WebCoreTestSupport::setAdditionalSupportedImageTypesForTesting(toWTFString(stringValue(settings, "additionalSupportedImageTypes")));
#endif

    m_testRunner->setUserStyleSheetEnabled(false);

    m_testRunner->setAcceptsEditing(true);
    m_testRunner->setTabKeyCyclesThroughElements(true);
    m_testRunner->clearTestRunnerCallbacks();

    if (m_timeout > 0_s)
        m_testRunner->setCustomTimeout(m_timeout);

    page()->prepare();

    if (testingMode != BegingTestingMode::New)
        return;

    WKBundlePageClearApplicationCache(page()->page());
    WKBundleResetOriginAccessAllowLists(m_bundle.get());
    clearResourceLoadStatistics();

    // [WK2] REGRESSION(r128623): It made layout tests extremely slow
    // https://bugs.webkit.org/show_bug.cgi?id=96862
    // WKBundleSetDatabaseQuota(m_bundle.get(), 5 * 1024 * 1024);
}

void InjectedBundle::done()
{
    m_state = Stopping;

    m_useWorkQueue = false;

    page()->stopLoading();
    setTopLoadingFrame(0);

#if ENABLE(ACCESSIBILITY)
    m_accessibilityController->resetToConsistentState();
#endif

    auto body = adoptWK(WKMutableDictionaryCreate());

    setValue(body, "PixelResultIsPending", m_pixelResultIsPending);
    if (!m_pixelResultIsPending)
        setValue(body, "PixelResult", m_pixelResult);
    setValue(body, "RepaintRects", m_repaintRects);
    setValue(body, "AudioResult", m_audioResult);

    WKBundlePagePostMessageIgnoringFullySynchronousMode(page()->page(), toWK("Done").get(), body.get());

    m_state = Idle;
}

void InjectedBundle::clearResourceLoadStatistics()
{
    WKBundleClearResourceLoadStatistics(m_bundle.get());
}

void InjectedBundle::dumpBackForwardListsForAllPages(StringBuilder& stringBuilder)
{
    size_t size = m_pages.size();
    for (size_t i = 0; i < size; ++i)
        stringBuilder.append(m_pages[i]->dumpHistory());
}

void InjectedBundle::dumpToStdErr(const String& output)
{
    if (m_state != Testing)
        return;
    if (output.isEmpty())
        return;
    // FIXME: Do we really have to convert to UTF-8 instead of using toWK?
    auto string = output.tryGetUtf8();
    postPageMessage("DumpToStdErr", string ? string->data() : "Out of memory\n");
}

void InjectedBundle::outputText(StringView output, IsFinalTestOutput isFinalTestOutput)
{
    if (m_state != Testing)
        return;
    if (output.isEmpty())
        return;
    // FIXME: Do we really have to convert to UTF-8 instead of using toWK?
    auto string = output.tryGetUtf8();
    // We use WKBundlePagePostMessageIgnoringFullySynchronousMode() instead of WKBundlePagePostMessage() to make sure that all text output
    // is done via asynchronous IPC, even if the connection is in fully synchronous mode due to a WKBundlePagePostSynchronousMessageForTesting()
    // call. Otherwise, messages logged via sync and async IPC may end up out of order and cause flakiness.
    auto messageName = isFinalTestOutput == IsFinalTestOutput::Yes ? toWK("FinalTextOutput") : toWK("TextOutput");
    WKBundlePagePostMessageIgnoringFullySynchronousMode(page()->page(), messageName.get(), toWK(string ? string->data() : "Out of memory\n").get());
}

void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
{
    postPageMessage("BeforeUnloadReturnValue", value);
}

void InjectedBundle::postAddChromeInputField()
{
    postPageMessage("AddChromeInputField");
}

void InjectedBundle::postRemoveChromeInputField()
{
    postPageMessage("RemoveChromeInputField");
}

void InjectedBundle::postSetTextInChromeInputField(const String& text)
{
    auto wkText = toWK(text);
    postPageMessage("SetTextInChromeInputField", wkText.get());
}

void InjectedBundle::postSelectChromeInputField()
{
    postPageMessage("SelectChromeInputField");
}

void InjectedBundle::postGetSelectedTextInChromeInputField()
{
    postPageMessage("GetSelectedTextInChromeInputField");
}

void InjectedBundle::postFocusWebView()
{
    postPageMessage("FocusWebView");
}

void InjectedBundle::postSetBackingScaleFactor(double backingScaleFactor)
{
    postPageMessage("SetBackingScaleFactor", adoptWK(WKDoubleCreate(backingScaleFactor)));
}

void InjectedBundle::postSetWindowIsKey(bool isKey)
{
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("SetWindowIsKey").get(), adoptWK(WKBooleanCreate(isKey)).get(), 0);
}

void InjectedBundle::postSetViewSize(double width, double height)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "width", width);
    setValue(body, "height", height);
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("SetViewSize").get(), body.get(), 0);
}

void InjectedBundle::postSimulateWebNotificationClick(WKDataRef notificationID)
{
    postPageMessage("SimulateWebNotificationClick", notificationID);
}

void InjectedBundle::postSimulateWebNotificationClickForServiceWorkerNotifications()
{
    postPageMessage("SimulateWebNotificationClickForServiceWorkerNotifications");
}

void InjectedBundle::postSetAddsVisitedLinks(bool addsVisitedLinks)
{
    postPageMessage("SetAddsVisitedLinks", adoptWK(WKBooleanCreate(addsVisitedLinks)));
}

void InjectedBundle::setGeolocationPermission(bool enabled)
{
    postPageMessage("SetGeolocationPermission", adoptWK(WKBooleanCreate(enabled)));
}

void InjectedBundle::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)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "latitude", latitude);
    setValue(body, "longitude", longitude);
    setValue(body, "accuracy", accuracy);
    setValue(body, "altitude", altitude);
    setValue(body, "altitudeAccuracy", altitudeAccuracy);
    setValue(body, "heading", heading);
    setValue(body, "speed", speed);
    setValue(body, "floorLevel", floorLevel);
    postPageMessage("SetMockGeolocationPosition", body);
}

void InjectedBundle::setMockGeolocationPositionUnavailableError(WKStringRef errorMessage)
{
    postPageMessage("SetMockGeolocationPositionUnavailableError", errorMessage);
}

bool InjectedBundle::isGeolocationProviderActive() const
{
    WKTypeRef result = nullptr;
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("IsGeolocationClientActive").get(), 0, &result);
    return booleanValue(adoptWK(result).get());
}

unsigned InjectedBundle::imageCountInGeneralPasteboard() const
{
    WKTypeRef result = nullptr;
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("ImageCountInGeneralPasteboard").get(), 0, &result);
    return uint64Value(adoptWK(result).get());
}

void InjectedBundle::setUserMediaPermission(bool enabled)
{
    postPageMessage("SetUserMediaPermission", adoptWK(WKBooleanCreate(enabled)));
}

void InjectedBundle::resetUserMediaPermission()
{
    postPageMessage("ResetUserMediaPermission");
}

void InjectedBundle::setUserMediaPersistentPermissionForOrigin(bool permission, WKStringRef origin, WKStringRef parentOrigin)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "permission", permission);
    setValue(body, "origin", origin);
    setValue(body, "parentOrigin", parentOrigin);
    postPageMessage("SetUserMediaPersistentPermissionForOrigin", body);
}

unsigned InjectedBundle::userMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin) const
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "origin", origin);
    setValue(body, "parentOrigin", parentOrigin);
    WKTypeRef result = nullptr;
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("UserMediaPermissionRequestCountForOrigin").get(), body.get(), &result);
    return uint64Value(adoptWK(result).get());
}

void InjectedBundle::resetUserMediaPermissionRequestCountForOrigin(WKStringRef origin, WKStringRef parentOrigin)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "origin", origin);
    setValue(body, "parentOrigin", parentOrigin);
    postPageMessage("ResetUserMediaPermissionRequestCountForOrigin", body);
}

void InjectedBundle::setCustomPolicyDelegate(bool enabled, bool permissive)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "enabled", enabled);
    setValue(body, "permissive", permissive);
    postPageMessage("SetCustomPolicyDelegate", body);
}

void InjectedBundle::setHidden(bool hidden)
{
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "hidden", hidden);
    postPageMessage("SetHidden", body);
}

void InjectedBundle::setCacheModel(int model)
{
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("SetCacheModel").get(), adoptWK(WKUInt64Create(model)).get(), nullptr);
}

bool InjectedBundle::shouldProcessWorkQueue() const
{
    if (!m_useWorkQueue)
        return false;

    WKTypeRef result = nullptr;
    WKBundlePagePostSynchronousMessageForTesting(page()->page(), toWK("IsWorkQueueEmpty").get(), 0, &result);

    // The IPC failed. This happens when swapping processes on navigation because the WebPageProxy unregisters itself
    // as a MessageReceiver from the old WebProcessProxy and register itself with the new WebProcessProxy instead.
    if (!result)
        return false;

    auto isEmpty = booleanValue(adoptWK(result).get());
    return !isEmpty;
}

void InjectedBundle::processWorkQueue()
{
    postPageMessage("ProcessWorkQueue");
}

void InjectedBundle::queueBackNavigation(unsigned howFarBackward)
{
    m_useWorkQueue = true;
    postPageMessage("QueueBackNavigation", adoptWK(WKUInt64Create(howFarBackward)));
}

void InjectedBundle::queueForwardNavigation(unsigned howFarForward)
{
    m_useWorkQueue = true;
    postPageMessage("QueueForwardNavigation", adoptWK(WKUInt64Create(howFarForward)));
}

void InjectedBundle::queueLoad(WKStringRef url, WKStringRef target, bool shouldOpenExternalURLs)
{
    m_useWorkQueue = true;
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "url", url);
    setValue(body, "target", target);
    setValue(body, "shouldOpenExternalURLs", shouldOpenExternalURLs);
    postPageMessage("QueueLoad", body);
}

void InjectedBundle::queueLoadHTMLString(WKStringRef content, WKStringRef baseURL, WKStringRef unreachableURL)
{
    m_useWorkQueue = true;
    auto body = adoptWK(WKMutableDictionaryCreate());
    setValue(body, "content", content);
    if (baseURL)
        setValue(body, "baseURL", baseURL);
    if (unreachableURL)
        setValue(body, "unreachableURL", unreachableURL);
    postPageMessage("QueueLoadHTMLString", body);
}

void InjectedBundle::queueReload()
{
    m_useWorkQueue = true;
    postPageMessage("QueueReload");
}

void InjectedBundle::queueLoadingScript(WKStringRef script)
{
    m_useWorkQueue = true;
    postPageMessage("QueueLoadingScript", script);
}

void InjectedBundle::queueNonLoadingScript(WKStringRef script)
{
    m_useWorkQueue = true;
    postPageMessage("QueueNonLoadingScript", script);
}

bool InjectedBundle::isAllowedHost(WKStringRef host)
{
    if (m_allowedHosts.isEmpty())
        return false;
    return m_allowedHosts.contains(toWTFString(host));
}

void InjectedBundle::setAllowsAnySSLCertificate(bool allowsAnySSLCertificate)
{
    WebCoreTestSupport::setAllowsAnySSLCertificate(allowsAnySSLCertificate);
}

bool InjectedBundle::statisticsNotifyObserver()
{
    return WKBundleResourceLoadStatisticsNotifyObserver(m_bundle.get());
}

void InjectedBundle::textDidChangeInTextField()
{
    m_testRunner->textDidChangeInTextFieldCallback();
}

void InjectedBundle::textFieldDidBeginEditing()
{
    m_testRunner->textFieldDidBeginEditingCallback();
}

void InjectedBundle::textFieldDidEndEditing()
{
    m_testRunner->textFieldDidEndEditingCallback();
}

void postMessage(const char* name)
{
    postMessage(name, WKRetainPtr<WKTypeRef> { });
}

void postMessage(const char* name, bool value)
{
    postMessage(name, adoptWK(WKBooleanCreate(value)));
}

void postMessage(const char* name, unsigned value)
{
    postMessage(name, adoptWK(WKUInt64Create(value)));
}

void postMessage(const char* name, JSStringRef value)
{
    postMessage(name, toWK(value));
}

void postSynchronousMessage(const char* name)
{
    postSynchronousMessage(name, WKRetainPtr<WKTypeRef> { });
}

void postSynchronousMessage(const char* name, bool value)
{
    postSynchronousMessage(name, adoptWK(WKBooleanCreate(value)));
}

void postSynchronousMessage(const char* name, uint64_t value)
{
    postSynchronousMessage(name, adoptWK(WKUInt64Create(value)));
}

void postSynchronousMessage(const char* name, unsigned value)
{
    uint64_t promotedValue = value;
    postSynchronousMessage(name, promotedValue);
}

void postSynchronousMessage(const char* name, double value)
{
    postSynchronousMessage(name, adoptWK(WKDoubleCreate(value)));
}

void postPageMessage(const char* name)
{
    postPageMessage(name, WKRetainPtr<WKTypeRef> { });
}

void postPageMessage(const char* name, bool value)
{
    postPageMessage(name, adoptWK(WKBooleanCreate(value)));
}

void postPageMessage(const char* name, const char* value)
{
    postPageMessage(name, toWK(value));
}

void postPageMessage(const char* name, WKStringRef value)
{
    if (auto page = InjectedBundle::singleton().pageRef())
        WKBundlePagePostMessage(page, toWK(name).get(), value);
}

void postPageMessage(const char* name, WKDataRef value)
{
    if (auto page = InjectedBundle::singleton().pageRef())
        WKBundlePagePostMessage(page, toWK(name).get(), value);
}

void postSynchronousPageMessage(const char* name)
{
    postSynchronousPageMessage(name, WKRetainPtr<WKTypeRef> { });
}

void postSynchronousPageMessage(const char* name, bool value)
{
    postSynchronousPageMessage(name, adoptWK(WKBooleanCreate(value)));
}

} // namespace WTR
