/*
 * Copyright (C) 2005-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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "DumpRenderTree.h"

#include "DefaultPolicyDelegate.h"
#include "EditingDelegate.h"
#include "FrameLoadDelegate.h"
#include "GCController.h"
#include "HistoryDelegate.h"
#include "JavaScriptThreading.h"
#include "PixelDumpSupport.h"
#include "PolicyDelegate.h"
#include "ResourceLoadDelegate.h"
#include "TestCommand.h"
#include "TestFeatures.h"
#include "TestOptions.h"
#include "TestRunner.h"
#include "UIDelegate.h"
#include "WebCoreTestSupport.h"
#include "WorkQueueItem.h"
#include "WorkQueue.h"

#include <CoreFoundation/CoreFoundation.h>
#include <JavaScriptCore/InitializeThreading.h>
#include <JavaScriptCore/Options.h>
#include <JavaScriptCore/TestRunnerUtils.h>
#include <WebKitLegacy/WebKit.h>
#include <WebKitLegacy/WebKitCOMAPI.h>
#include <comutil.h>
#include <cstdio>
#include <cstring>
#include <fcntl.h>
#include <fstream>
#include <io.h>
#include <math.h>
#include <shlobj.h>
#include <shlwapi.h>
#include <tchar.h>
#include <windows.h>
#include <wtf/FileSystem.h>
#include <wtf/HashSet.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/RetainPtr.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringConcatenateNumbers.h>
#include <wtf/text/StringHash.h>

#if USE(CFURLCONNECTION)
#include <CFNetwork/CFHTTPCookiesPriv.h>
#include <CFNetwork/CFURLCachePriv.h>
#endif

using namespace std;

#ifdef DEBUG_ALL
const _bstr_t TestPluginDir = L"TestNetscapePlugin_Debug";
#else
const _bstr_t TestPluginDir = L"TestNetscapePlugin";
#endif

static LPCWSTR fontsEnvironmentVariable = L"WEBKIT_TESTFONTS";
static LPCWSTR dumpRenderTreeTemp = L"DUMPRENDERTREE_TEMP";
#define USE_MAC_FONTS

static CFStringRef WebDatabaseDirectoryDefaultsKey = CFSTR("WebDatabaseDirectory");
static CFStringRef WebKitLocalCacheDefaultsKey = CFSTR("WebKitLocalCache");
static CFStringRef WebStorageDirectoryDefaultsKey = CFSTR("WebKitLocalStorageDatabasePathPreferenceKey");

const LPCWSTR kDumpRenderTreeClassName = L"DumpRenderTreeWindow";

static bool dumpPixelsForAllTests = false;
static bool dumpPixelsForCurrentTest = false;
static bool threaded = false;
static bool dumpTree = true;
static bool forceComplexText = false;
static bool dumpAllPixels;
static bool useAcceleratedDrawing = true; // Not used
// FIXME: gcBetweenTests should initially be false, but we currently set it to true, to make sure
// deallocations are not performed in one of the following tests which might cause flakiness.
static bool gcBetweenTests = true; 
static bool printSeparators = false;
static bool leakChecking = false;
static bool showWebView = false;
static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;

volatile bool done;
// This is the topmost frame that is loading, during a given load, or nil when no load is 
// in progress.  Usually this is the same as the main frame, but not always.  In the case
// where a frameset is loaded, and then new content is loaded into one of the child frames,
// that child frame is the "topmost frame that is loading".
IWebFrame* topLoadingFrame;     // !nil iff a load is in progress
static COMPtr<IWebHistoryItem> prevTestBFItem;  // current b/f item at the end of the previous test
PolicyDelegate* policyDelegate; 
COMPtr<FrameLoadDelegate> sharedFrameLoadDelegate;
COMPtr<UIDelegate> sharedUIDelegate;
COMPtr<EditingDelegate> sharedEditingDelegate;
COMPtr<ResourceLoadDelegate> resourceLoadDelegate;
COMPtr<HistoryDelegate> sharedHistoryDelegate;

IWebFrame* frame;
HWND webViewWindow;

RefPtr<TestRunner> gTestRunner;

UINT_PTR waitToDumpWatchdog = 0;
bool useTimeoutWatchdog = true;

void setPersistentUserStyleSheetLocation(CFStringRef url)
{
    persistentUserStyleSheetLocation = url;
}

bool setAlwaysAcceptCookies(bool)
{
    // FIXME: Implement this by making the Windows port use the testing network storage session and
    // modify its cookie storage policy.
    return false;
}

static RetainPtr<CFStringRef> substringFromIndex(CFStringRef string, CFIndex index)
{
    return adoptCF(CFStringCreateWithSubstring(kCFAllocatorDefault, string, CFRangeMake(index, CFStringGetLength(string) - index)));
}

static wstring lastPathComponentAsWString(CFURLRef url)
{
    RetainPtr<CFStringRef> lastPathComponent = adoptCF(CFURLCopyLastPathComponent(url));
    return cfStringRefToWString(lastPathComponent.get());
}

wstring urlSuitableForTestResult(const wstring& urlString)
{
    if (urlString.empty())
        return urlString;

    RetainPtr<CFURLRef> url = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlString.c_str()), urlString.length() * sizeof(wstring::value_type), kCFStringEncodingUTF16, 0));

    RetainPtr<CFStringRef> scheme = adoptCF(CFURLCopyScheme(url.get()));
    if (scheme && CFStringCompare(scheme.get(), CFSTR("file"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)
        return urlString;

    COMPtr<IWebDataSource> dataSource;
    if (FAILED(frame->dataSource(&dataSource))) {
        if (FAILED(frame->provisionalDataSource(&dataSource)))
            return lastPathComponentAsWString(url.get());
    }

    COMPtr<IWebMutableURLRequest> request;
    if (FAILED(dataSource->request(&request)))
        return lastPathComponentAsWString(url.get());

    _bstr_t requestURLString;
    if (FAILED(request->URL(requestURLString.GetAddress())))
        return lastPathComponentAsWString(url.get());

    RetainPtr<CFURLRef> requestURL = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(requestURLString.GetBSTR()), requestURLString.length() * sizeof(OLECHAR), kCFStringEncodingUTF16, 0));
    RetainPtr<CFURLRef> baseURL = adoptCF(CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, requestURL.get()));

    RetainPtr<CFStringRef> basePath = adoptCF(CFURLCopyPath(baseURL.get()));
    RetainPtr<CFStringRef> path = adoptCF(CFURLCopyPath(url.get()));

    if (basePath.get() && CFStringHasPrefix(path.get(), basePath.get()))
        return cfStringRefToWString(substringFromIndex(path.get(), CFStringGetLength(basePath.get())).get());

    return lastPathComponentAsWString(url.get());
}

wstring lastPathComponent(const wstring& urlString)
{
    if (urlString.empty())
        return urlString;

    RetainPtr<CFURLRef> url = adoptCF(CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlString.c_str()), urlString.length() * sizeof(wstring::value_type), kCFStringEncodingUTF16, 0));
    RetainPtr<CFStringRef> lastPathComponent = adoptCF(CFURLCopyLastPathComponent(url.get()));

    return cfStringRefToWString(lastPathComponent.get());
}

static string toUTF8(const wchar_t* wideString, size_t length)
{
    int result = WideCharToMultiByte(CP_UTF8, 0, wideString, length + 1, 0, 0, 0, 0);
    Vector<char> utf8Vector(result);
    result = WideCharToMultiByte(CP_UTF8, 0, wideString, length + 1, utf8Vector.data(), result, 0, 0);
    if (!result)
        return string();

    return string(utf8Vector.data(), utf8Vector.size() - 1);
}

#if USE(CF)
static String libraryPathForDumpRenderTree()
{
    DWORD size = ::GetEnvironmentVariable(dumpRenderTreeTemp, 0, 0);
    Vector<TCHAR> buffer(size);
    if (::GetEnvironmentVariable(dumpRenderTreeTemp, buffer.data(), buffer.size())) {
        wstring path = buffer.data();
        if (!path.empty() && (path[path.length() - 1] != L'\\'))
            path.append(L"\\");
        return String (path.data(), path.length());
    }

    return FileSystem::localUserSpecificStorageDirectory();
}
#endif

std::string toUTF8(BSTR bstr)
{
    return toUTF8(bstr, SysStringLen(bstr));
}

std::string toUTF8(const wstring& wideString)
{
    return toUTF8(wideString.c_str(), wideString.length());
}

static std::string toUTF8(CFStringRef input)
{
    CFIndex maximumURLLengthAsUTF8 = CFStringGetMaximumSizeForEncoding(CFStringGetLength(input), kCFStringEncodingUTF8) + 1;
    Vector<char> buffer(maximumURLLengthAsUTF8 + 1, 0);
    CFStringGetCString(input, buffer.data(), maximumURLLengthAsUTF8, kCFStringEncodingUTF8);

    return buffer.data();
}

wstring cfStringRefToWString(CFStringRef cfStr)
{
    Vector<wchar_t> v(CFStringGetLength(cfStr));
    CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), (UniChar *)v.data());

    return wstring(v.data(), v.size());
}

static _bstr_t toBSTR(const std::string& input)
{
    return input.c_str();
}

static _bstr_t toBSTR(CFStringRef input)
{
    size_t stringLength = CFStringGetLength(input);
    Vector<UniChar> buffer(stringLength + 1, 0);
    CFStringGetCharacters(input, CFRangeMake(0, stringLength), buffer.data());
    return reinterpret_cast<wchar_t*>(buffer.data());
}

static LRESULT CALLBACK DumpRenderTreeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
        case WM_DESTROY:
            for (long i = openWindows().size() - 1; i >= 0; --i) {
                if (openWindows()[i] == hWnd) {
                    openWindows().remove(i);
                    windowToWebViewMap().remove(hWnd);
                    break;
                }
            }
            return 0;
            break;
        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
}

static const wstring& exePath()
{
    static wstring path;
    static bool initialized;

    if (initialized)
        return path;
    initialized = true;

    TCHAR buffer[MAX_PATH];
    GetModuleFileName(GetModuleHandle(0), buffer, ARRAYSIZE(buffer));
    path = buffer;
    int lastSlash = path.rfind('\\');
    if (lastSlash != -1 && lastSlash + 1 < path.length())
        path = path.substr(0, lastSlash + 1);

    return path;
}

static const wstring& fontsPath()
{
    static wstring path;
    static bool initialized;

    if (initialized)
        return path;
    initialized = true;

    DWORD size = GetEnvironmentVariable(fontsEnvironmentVariable, 0, 0);
    Vector<TCHAR> buffer(size);
    if (GetEnvironmentVariable(fontsEnvironmentVariable, buffer.data(), buffer.size())) {
        path = buffer.data();
        if (path[path.length() - 1] != '\\')
            path.append(L"\\");
        return path;
    }

    path = exePath() + TEXT("DumpRenderTree.resources\\");
    return path;
}

#ifdef DEBUG_ALL
#define WEBKITDLL TEXT("WebKit_debug.dll")
#else
#define WEBKITDLL TEXT("WebKit.dll")
#endif

static void initialize()
{
    JSC::Config::configureForTesting();

    if (HMODULE webKitModule = LoadLibrary(WEBKITDLL))
        if (FARPROC dllRegisterServer = GetProcAddress(webKitModule, "DllRegisterServer"))
            dllRegisterServer();

    // Init COM
    OleInitialize(nullptr);

    static LPCTSTR fontsToInstall[] = {
        TEXT("AHEM____.ttf"),
        TEXT("Apple Chancery.ttf"),
        TEXT("Courier Bold.ttf"),
        TEXT("Courier.ttf"),
        TEXT("Helvetica Bold Oblique.ttf"),
        TEXT("Helvetica Bold.ttf"),
        TEXT("Helvetica Oblique.ttf"),
        TEXT("Helvetica.ttf"),
        TEXT("Helvetica Neue Bold Italic.ttf"),
        TEXT("Helvetica Neue Bold.ttf"),
        TEXT("Helvetica Neue Condensed Black.ttf"),
        TEXT("Helvetica Neue Condensed Bold.ttf"),
        TEXT("Helvetica Neue Italic.ttf"),
        TEXT("Helvetica Neue Light Italic.ttf"),
        TEXT("Helvetica Neue Light.ttf"),
        TEXT("Helvetica Neue UltraLight Italic.ttf"),
        TEXT("Helvetica Neue UltraLight.ttf"),
        TEXT("Helvetica Neue.ttf"),
        TEXT("Lucida Grande.ttf"),
        TEXT("Lucida Grande Bold.ttf"),
        TEXT("Monaco.ttf"),
        TEXT("Papyrus.ttf"),
        TEXT("Times Bold Italic.ttf"),
        TEXT("Times Bold.ttf"),
        TEXT("Times Italic.ttf"),
        TEXT("Times Roman.ttf"),
        TEXT("WebKit Layout Tests 2.ttf"),
        TEXT("WebKit Layout Tests.ttf"),
        TEXT("WebKitWeightWatcher100.ttf"),
        TEXT("WebKitWeightWatcher200.ttf"),
        TEXT("WebKitWeightWatcher300.ttf"),
        TEXT("WebKitWeightWatcher400.ttf"),
        TEXT("WebKitWeightWatcher500.ttf"),
        TEXT("WebKitWeightWatcher600.ttf"),
        TEXT("WebKitWeightWatcher700.ttf"),
        TEXT("WebKitWeightWatcher800.ttf"),
        TEXT("WebKitWeightWatcher900.ttf")
    };

    wstring resourcesPath = fontsPath();

    COMPtr<IWebTextRenderer> textRenderer;
    if (SUCCEEDED(WebKitCreateInstance(CLSID_WebTextRenderer, 0, IID_IWebTextRenderer, (void**)&textRenderer)))
        for (int i = 0; i < ARRAYSIZE(fontsToInstall); ++i)
            textRenderer->registerPrivateFont(wstring(resourcesPath + fontsToInstall[i]).c_str());

    // Register a host window
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style         = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc   = DumpRenderTreeWndProc;
    wcex.cbClsExtra    = 0;
    wcex.cbWndExtra    = 0;
    wcex.hInstance     = GetModuleHandle(0);
    wcex.hIcon         = 0;
    wcex.hCursor       = LoadCursor(0, IDC_ARROW);
    wcex.hbrBackground = 0;
    wcex.lpszMenuName  = 0;
    wcex.lpszClassName = kDumpRenderTreeClassName;
    wcex.hIconSm       = 0;

    RegisterClassEx(&wcex);
}

void displayWebView()
{
    ::InvalidateRect(webViewWindow, 0, TRUE);
    ::SendMessage(webViewWindow, WM_PAINT, 0, 0);
}

void dumpFrameScrollPosition(IWebFrame* frame)
{
    if (!frame)
        return;

    COMPtr<IWebFramePrivate> framePrivate;
    if (FAILED(frame->QueryInterface(&framePrivate)))
        return;

    SIZE scrollPosition;
    if (FAILED(framePrivate->scrollOffset(&scrollPosition)))
        return;

    if (abs(scrollPosition.cx) > 0.00000001 || abs(scrollPosition.cy) > 0.00000001) {
        COMPtr<IWebFrame> parent;
        if (FAILED(frame->parentFrame(&parent)))
            return;
        if (parent) {
            _bstr_t name;
            if (FAILED(frame->name(&name.GetBSTR())))
                return;
            fprintf(testResult, "frame '%S' ", static_cast<wchar_t*>(name));
        }
        fprintf(testResult, "scrolled to %.f,%.f\n", (double)scrollPosition.cx, (double)scrollPosition.cy);
    }

    if (::gTestRunner->dumpChildFrameScrollPositions()) {
        COMPtr<IEnumVARIANT> enumKids;
        if (FAILED(frame->childFrames(&enumKids)))
            return;
        _variant_t var;
        while (enumKids->Next(1, &var.GetVARIANT(), nullptr) == S_OK) {
            ASSERT(V_VT(&var) == VT_UNKNOWN);
            COMPtr<IWebFrame> framePtr;
            V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
            dumpFrameScrollPosition(framePtr.get());
        }
    }
}

static wstring dumpFramesAsText(IWebFrame* frame)
{
    if (!frame)
        return L"";

    COMPtr<IDOMDocument> document;
    if (FAILED(frame->DOMDocument(&document)))
        return L"";

    COMPtr<IDOMElement> documentElement;
    if (FAILED(document->documentElement(&documentElement)))
        return L"";

    wstring result;

    // Add header for all but the main frame.
    COMPtr<IWebFrame> parent;
    if (FAILED(frame->parentFrame(&parent)))
        return L"";

    if (parent) {
        _bstr_t name;
        if (FAILED(frame->name(&name.GetBSTR())))
            return L"";

        result.append(L"\n--------\nFrame: '");
        result.append(static_cast<wchar_t*>(name), name.length());
        result.append(L"'\n--------\n");
    }

    _bstr_t innerText;
    COMPtr<IDOMElementPrivate> docPrivate;
    if (SUCCEEDED(documentElement->QueryInterface(&docPrivate)))
        docPrivate->innerText(&innerText.GetBSTR());

    result.append(static_cast<wchar_t*>(innerText), innerText.length());
    result.append(L"\n");

    if (::gTestRunner->dumpChildFramesAsText()) {
        COMPtr<IEnumVARIANT> enumKids;
        if (FAILED(frame->childFrames(&enumKids)))
            return L"";

        _variant_t var;
        while (enumKids->Next(1, &var.GetVARIANT(), nullptr) == S_OK) {
            ASSERT(V_VT(&var) == VT_UNKNOWN);
            COMPtr<IWebFrame> framePtr;
            V_UNKNOWN(&var)->QueryInterface(IID_IWebFrame, (void**)&framePtr);
            result.append(dumpFramesAsText(framePtr.get()));
        }
    }

    // To keep things tidy, strip all trailing spaces: they are not a meaningful part of dumpAsText test output.
    std::wstring::size_type spacePosition;
    while ((spacePosition = result.find(L" \n")) != std::wstring::npos)
        result.erase(spacePosition, 1);
    while (!result.empty() && result.back() == ' ')
        result.pop_back();

    return result;
}

static int compareHistoryItems(const void* item1, const void* item2)
{
    COMPtr<IWebHistoryItemPrivate> itemA;
    if (FAILED((*(COMPtr<IUnknown>*)item1)->QueryInterface(&itemA)))
        return 0;

    COMPtr<IWebHistoryItemPrivate> itemB;
    if (FAILED((*(COMPtr<IUnknown>*)item2)->QueryInterface(&itemB)))
        return 0;

    _bstr_t targetA;
    if (FAILED(itemA->target(&targetA.GetBSTR())))
        return 0;

    _bstr_t targetB;
    if (FAILED(itemB->target(&targetB.GetBSTR())))
        return 0;

    return wcsicmp(static_cast<wchar_t*>(targetA), static_cast<wchar_t*>(targetB));
}

static void dumpHistoryItem(IWebHistoryItem* item, int indent, bool current)
{
    ASSERT(item);

    int start = 0;
    if (current) {
        fprintf(testResult, "curr->");
        start = 6;
    }
    for (int i = start; i < indent; i++)
        fputc(' ', testResult);

    _bstr_t url;
    if (FAILED(item->URLString(&url.GetBSTR())))
        return;

    if (wcsstr(static_cast<wchar_t*>(url), L"file:/") == static_cast<wchar_t*>(url)) {
        auto layoutTestsStringUnixPath = L"/LayoutTests/";
        auto layoutTestsStringDOSPath = L"\\LayoutTests\\";
        
        wchar_t* result = wcsstr(static_cast<wchar_t*>(url), layoutTestsStringUnixPath);
        if (!result)
            result = wcsstr(static_cast<wchar_t*>(url), layoutTestsStringDOSPath);
        if (!result)
            return;

        wchar_t* start = result + wcslen(layoutTestsStringUnixPath);

        url = _bstr_t(L"(file test):") + _bstr_t(start);
    }

    fprintf(testResult, "%S", static_cast<wchar_t*>(url));

    COMPtr<IWebHistoryItemPrivate> itemPrivate;
    if (FAILED(item->QueryInterface(&itemPrivate)))
        return;

    _bstr_t target;
    if (FAILED(itemPrivate->target(&target.GetBSTR())))
        return;
    if (target.length())
        fprintf(testResult, " (in frame \"%S\")", static_cast<wchar_t*>(target));
    BOOL isTargetItem = FALSE;
    if (FAILED(itemPrivate->isTargetItem(&isTargetItem)))
        return;
    if (isTargetItem)
        fprintf(testResult, "  **nav target**");
    fputc('\n', testResult);

    unsigned kidsCount;
    SAFEARRAY* arrayPtr;
    if (FAILED(itemPrivate->children(&kidsCount, &arrayPtr)) || !kidsCount)
        return;

    std::unique_ptr<SAFEARRAY, decltype(&::SafeArrayDestroy)> array(arrayPtr, ::SafeArrayDestroy);

    Vector<COMPtr<IUnknown> > kidsVector;

    LONG lowerBound;
    if (FAILED(::SafeArrayGetLBound(array.get(), 1, &lowerBound)))
        return;

    LONG upperBound;
    if (FAILED(::SafeArrayGetUBound(array.get(), 1, &upperBound)))
        return;

    LONG length = upperBound - lowerBound + 1;
    if (!length)
        return;
    ASSERT(length == kidsCount);

    IUnknown** safeArrayData;
    if (FAILED(::SafeArrayAccessData(array.get(), (void**)&safeArrayData)))
        return;

    for (int i = 0; i < length; ++i)
        kidsVector.append(safeArrayData[i]);
    ::SafeArrayUnaccessData(array.get());

    // must sort to eliminate arbitrary result ordering which defeats reproducible testing
    qsort(kidsVector.data(), kidsCount, sizeof(kidsVector[0]), compareHistoryItems);

    for (unsigned i = 0; i < kidsCount; ++i) {
        COMPtr<IWebHistoryItem> item;
        kidsVector[i]->QueryInterface(&item);
        dumpHistoryItem(item.get(), indent + 4, false);
    }
}

static void dumpBackForwardList(IWebView* webView)
{
    ASSERT(webView);

    fprintf(testResult, "\n============== Back Forward List ==============\n");

    COMPtr<IWebBackForwardList> bfList;
    if (FAILED(webView->backForwardList(&bfList)))
        return;

    // Print out all items in the list after prevTestBFItem, which was from the previous test
    // Gather items from the end of the list, the print them out from oldest to newest

    Vector<COMPtr<IUnknown> > itemsToPrint;

    int forwardListCount;
    if (FAILED(bfList->forwardListCount(&forwardListCount)))
        return;

    for (int i = forwardListCount; i > 0; --i) {
        COMPtr<IWebHistoryItem> item;
        if (FAILED(bfList->itemAtIndex(i, &item)))
            return;
        // something is wrong if the item from the last test is in the forward part of the b/f list
        ASSERT(item != prevTestBFItem);
        COMPtr<IUnknown> itemUnknown;
        item->QueryInterface(&itemUnknown);
        itemsToPrint.append(itemUnknown);
    }

    COMPtr<IWebHistoryItem> currentItem;
    if (FAILED(bfList->currentItem(&currentItem)))
        return;

    ASSERT(currentItem != prevTestBFItem);
    COMPtr<IUnknown> currentItemUnknown;
    currentItem->QueryInterface(&currentItemUnknown);
    itemsToPrint.append(currentItemUnknown);
    int currentItemIndex = itemsToPrint.size() - 1;

    int backListCount;
    if (FAILED(bfList->backListCount(&backListCount)))
        return;

    for (int i = -1; i >= -backListCount; --i) {
        COMPtr<IWebHistoryItem> item;
        if (FAILED(bfList->itemAtIndex(i, &item)))
            return;
        if (item == prevTestBFItem)
            break;
        COMPtr<IUnknown> itemUnknown;
        item->QueryInterface(&itemUnknown);
        itemsToPrint.append(itemUnknown);
    }

    for (int i = itemsToPrint.size() - 1; i >= 0; --i) {
        COMPtr<IWebHistoryItem> historyItemToPrint;
        itemsToPrint[i]->QueryInterface(&historyItemToPrint);
        dumpHistoryItem(historyItemToPrint.get(), 8, i == currentItemIndex);
    }

    fprintf(testResult, "===============================================\n");
}

static void dumpBackForwardListForAllWindows()
{
    unsigned count = openWindows().size();
    for (unsigned i = 0; i < count; i++) {
        HWND window = openWindows()[i];
        IWebView* webView = windowToWebViewMap().get(window);
        dumpBackForwardList(webView);
    }
}

static void invalidateAnyPreviousWaitToDumpWatchdog()
{
    if (!waitToDumpWatchdog)
        return;

    KillTimer(0, waitToDumpWatchdog);
    waitToDumpWatchdog = 0;
}

void dump()
{
    if (done) {
        fprintf(stderr, "dump() has already been called!\n");
        return;
    }

    ::InvalidateRect(webViewWindow, 0, TRUE);
    ::SendMessage(webViewWindow, WM_PAINT, 0, 0);

    invalidateAnyPreviousWaitToDumpWatchdog();
    ASSERT(!::gTestRunner->hasPendingWebNotificationClick());

    if (dumpTree) {
        _bstr_t resultString;

        COMPtr<IWebDataSource> dataSource;
        if (SUCCEEDED(frame->dataSource(&dataSource))) {
            COMPtr<IWebURLResponse> response;
            if (SUCCEEDED(dataSource->response(&response)) && response) {
                _bstr_t mimeType;
                if (SUCCEEDED(response->MIMEType(&mimeType.GetBSTR())) && !_tcscmp(static_cast<TCHAR*>(mimeType), TEXT("text/plain"))) {
                    ::gTestRunner->setDumpAsText(true);
                    ::gTestRunner->setGeneratePixelResults(false);
                }
            }
        }

        if (::gTestRunner->dumpAsText()) {
            resultString = dumpFramesAsText(frame).data();
        } else {
            COMPtr<IWebFramePrivate> framePrivate;
            if (FAILED(frame->QueryInterface(&framePrivate)))
                goto fail;

            if (::gTestRunner->isPrinting())
                framePrivate->renderTreeAsExternalRepresentationForPrinting(&resultString.GetBSTR());
            else
                framePrivate->renderTreeAsExternalRepresentation(::gTestRunner->renderTreeDumpOptions(), &resultString.GetBSTR());
        }

        if (resultString.length()) {
            unsigned stringLength = resultString.length();
            int bufferSize = ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, 0, 0, 0, 0);
            char* buffer = (char*)malloc(bufferSize + 1);
            ::WideCharToMultiByte(CP_UTF8, 0, resultString, stringLength, buffer, bufferSize + 1, 0, 0);
            fwrite(buffer, 1, bufferSize, testResult);
            free(buffer);

            if (!::gTestRunner->dumpAsText() && !::gTestRunner->dumpDOMAsWebArchive() && !::gTestRunner->dumpSourceAsWebArchive() && !::gTestRunner->dumpAsAudio())
                dumpFrameScrollPosition(frame);

            if (::gTestRunner->dumpBackForwardList())
                dumpBackForwardListForAllWindows();
        } else
            fprintf(testResult, "ERROR: nil result from %s\n", ::gTestRunner->dumpAsText() ? "IDOMElement::innerText" : "IFrameViewPrivate::renderTreeAsExternalRepresentation");

        if (printSeparators)
            fputs("#EOF\n", testResult); // terminate the content block
    }

    if (dumpPixelsForCurrentTest && ::gTestRunner->generatePixelResults()) {
        // FIXME: when isPrinting is set, dump the image with page separators.
        dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash());
    }

    fputs("#EOF\n", testResult); // terminate the (possibly empty) pixels block
    fflush(testResult);

fail:
    // This will exit from our message loop.
    done = true;
}

static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
{
    return strstr(pathOrURL, "/loading/") || strstr(pathOrURL, "\\loading\\");
}

static bool shouldLogHistoryDelegates(const char* pathOrURL)
{
    return strstr(pathOrURL, "/globalhistory/") || strstr(pathOrURL, "\\globalhistory\\");
}

static bool shouldDumpAsText(const char* pathOrURL)
{
    return strstr(pathOrURL, "/dumpAsText/") || strstr(pathOrURL, "\\dumpAsText\\");
}

static void enableExperimentalFeatures(IWebPreferences* preferences)
{
    COMPtr<IWebPreferencesPrivate7> prefsPrivate { Query, preferences };

    prefsPrivate->setFetchAPIKeepAliveEnabled(TRUE);
    // FIXME: CSSGridLayout
    // FIXME: SpringTimingFunction
    // FIXME: Gamepads
    prefsPrivate->setLinkPreloadEnabled(TRUE);
    prefsPrivate->setMediaPreloadingEnabled(TRUE);
    // FIXME: ModernMediaControls
    // FIXME: InputEvents
    // FIXME: SubtleCrypto
    prefsPrivate->setVisualViewportAPIEnabled(TRUE);
    prefsPrivate->setCSSOMViewScrollingAPIEnabled(TRUE);
    prefsPrivate->setResizeObserverEnabled(TRUE);
    prefsPrivate->setWebAnimationsCompositeOperationsEnabled(TRUE);
    prefsPrivate->setWebAnimationsMutableTimelinesEnabled(TRUE);
    prefsPrivate->setCSSCustomPropertiesAndValuesEnabled(TRUE);
    prefsPrivate->setServerTimingEnabled(TRUE);
    prefsPrivate->setAspectRatioOfImgFromWidthAndHeightEnabled(TRUE);
    // FIXME: WebGL2
    // FIXME: WebRTC
    prefsPrivate->setCSSOMViewSmoothScrollingEnabled(TRUE);
}

static void resetWebPreferencesToConsistentValues(IWebPreferences* preferences)
{
    ASSERT(preferences);

    preferences->setAutosaves(FALSE);

    COMPtr<IWebPreferencesPrivate8> prefsPrivate(Query, preferences);
    ASSERT(prefsPrivate);

    prefsPrivate->resetForTesting();

    enableExperimentalFeatures(preferences);

    prefsPrivate->setFullScreenEnabled(TRUE);

#ifdef USE_MAC_FONTS
    static _bstr_t standardFamily(TEXT("Times"));
    static _bstr_t fixedFamily(TEXT("Courier"));
    static _bstr_t sansSerifFamily(TEXT("Helvetica"));
    static _bstr_t cursiveFamily(TEXT("Apple Chancery"));
    static _bstr_t fantasyFamily(TEXT("Papyrus"));
    static _bstr_t pictographFamily(TEXT("Apple Color Emoji"));
#else
    static _bstr_t standardFamily(TEXT("Times New Roman"));
    static _bstr_t fixedFamily(TEXT("Courier New"));
    static _bstr_t sansSerifFamily(TEXT("Arial"));
    static _bstr_t cursiveFamily(TEXT("Comic Sans MS")); // Not actually cursive, but it's what IE and Firefox use.
    static _bstr_t fantasyFamily(TEXT("Times New Roman"));
    static _bstr_t pictographFamily(TEXT("Segoe UI Symbol"));
#endif

    prefsPrivate->setAllowTopNavigationToDataURLs(TRUE);
    prefsPrivate->setModernUnprefixedWebAudioEnabled(TRUE);
    prefsPrivate->setAllowUniversalAccessFromFileURLs(TRUE);
    prefsPrivate->setAllowFileAccessFromFileURLs(TRUE);
    preferences->setStandardFontFamily(standardFamily);
    preferences->setFixedFontFamily(fixedFamily);
    preferences->setSerifFontFamily(standardFamily);
    preferences->setSansSerifFontFamily(sansSerifFamily);
    preferences->setCursiveFontFamily(cursiveFamily);
    preferences->setFantasyFontFamily(fantasyFamily);
    preferences->setPictographFontFamily(pictographFamily);
    preferences->setDefaultFontSize(16);
    preferences->setDefaultFixedFontSize(13);
    preferences->setMinimumFontSize(0);
    preferences->setDefaultTextEncodingName(_bstr_t(L"ISO-8859-1"));
    preferences->setJavaScriptEnabled(TRUE);
    preferences->setEditableLinkBehavior(WebKitEditableLinkOnlyLiveWithShiftKey);
    preferences->setDOMPasteAllowed(TRUE);
    preferences->setShouldPrintBackgrounds(TRUE);
    preferences->setCacheModel(WebCacheModelDocumentBrowser);
    prefsPrivate->setXSSAuditorEnabled(FALSE);
    preferences->setPlugInsEnabled(TRUE);
    preferences->setTextAreasAreResizable(TRUE);
    preferences->setUsesPageCache(FALSE);

    preferences->setPrivateBrowsingEnabled(FALSE);
    prefsPrivate->setAuthorAndUserStylesEnabled(TRUE);
    // Shrinks standalone images to fit: YES
    preferences->setJavaScriptCanOpenWindowsAutomatically(TRUE);
    prefsPrivate->setJavaScriptCanAccessClipboard(TRUE);
    prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE);
    prefsPrivate->setJavaScriptRuntimeFlags(WebKitJavaScriptRuntimeFlagsAllEnabled);
    // Set JS experiments enabled: YES
    preferences->setLoadsImagesAutomatically(TRUE);
    prefsPrivate->setLoadsSiteIconsIgnoringImageLoadingPreference(FALSE);
    prefsPrivate->setFrameFlatteningEnabled(FALSE);
    if (persistentUserStyleSheetLocation) {
        preferences->setUserStyleSheetLocation(toBSTR(persistentUserStyleSheetLocation.get()));
        preferences->setUserStyleSheetEnabled(TRUE);
    } else
        preferences->setUserStyleSheetEnabled(FALSE);

#if USE(CG)
    prefsPrivate->setAcceleratedCompositingEnabled(TRUE);
#endif
    // Set WebGL Enabled: NO
    preferences->setCSSRegionsEnabled(TRUE);
    // Set uses HTML5 parser quirks: NO
    // Async spellcheck: NO
    prefsPrivate->setMockScrollbarsEnabled(TRUE);

    preferences->setFontSmoothing(FontSmoothingTypeStandard);

    prefsPrivate->setWebSQLEnabled(true);

    prefsPrivate->setDataTransferItemsEnabled(TRUE);
    prefsPrivate->clearNetworkLoaderSession();

    prefsPrivate->setSpeechRecognitionEnabled(TRUE);

    setAlwaysAcceptCookies(false);
}

template<typename T> T webPreferenceFeatureValue(const std::string& key, const std::unordered_map<std::string, T>& map)
{
    auto it = map.find(key);
    ASSERT(it != map.end());
    return it->second;
}

static void setWebPreferencesForTestOptions(IWebPreferences* preferences, const WTR::TestOptions& options)
{
    COMPtr<IWebPreferencesPrivate8> prefsPrivate { Query, preferences };

    preferences->setPrivateBrowsingEnabled(options.useEphemeralSession());

    // FIXME: Remove this once there is a viable mechanism for reseting WebPreferences between tests,
    // at which point, we will not need to manually reset every supported preference for each test.
    for (const auto& key : options.supportedBoolWebPreferenceFeatures())
        prefsPrivate->setBoolPreferenceForTesting(toBSTR(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)), webPreferenceFeatureValue(key, options.boolWebPreferenceFeatures()));
    for (const auto& key : options.supportedUInt32WebPreferenceFeatures())
        prefsPrivate->setUInt32PreferenceForTesting(toBSTR(WTR::TestOptions::toWebKitLegacyPreferenceKey(key)), webPreferenceFeatureValue(key, options.uint32WebPreferenceFeatures()));
}

static String applicationId()
{
    return makeString("com.apple.DumpRenderTree.", ::GetCurrentProcessId());
}

static void setApplicationId()
{
    COMPtr<IWebPreferences> preferences;
    if (SUCCEEDED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, (void**)&preferences))) {
        COMPtr<IWebPreferencesPrivate4> prefsPrivate4(Query, preferences);
        ASSERT(prefsPrivate4);
        _bstr_t fileName = applicationId().wideCharacters().data();
        prefsPrivate4->setApplicationId(fileName);
    }
}

// Called once on DumpRenderTree startup.
static void setDefaultsToConsistentValuesForTesting()
{
#if USE(CF)
    // Create separate preferences for each DRT instance
    setApplicationId();

    RetainPtr<CFStringRef> appId = applicationId().createCFString();

    String libraryPath = libraryPathForDumpRenderTree();

    // Set up these values before creating the WebView so that the various initializations will see these preferred values.
    CFPreferencesSetAppValue(WebDatabaseDirectoryDefaultsKey, FileSystem::pathByAppendingComponent(libraryPath, "Databases"_s).createCFString().get(), appId.get());
    CFPreferencesSetAppValue(WebStorageDirectoryDefaultsKey, FileSystem::pathByAppendingComponent(libraryPath, "LocalStorage"_s).createCFString().get(), appId.get());
    CFPreferencesSetAppValue(WebKitLocalCacheDefaultsKey, FileSystem::pathByAppendingComponent(libraryPath, "LocalCache"_s).createCFString().get(), appId.get());
#endif
}

static void setJSCOptions(const WTR::TestOptions& options)
{
    static WTF::StringBuilder savedOptions;

    if (!savedOptions.isEmpty()) {
        JSC::Options::setOptions(savedOptions.toString().ascii().data());
        savedOptions.clear();
    }

    if (!options.jscOptions().empty()) {
        JSC::Options::dumpAllOptionsInALine(savedOptions);
        JSC::Options::setOptions(options.jscOptions().c_str());
    }
}

static void resetWebViewToConsistentStateBeforeTesting(const WTR::TestOptions& options)
{
    setJSCOptions(options);

    COMPtr<IWebView> webView;
    if (FAILED(frame->webView(&webView))) 
        return;

    COMPtr<IWebViewEditing> viewEditing;
    if (SUCCEEDED(webView->QueryInterface(&viewEditing)) && viewEditing) {

        viewEditing->setEditable(FALSE);

        COMPtr<IWebEditingDelegate> delegate;
        if (SUCCEEDED(viewEditing->editingDelegate(&delegate)) && delegate) {
            COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
            if (editingDelegate)
                editingDelegate->setAcceptsEditing(TRUE);
        }
    }

    COMPtr<IWebIBActions> webIBActions(Query, webView);
    if (webIBActions) {
        webIBActions->makeTextStandardSize(0);
        webIBActions->resetPageZoom(0);
    }

    COMPtr<IWebViewPrivate2> webViewPrivate(Query, webView);
    if (webViewPrivate) {
        POINT origin = { 0, 0 };
        webViewPrivate->scaleWebView(1.0, origin);
        webViewPrivate->setCustomBackingScaleFactor(0);
        webViewPrivate->setTabKeyCyclesThroughElements(TRUE);
    }

    webView->setPolicyDelegate(DefaultPolicyDelegate::sharedInstance());
    policyDelegate->setPermissive(false);
    policyDelegate->setControllerToNotifyDone(nullptr);
    sharedFrameLoadDelegate->resetToConsistentState();

    if (webViewPrivate) {
        webViewPrivate->clearMainFrameName();
        _bstr_t groupName;
        if (SUCCEEDED(webView->groupName(&groupName.GetBSTR())))
            webViewPrivate->removeAllUserContentFromGroup(groupName);
    }

    COMPtr<IWebPreferences> preferences;
    if (SUCCEEDED(webView->preferences(&preferences))) {
        COMPtr<IWebPreferencesPrivate8> prefsPrivate { Query, preferences };
        prefsPrivate->startBatchingUpdates();

        resetWebPreferencesToConsistentValues(preferences.get());
        setWebPreferencesForTestOptions(preferences.get(), options);

        prefsPrivate->stopBatchingUpdates();
    }

    TestRunner::setSerializeHTTPLoads(false);

    setlocale(LC_ALL, "");

    if (::gTestRunner) {
        JSGlobalContextRef context = frame->globalContext();
        WebCoreTestSupport::resetInternalsObject(context);
    }

    if (preferences) {
        preferences->setContinuousSpellCheckingEnabled(TRUE);
        // Automatic Quote Subs
        // Automatic Link Detection
        // Autommatic Dash substitution
        // Automatic Spell Check
        preferences->setGrammarCheckingEnabled(TRUE);
        // Use Test Mode Focus Ring
    }

    HWND viewWindow;
    if (webViewPrivate && SUCCEEDED(webViewPrivate->viewWindow(&viewWindow)) && viewWindow)
        ::SetFocus(viewWindow);

    webViewPrivate->resetOriginAccessAllowLists();

    sharedUIDelegate->resetUndoManager();

    COMPtr<IWebFramePrivate> framePrivate;
    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))
        framePrivate->clearOpener();

    COMPtr<IWebViewPrivate5> webViewPrivate5(Query, webView);
    webViewPrivate5->exitFullscreenIfNeeded();

    WebCoreTestSupport::clearAllLogChannelsToAccumulate();
    WebCoreTestSupport::initializeLogChannelsIfNecessary();
}

static void sizeWebViewForCurrentTest()
{
    bool isSVGW3CTest = (::gTestRunner->testURL().find("svg\\W3C-SVG-1.1") != string::npos)
        || (::gTestRunner->testURL().find("svg/W3C-SVG-1.1") != string::npos);
    unsigned width = isSVGW3CTest ? TestRunner::w3cSVGViewWidth : TestRunner::viewWidth;
    unsigned height = isSVGW3CTest ? TestRunner::w3cSVGViewHeight : TestRunner::viewHeight;

    ::SetWindowPos(webViewWindow, 0, 0, 0, width, height, SWP_NOMOVE);
}

static String findFontFallback(const char* pathOrUrl)
{
    String pathToFontFallback = FileSystem::parentPath(String::fromUTF8(pathOrUrl));

    wchar_t fullPath[_MAX_PATH];
    if (!_wfullpath(fullPath, pathToFontFallback.wideCharacters().data(), _MAX_PATH))
        return emptyString();

    if (!::PathIsDirectoryW(fullPath))
        return emptyString();

    String pathToCheck = fullPath;
    StringView pathToCheckView { pathToCheck };

    static const String layoutTests = "LayoutTests"_s;

    // Find the layout test root on the current path:
    size_t location = pathToCheckView.find(layoutTests);
    if (WTF::notFound == location)
        return emptyString();

    StringView pathToTest = pathToCheckView.substring(location + layoutTests.length() + 1);
    String possiblePathToLogue = FileSystem::pathByAppendingComponent(pathToCheckView.left(location + layoutTests.length() + 1), "platform\\win"_s);

    Vector<String> possiblePaths;
    possiblePaths.append(FileSystem::pathByAppendingComponent(possiblePathToLogue, pathToTest));

    size_t nextCandidateEnd = pathToTest.reverseFind('\\');
    while (nextCandidateEnd && nextCandidateEnd != WTF::notFound) {
        pathToTest = pathToTest.left(nextCandidateEnd);
        possiblePaths.append(FileSystem::pathByAppendingComponent(possiblePathToLogue, pathToTest));
        nextCandidateEnd = pathToTest.reverseFind('\\');
    }

    for (Vector<String>::iterator pos = possiblePaths.begin(); pos != possiblePaths.end(); ++pos) {
        pathToFontFallback = FileSystem::pathByAppendingComponent(*pos, "resources\\"_s);

        if (::PathIsDirectoryW(pathToFontFallback.wideCharacters().data()))
            return pathToFontFallback;
    }

    return emptyString();
}

static void addFontFallbackIfPresent(const String& fontFallbackPath)
{
    if (fontFallbackPath.isEmpty())
        return;

    String fontFallback = FileSystem::pathByAppendingComponent(fontFallbackPath, "Mac-compatible-font-fallback.css"_s);

    if (!::PathFileExistsW(fontFallback.wideCharacters().data()))
        return;

    ::setPersistentUserStyleSheetLocation(fontFallback.createCFString().get());
}

static void removeFontFallbackIfPresent(const String& fontFallbackPath)
{
    if (fontFallbackPath.isEmpty())
        return;

    String fontFallback = FileSystem::pathByAppendingComponent(fontFallbackPath, "Mac-compatible-font-fallback.css"_s);

    if (!::PathFileExistsW(fontFallback.wideCharacters().data()))
        return;

    ::setPersistentUserStyleSheetLocation(nullptr);
}

static bool handleControlCommand(const char* command)
{
    if (!strcmp("#CHECK FOR ABANDONED DOCUMENTS", command)) {
        // DumpRenderTree does not support checking for abandoned documents.
        fputs("Content-Type: text/plain\nContent-Length: 1\n\n#EOF\n", stdout);
        fputs("#EOF\n", stderr);
        fflush(stdout);
        fflush(stderr);
        return true;
    }
    return false;
}

static WTR::TestOptions testOptionsForTest(const WTR::TestCommand& command)
{
    WTR::TestFeatures features = WTR::TestOptions::defaults();
    WTR::merge(features, WTR::hardcodedFeaturesBasedOnPathForTest(command));
    WTR::merge(features, WTR::featureDefaultsFromTestHeaderForTest(command, WTR::TestOptions::keyTypeMapping()));

    return WTR::TestOptions { WTFMove(features) };
}

static void runTest(const string& inputLine)
{
    ASSERT(!inputLine.empty());

    auto command = WTR::parseInputLine(inputLine);
    const string& pathOrURL = command.pathOrURL;
    dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests;

    static _bstr_t methodBStr(TEXT("GET"));

    auto str = adoptCF(CFStringCreateWithCString(0, pathOrURL.c_str(), kCFStringEncodingWindowsLatin1));
    if (!str) {
        fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str());
        return;
    }

    auto url = adoptCF(CFURLCreateWithString(0, str.get(), 0));
    if (!url)
        url = adoptCF(CFURLCreateWithFileSystemPath(0, str.get(), kCFURLWindowsPathStyle, false));

    if (!url) {
        fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str());
        return;
    }

    String hostName = String(adoptCF(CFURLCopyHostName(url.get())).get());
    String fallbackPath = findFontFallback(pathOrURL.c_str());

    auto urlCFString = CFURLGetString(url.get());

    auto urlBStr = toBSTR(urlCFString);
    ASSERT(urlBStr.length() == CFStringGetLength(urlCFString));

    auto options = testOptionsForTest(command);

    resetWebViewToConsistentStateBeforeTesting(options);

    ::gTestRunner = TestRunner::create(toUTF8(urlCFString), command.expectedPixelHash);
    ::gTestRunner->setCustomTimeout(command.timeout.milliseconds());
    ::gTestRunner->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr || options.dumpJSConsoleLogInStdErr());

    topLoadingFrame = nullptr;
    done = false;

    addFontFallbackIfPresent(fallbackPath);

    sizeWebViewForCurrentTest();
    ::gTestRunner->setIconDatabaseEnabled(false);
    ::gTestRunner->clearAllApplicationCaches();

    ::gTestRunner->clearAllDatabases();

    if (shouldLogFrameLoadDelegates(pathOrURL.c_str()))
        ::gTestRunner->setDumpFrameLoadCallbacks(true);

    COMPtr<IWebView> webView;
    if (SUCCEEDED(frame->webView(&webView))) {
        COMPtr<IWebViewPrivate2> viewPrivate;
        if (SUCCEEDED(webView->QueryInterface(&viewPrivate))) {
            if (shouldLogHistoryDelegates(pathOrURL.c_str())) {
                ::gTestRunner->setDumpHistoryDelegateCallbacks(true);            
                viewPrivate->setHistoryDelegate(sharedHistoryDelegate.get());
            } else
                viewPrivate->setHistoryDelegate(nullptr);
        }
    }

    if (shouldDumpAsText(pathOrURL.c_str())) {
        ::gTestRunner->setDumpAsText(true);
        ::gTestRunner->setGeneratePixelResults(false);
    }

    COMPtr<IWebHistory> history;
    if (SUCCEEDED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
        history->setOptionalSharedHistory(nullptr);

    prevTestBFItem = nullptr;
    COMPtr<IWebBackForwardList> bfList;
    if (webView && SUCCEEDED(webView->backForwardList(&bfList)))
        bfList->currentItem(&prevTestBFItem);

    auto& workQueue = DRT::WorkQueue::singleton();
    workQueue.clear();
    workQueue.setFrozen(false);

    MSG msg { };
    HWND hostWindow;
    webView->hostWindow(&hostWindow);

    COMPtr<IWebMutableURLRequest> request, emptyRequest;
    HRESULT hr = WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&request);
    if (FAILED(hr))
        goto exit;

    request->initWithURL(urlBStr, WebURLRequestUseProtocolCachePolicy, 60);
    request->setHTTPMethod(methodBStr);
    if (hostName == "localhost"_s || hostName == "127.0.0.1"_s)
        request->setAllowsAnyHTTPSCertificate();
    frame->loadRequest(request.get());

    while (true) {
#if USE(CF)
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
#endif
        if (done) {
            // Post WM_QUIT to ensure that all deferred tasks are dispatched before quitting the run loop.
            PostQuitMessage(0);
        }

        if (!::GetMessage(&msg, 0, 0, 0))
            break;

        // We get spurious WM_MOUSELEAVE events which make event handling machinery think that mouse button
        // is released during dragging (see e.g. fast\dynamic\layer-hit-test-crash.html).
        // Mouse can never leave WebView during normal DumpRenderTree operation, so we just ignore all such events.
        if (msg.message == WM_MOUSELEAVE)
            continue;
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }

    // EventSendingController clearSavedEvents
    workQueue.clear();

    // If the test page could have possibly opened the Web Inspector frontend,
    // then try to close it in case it was accidentally left open.
    ::gTestRunner->closeWebInspector();


    for (HWND window : Vector(openWindows())) {
        // Don't try to close the main window
        if (window == hostWindow)
            continue;

        ::DestroyWindow(window);
    }

    resetWebViewToConsistentStateBeforeTesting(options);

    // Loading an empty request synchronously replaces the document with a blank one, which is necessary
    // to stop timers, WebSockets and other activity that could otherwise spill output into next test's results.
    if (SUCCEEDED(WebKitCreateInstance(CLSID_WebMutableURLRequest, 0, IID_IWebMutableURLRequest, (void**)&emptyRequest))) {
        _bstr_t emptyURL(L"");
        emptyRequest->initWithURL(emptyURL.GetBSTR(), WebURLRequestUseProtocolCachePolicy, 60);
        emptyRequest->setHTTPMethod(methodBStr);
        frame->loadRequest(emptyRequest.get());
    }

    // We should only have our main window left open when we're done
    ASSERT(openWindows().size() == 1);
    ASSERT(openWindows()[0] == hostWindow);

exit:
    removeFontFallbackIfPresent(fallbackPath);
    ::gTestRunner->cleanup();
    ::gTestRunner = nullptr;

    if (gcBetweenTests) {
        GCController gcController;
        gcController.collect();
    }
    JSC::waitForVMDestruction();

    fputs("#EOF\n", stderr);
    fflush(stderr);
}

Vector<HWND>& openWindows()
{
    static NeverDestroyed<Vector<HWND>> vector;
    return vector;
}

WindowToWebViewMap& windowToWebViewMap()
{
    static NeverDestroyed<WindowToWebViewMap> map;
    return map;
}

IWebView* createWebViewAndOffscreenWindow(HWND* webViewWindow)
{
    int maxViewWidth = TestRunner::viewWidth;
    int maxViewHeight = TestRunner::viewHeight;
    HWND hostWindow = (showWebView) ? CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP, 100, 100, maxViewWidth, maxViewHeight, 0, 0, ::GetModuleHandle(0), nullptr)
        : CreateWindowEx(WS_EX_TOOLWINDOW, kDumpRenderTreeClassName, TEXT("DumpRenderTree"), WS_POPUP, -maxViewWidth, -maxViewHeight, maxViewWidth, maxViewHeight, 0, 0, ::GetModuleHandle(0), nullptr);

    IWebView* webView = nullptr;
    HRESULT hr = WebKitCreateInstance(CLSID_WebView, 0, IID_IWebView, (void**)&webView);
    if (FAILED(hr)) {
        fprintf(stderr, "Failed to create CLSID_WebView instance, error 0x%lx\n", hr);
        return nullptr;
    }

    if (FAILED(webView->setHostWindow(hostWindow)))
        return nullptr;

    RECT clientRect;
    clientRect.bottom = clientRect.left = clientRect.top = clientRect.right = 0;
    _bstr_t groupName(L"org.webkit.DumpRenderTree");
    if (FAILED(webView->initWithFrame(clientRect, 0, groupName)))
        return nullptr;

    COMPtr<IWebViewPrivate2> viewPrivate;
    if (FAILED(webView->QueryInterface(&viewPrivate)))
        return nullptr;

    viewPrivate->setShouldApplyMacFontAscentHack(TRUE);
    viewPrivate->setAlwaysUsesComplexTextCodePath(forceComplexText);
    viewPrivate->setCustomBackingScaleFactor(1.0);

    _bstr_t pluginPath = _bstr_t(exePath().data()) + TestPluginDir;
    if (FAILED(viewPrivate->addAdditionalPluginDirectory(pluginPath.GetBSTR())))
        return nullptr;

    HWND viewWindow;
    if (FAILED(viewPrivate->viewWindow(&viewWindow)))
        return nullptr;
    if (webViewWindow)
        *webViewWindow = viewWindow;

    ::SetWindowPos(viewWindow, 0, 0, 0, maxViewWidth, maxViewHeight, 0);
    ::ShowWindow(hostWindow, SW_SHOW);

    if (FAILED(webView->setUIDelegate(sharedUIDelegate.get())))
        return nullptr;

    if (FAILED(webView->setFrameLoadDelegate(sharedFrameLoadDelegate.get())))
        return nullptr;

    if (FAILED(viewPrivate->setFrameLoadDelegatePrivate(sharedFrameLoadDelegate.get())))
        return nullptr;

    COMPtr<IWebViewEditing> viewEditing;
    if (FAILED(webView->QueryInterface(&viewEditing)))
        return nullptr;

    if (FAILED(viewEditing->setEditingDelegate(sharedEditingDelegate.get())))
        return nullptr;

    if (FAILED(webView->setResourceLoadDelegate(resourceLoadDelegate.get())))
        return nullptr;

    viewPrivate->setDefersCallbacks(FALSE);

    openWindows().append(hostWindow);
    windowToWebViewMap().set(hostWindow, webView);
    return webView;
}

#if USE(CFURLCONNECTION)
RetainPtr<CFURLCacheRef> sharedCFURLCache()
{
#ifndef DEBUG_ALL
    HMODULE module = GetModuleHandle(TEXT("CFNetwork.dll"));
#else
    HMODULE module = GetModuleHandle(TEXT("CFNetwork_debug.dll"));
#endif
    if (!module)
        return nullptr;

    typedef CFURLCacheRef (*CFURLCacheCopySharedURLCacheProcPtr)(void);
    if (CFURLCacheCopySharedURLCacheProcPtr copyCache = reinterpret_cast<CFURLCacheCopySharedURLCacheProcPtr>(GetProcAddress(module, "CFURLCacheCopySharedURLCache")))
        return adoptCF(copyCache());

    typedef CFURLCacheRef (*CFURLCacheSharedURLCacheProcPtr)(void);
    if (CFURLCacheSharedURLCacheProcPtr sharedCache = reinterpret_cast<CFURLCacheSharedURLCacheProcPtr>(GetProcAddress(module, "CFURLCacheSharedURLCache")))
        return sharedCache();

    return nullptr;
}
#endif

static Vector<const char*> initializeGlobalsFromCommandLineOptions(int argc, const char* argv[])
{
    Vector<const char*> tests;

    for (int i = 1; i < argc; ++i) {
        if (!stricmp(argv[i], "--notree")) {
            dumpTree = false;
            continue;
        }

        if (!stricmp(argv[i], "--pixel-tests")) {
            dumpPixelsForAllTests = true;
            continue;
        }

        if (!stricmp(argv[i], "--tree")) {
            dumpTree = true;
            continue;
        }

        if (!stricmp(argv[i], "--threaded")) {
            threaded = true;
            continue;
        }

        if (!stricmp(argv[i], "--complex-text")) {
            forceComplexText = true;
            continue;
        }

        if (!stricmp(argv[i], "--accelerated-drawing")) {
            useAcceleratedDrawing = true;
            continue;
        }

        if (!stricmp(argv[i], "--gc-between-tests")) {
            gcBetweenTests = true;
            continue;
        }

        if (!stricmp(argv[i], "--no-timeout")) {
            useTimeoutWatchdog = false;
            continue;
        }

        if (!stricmp(argv[i], "--dump-all-pixels")) {
            dumpAllPixels = true;
            continue;
        }

        if (!stricmp(argv[i], "--show-webview")) {
            showWebView = true;
            continue;
        }

        tests.append(argv[i]);
    }

    return tests;
}

static void allocateGlobalControllers()
{
    sharedFrameLoadDelegate.adoptRef(new FrameLoadDelegate);
    sharedUIDelegate.adoptRef(new UIDelegate);
    sharedEditingDelegate.adoptRef(new EditingDelegate);
    resourceLoadDelegate.adoptRef(new ResourceLoadDelegate);
    policyDelegate = new PolicyDelegate();
    sharedHistoryDelegate.adoptRef(new HistoryDelegate);
    // storage delegate
    // policy delegate
}

static void prepareConsistentTestingEnvironment(IWebPreferences* standardPreferences, IWebPreferencesPrivate* standardPreferencesPrivate)
{
    ASSERT(standardPreferences);
    ASSERT(standardPreferencesPrivate);
    standardPreferences->setAutosaves(FALSE);

#if USE(CFURLCONNECTION)
    auto newCache = adoptCF(CFURLCacheCreate(kCFAllocatorDefault, 1024 * 1024, 0, nullptr));
    CFURLCacheSetSharedURLCache(newCache.get());
#endif

    COMPtr<IWebPreferencesPrivate4> prefsPrivate4(Query, standardPreferences);
    prefsPrivate4->switchNetworkLoaderToNewTestingSession();

    standardPreferences->setJavaScriptEnabled(TRUE);
    standardPreferences->setDefaultFontSize(16);
#if USE(CG)
    standardPreferences->setAcceleratedCompositingEnabled(TRUE);
    standardPreferences->setAVFoundationEnabled(TRUE);
#endif

    allocateGlobalControllers();
}

int main(int argc, const char* argv[])
{
    // Cygwin calls ::SetErrorMode(SEM_FAILCRITICALERRORS), which we will inherit. This is bad for
    // testing/debugging, as it causes the post-mortem debugger not to be invoked. We reset the
    // error mode here to work around Cygwin's behavior. See <http://webkit.org/b/55222>.
    ::SetErrorMode(0);

    leakChecking = false;

    _setmode(1, _O_BINARY);
    _setmode(2, _O_BINARY);

    // Some tests are flaky because certain DLLs are writing to stdout, giving incorrect test results.
    // We work around that here by duplicating and redirecting stdout.
    int fdStdout = _dup(1);
    _setmode(fdStdout, _O_BINARY);
    testResult = fdopen(fdStdout, "a+b");
    // Redirect stdout to stderr.
    int result = _dup2(_fileno(stderr), 1);
    if (result)
        return -5;

    // Tests involving the clipboard are flaky when running with multiple DRTs, since the clipboard is global.
    // We can fix this by assigning each DRT a separate window station (each window station has its own clipboard).
    DWORD processId = ::GetCurrentProcessId();
    String windowStationName = makeString("windowStation", processId);
    String desktopName = makeString("desktop", processId);
    HDESK desktop = nullptr;

    auto windowsStation = ::CreateWindowStation(windowStationName.wideCharacters().data(), CWF_CREATE_ONLY, WINSTA_ALL_ACCESS, nullptr);
    if (windowsStation) {
        if (!::SetProcessWindowStation(windowsStation))
            fprintf(stderr, "SetProcessWindowStation failed with error %lu\n", ::GetLastError());

        desktop = ::CreateDesktop(desktopName.wideCharacters().data(), nullptr, nullptr, 0, GENERIC_ALL, nullptr);
        if (!desktop)
            fprintf(stderr, "Failed to create desktop with error %lu\n", ::GetLastError());
    } else {
        DWORD error = ::GetLastError();
        fprintf(stderr, "Failed to create window station with error %lu\n", error);
        if (error == ERROR_ACCESS_DENIED)
            fprintf(stderr, "DumpRenderTree should be run as Administrator!\n");
    }

    initialize();

    setDefaultsToConsistentValuesForTesting();

    Vector<const char*> tests = initializeGlobalsFromCommandLineOptions(argc, argv);

    JSC::initialize();
    WTF::initializeMainThread();
    WebCoreTestSupport::populateJITOperations();

    // FIXME - need to make DRT pass with Windows native controls <http://bugs.webkit.org/show_bug.cgi?id=25592>
    COMPtr<IWebPreferences> tmpPreferences;
    if (FAILED(WebKitCreateInstance(CLSID_WebPreferences, 0, IID_IWebPreferences, reinterpret_cast<void**>(&tmpPreferences))))
        return -1;
    COMPtr<IWebPreferences> standardPreferences;
    if (FAILED(tmpPreferences->standardPreferences(&standardPreferences)))
        return -2;
    COMPtr<IWebPreferencesPrivate> standardPreferencesPrivate;
    if (FAILED(standardPreferences->QueryInterface(&standardPreferencesPrivate)))
        return -3;

    prepareConsistentTestingEnvironment(standardPreferences.get(), standardPreferencesPrivate.get());

    COMPtr<IWebView> webView(AdoptCOM, createWebViewAndOffscreenWindow(&webViewWindow));
    if (!webView)
        return -4;

    if (FAILED(webView->mainFrame(&frame)))
        return -7;

#if USE(CFURLCONNECTION)
    RetainPtr<CFURLCacheRef> urlCache = sharedCFURLCache();
    CFURLCacheRemoveAllCachedResponses(urlCache.get());
#endif

#ifdef _DEBUG
    _CrtMemState entryToMainMemCheckpoint;
    if (leakChecking)
        _CrtMemCheckpoint(&entryToMainMemCheckpoint);
#endif

    if (threaded)
        startJavaScriptThreads();

    if (tests.size() == 1 && !strcmp(tests[0], "-")) {
        char filenameBuffer[2048];
        printSeparators = true;
        while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
            char* newLineCharacter = strchr(filenameBuffer, '\n');
            if (newLineCharacter)
                *newLineCharacter = '\0';
            
            if (strlen(filenameBuffer) == 0)
                continue;

            if (handleControlCommand(filenameBuffer))
                continue;

            runTest(filenameBuffer);
        }
    } else {
        printSeparators = tests.size() > 1;
        for (int i = 0; i < tests.size(); i++)
            runTest(tests[i]);
    }

    if (threaded)
        stopJavaScriptThreads();
    
    delete policyDelegate;
    frame->Release();

#ifdef _DEBUG
    if (leakChecking) {
        // dump leaks to stderr
        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
        _CrtMemDumpAllObjectsSince(&entryToMainMemCheckpoint);
    }
#endif

    shutDownWebKit();
#ifdef _CRTDBG_MAP_ALLOC
    _CrtDumpMemoryLeaks();
#endif

    if (desktop)
        ::CloseDesktop(desktop);
    if (windowsStation)
        ::CloseWindowStation(windowsStation);

    ::OleUninitialize();

    return 0;
}

extern "C" __declspec(dllexport) int WINAPI dllLauncherEntryPoint(int argc, const char* argv[])
{
    return main(argc, argv);
}
