/*
 * 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* arrPtr;
    if (FAILED(itemPrivate->children(&kidsCount, &arrPtr)) || !kidsCount)
        return;

    Vector<COMPtr<IUnknown> > kidsVector;

    LONG lowerBound;
    if (FAILED(::SafeArrayGetLBound(arrPtr, 1, &lowerBound)))
        goto exit;

    LONG upperBound;
    if (FAILED(::SafeArrayGetUBound(arrPtr, 1, &upperBound)))
        goto exit;

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

    IUnknown** safeArrayData;
    if (FAILED(::SafeArrayAccessData(arrPtr, (void**)&safeArrayData)))
        goto exit;

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

    // 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);
    }

exit:
    if (arrPtr && SUCCEEDED(::SafeArrayUnlock(arrPtr)))
        ::SafeArrayDestroy(arrPtr);
}

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->setJavaEnabled(FALSE);
    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").createCFString().get(), appId.get());
    CFPreferencesSetAppValue(WebStorageDirectoryDefaultsKey, FileSystem::pathByAppendingComponent(libraryPath, "LocalStorage").createCFString().get(), appId.get());
    CFPreferencesSetAppValue(WebKitLocalCacheDefaultsKey, FileSystem::pathByAppendingComponent(libraryPath, "LocalCache").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(pathOrUrl);

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

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

    String pathToCheck = fullPath;

    static const String layoutTests = "LayoutTests";

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

    String pathToTest = pathToCheck.substring(location + layoutTests.length() + 1);
    String possiblePathToLogue = FileSystem::pathByAppendingComponent(pathToCheck.substring(0, location + layoutTests.length() + 1), "platform\\win");

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

    size_t nextCandidateEnd = pathToTest.reverseFind('\\');
    while (nextCandidateEnd && nextCandidateEnd != WTF::notFound) {
        pathToTest = pathToTest.substring(0, 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\\");

        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");

    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");

    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 abandonded documents.
        String result("\n");
        printf("Content-Type: text/plain\n");
        printf("Content-Length: %u\n", result.length());
        fwrite(result.utf8().data(), 1, result.length(), stdout);
        printf("#EOF\n");
        fprintf(stderr, "#EOF\n");
        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" || hostName == "127.0.0.1")
        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);
}
