/*
 * Copyright (C) 2005-2019 Apple Inc. All rights reserved.
 *           (C) 2007 Graham Dennis (graham.dennis@gmail.com)
 *
 * 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.
 */

#import "config.h"
#import "DumpRenderTree.h"

#import "AccessibilityController.h"
#import "DefaultPolicyDelegate.h"
#import "DumpRenderTreeDraggingInfo.h"
#import "DumpRenderTreePasteboard.h"
#import "DumpRenderTreeWindow.h"
#import "EditingDelegate.h"
#import "EventSendingController.h"
#import "FrameLoadDelegate.h"
#import "HistoryDelegate.h"
#import "JavaScriptThreading.h"
#import "LayoutTestSpellChecker.h"
#import "MockGeolocationProvider.h"
#import "MockWebNotificationProvider.h"
#import "NavigationController.h"
#import "ObjCPlugin.h"
#import "ObjCPluginFunction.h"
#import "PixelDumpSupport.h"
#import "PolicyDelegate.h"
#import "ResourceLoadDelegate.h"
#import "TestOptions.h"
#import "TestRunner.h"
#import "UIDelegate.h"
#import "WebArchiveDumpSupport.h"
#import "WebCoreTestSupport.h"
#import "WorkQueue.h"
#import "WorkQueueItem.h"
#import <CoreFoundation/CoreFoundation.h>
#import <JavaScriptCore/JSCConfig.h>
#import <JavaScriptCore/Options.h>
#import <JavaScriptCore/TestRunnerUtils.h>
#import <WebCore/LogInitialization.h>
#import <WebCore/NetworkStorageSession.h>
#import <WebKit/DOMElement.h>
#import <WebKit/DOMExtensions.h>
#import <WebKit/DOMRange.h>
#import <WebKit/WKCrashReporter.h>
#import <WebKit/WKRetainPtr.h>
#import <WebKit/WKString.h>
#import <WebKit/WKStringCF.h>
#import <WebKit/WebArchive.h>
#import <WebKit/WebBackForwardList.h>
#import <WebKit/WebCache.h>
#import <WebKit/WebCoreStatistics.h>
#import <WebKit/WebDataSourcePrivate.h>
#import <WebKit/WebDatabaseManagerPrivate.h>
#import <WebKit/WebDeviceOrientationProviderMock.h>
#import <WebKit/WebDocumentPrivate.h>
#import <WebKit/WebEditingDelegate.h>
#import <WebKit/WebFrameView.h>
#import <WebKit/WebHistory.h>
#import <WebKit/WebHistoryItemPrivate.h>
#import <WebKit/WebInspector.h>
#import <WebKit/WebKitNSStringExtras.h>
#import <WebKit/WebPluginDatabase.h>
#import <WebKit/WebPreferenceKeysPrivate.h>
#import <WebKit/WebPreferences.h>
#import <WebKit/WebPreferencesPrivate.h>
#import <WebKit/WebResourceLoadDelegate.h>
#import <WebKit/WebStorageManagerPrivate.h>
#import <WebKit/WebViewPrivate.h>
#import <getopt.h>
#import <wtf/Assertions.h>
#import <wtf/FastMalloc.h>
#import <wtf/LoggingAccumulator.h>
#import <wtf/ObjCRuntimeExtras.h>
#import <wtf/ProcessPrivilege.h>
#import <wtf/RetainPtr.h>
#import <wtf/Threading.h>
#import <wtf/UniqueArray.h>
#import <wtf/text/StringBuilder.h>
#import <wtf/text/WTFString.h>

#if !PLATFORM(IOS_FAMILY)
#import <Carbon/Carbon.h>
#import <WebKit/WebDynamicScrollBarsView.h>
#endif

#if PLATFORM(IOS_FAMILY)
#import "DumpRenderTreeBrowserView.h"
#import "IOSLayoutTestCommunication.h"
#import "UIKitSPI.h"
#import <QuartzCore/QuartzCore.h>
#import <WebKit/WAKWindow.h>
#import <WebKit/WebCoreThread.h>
#import <WebKit/WebCoreThreadRun.h>
#import <WebKit/WebDOMOperations.h>
#import <fcntl.h>
#import <pal/spi/cg/CoreGraphicsSPI.h>
#endif

extern "C" {
#import <mach-o/getsect.h>
}

using namespace std;

#if !PLATFORM(IOS_FAMILY)
@interface DumpRenderTreeApplication : NSApplication
@end

@interface DumpRenderTreeEvent : NSEvent
@end
#else
@interface ScrollViewResizerDelegate : NSObject
@end

@implementation ScrollViewResizerDelegate
- (void)view:(UIWebDocumentView *)view didSetFrame:(CGRect)newFrame oldFrame:(CGRect)oldFrame asResultOfZoom:(BOOL)wasResultOfZoom
{
    UIView *scrollView = [view superview];
    while (![scrollView isKindOfClass:[UIWebScrollView class]])
        scrollView = [scrollView superview];

    ASSERT(scrollView && [scrollView isKindOfClass:[UIWebScrollView class]]);
    const CGSize scrollViewSize = [scrollView bounds].size;
    CGSize contentSize = newFrame.size;
    contentSize.height = CGRound(max(CGRectGetMaxY(newFrame), scrollViewSize.height));
    [(UIWebScrollView *)scrollView setContentSize:contentSize];
}
@end
#endif

@interface NSURLRequest (PrivateThingsWeShouldntReallyUse)
+(void)setAllowsAnyHTTPSCertificate:(BOOL)allow forHost:(NSString *)host;
@end

#if USE(APPKIT)
@interface NSSound ()
+ (void)_setAlertType:(NSUInteger)alertType;
@end
#endif

@interface WebView ()
- (BOOL)_flushCompositingChanges;
@end

#if !PLATFORM(IOS_FAMILY)
@interface WebView (WebViewInternalForTesting)
- (WebCore::Frame*)_mainCoreFrame;
@end
#endif

static void runTest(const string& testURL);

// Deciding when it's OK to dump out the state is a bit tricky.  All these must be true:
// - There is no load in progress
// - There is no work queued up (see workQueue var, below)
// - waitToDump==NO.  This means either waitUntilDone was never called, or it was called
//       and notifyDone was called subsequently.
// Note that the call to notifyDone and the end of the load can happen in either order.

volatile bool done;

NavigationController* gNavigationController = nullptr;
RefPtr<TestRunner> gTestRunner;

Optional<TestOptions> mainFrameTestOptions;
WebFrame *mainFrame = nil;
// 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".
WebFrame *topLoadingFrame = nil; // !nil iff a load is in progress

#if PLATFORM(MAC)
NSWindow *mainWindow = nil;
#endif

CFMutableSetRef disallowedURLs= nullptr;
static CFRunLoopTimerRef waitToDumpWatchdog;

// Delegates
static FrameLoadDelegate *frameLoadDelegate;
static UIDelegate *uiDelegate;
static EditingDelegate *editingDelegate;
static ResourceLoadDelegate *resourceLoadDelegate;
static HistoryDelegate *historyDelegate;
PolicyDelegate *policyDelegate = nullptr;
DefaultPolicyDelegate *defaultPolicyDelegate = nullptr;
#if PLATFORM(IOS_FAMILY)
static ScrollViewResizerDelegate *scrollViewResizerDelegate;
#endif

static int dumpPixelsForAllTests;
static bool dumpPixelsForCurrentTest;
static int threaded;
static int dumpTree = YES;
static int useTimeoutWatchdog = YES;
static int forceComplexText;
static int useAcceleratedDrawing;
static int gcBetweenTests;
static int allowAnyHTTPSCertificateForAllowedHosts;
static int showWebView;
static int printTestCount;
static int checkForWorldLeaks;
static BOOL printSeparators;
static RetainPtr<CFStringRef> persistentUserStyleSheetLocation;
static std::set<std::string> allowedHosts;

static WebHistoryItem *prevTestBFItem; // current b/f item at the end of the previous test

#if PLATFORM(IOS_FAMILY)
const CGRect layoutTestViewportRect = { {0, 0}, {static_cast<CGFloat>(TestRunner::viewWidth), static_cast<CGFloat>(TestRunner::viewHeight)} };
DumpRenderTreeBrowserView *gWebBrowserView = nil;
DumpRenderTreeWebScrollView *gWebScrollView = nil;
DumpRenderTreeWindow *gDrtWindow = nil;
#endif

#ifdef __OBJC2__
static void swizzleAllMethods(Class imposter, Class original)
{
    unsigned int imposterMethodCount;
    Method* imposterMethods = class_copyMethodList(imposter, &imposterMethodCount);

    unsigned int originalMethodCount;
    Method* originalMethods = class_copyMethodList(original, &originalMethodCount);

    for (unsigned int i = 0; i < imposterMethodCount; i++) {
        SEL imposterMethodName = method_getName(imposterMethods[i]);

        // Attempt to add the method to the original class.  If it fails, the method already exists and we should
        // instead exchange the implementations.
        if (class_addMethod(original, imposterMethodName, method_getImplementation(imposterMethods[i]), method_getTypeEncoding(imposterMethods[i])))
            continue;

        unsigned int j = 0;
        for (; j < originalMethodCount; j++) {
            SEL originalMethodName = method_getName(originalMethods[j]);
            if (sel_isEqual(imposterMethodName, originalMethodName))
                break;
        }

        // If class_addMethod failed above then the method must exist on the original class.
        ASSERT(j < originalMethodCount);
        method_exchangeImplementations(imposterMethods[i], originalMethods[j]);
    }

    free(imposterMethods);
    free(originalMethods);
}
#endif

static void poseAsClass(const char* imposter, const char* original)
{
    Class imposterClass = objc_getClass(imposter);
    Class originalClass = objc_getClass(original);

#ifndef __OBJC2__
    class_poseAs(imposterClass, originalClass);
#else

    // Swizzle instance methods
    swizzleAllMethods(imposterClass, originalClass);
    // and then class methods
    swizzleAllMethods(object_getClass(imposterClass), object_getClass(originalClass));
#endif
}

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

static bool shouldIgnoreWebCoreNodeLeaks(const string& URLString)
{
    static char* const ignoreSet[] = {
        // Keeping this infrastructure around in case we ever need it again.
    };
    static const int ignoreSetCount = sizeof(ignoreSet) / sizeof(char*);

    for (int i = 0; i < ignoreSetCount; i++) {
        // FIXME: ignore case
        string curIgnore(ignoreSet[i]);
        // Match at the end of the URLString
        if (!URLString.compare(URLString.length() - curIgnore.length(), curIgnore.length(), curIgnore))
            return true;
    }
    return false;
}

#if !PLATFORM(IOS_FAMILY)
static NSSet *allowedFontFamilySet()
{
    static NSSet *fontFamilySet = [[NSSet setWithObjects:
        @"Ahem",
        @"Al Bayan",
        @"American Typewriter",
        @"Andale Mono",
        @"Apple Braille",
        @"Apple Color Emoji",
        @"Apple Chancery",
        @"Apple Garamond BT",
        @"Apple LiGothic",
        @"Apple LiSung",
        @"Apple Symbols",
        @"AppleGothic",
        @"AppleMyungjo",
        @"Arial Black",
        @"Arial Hebrew",
        @"Arial Narrow",
        @"Arial Rounded MT Bold",
        @"Arial Unicode MS",
        @"Arial",
        @"Avenir Next",
        @"Ayuthaya",
        @"Baghdad",
        @"Baskerville",
        @"BiauKai",
        @"Big Caslon",
        @"Brush Script MT",
        @"Chalkboard",
        @"Chalkduster",
        @"Charcoal CY",
        @"Cochin",
        @"Comic Sans MS",
        @"Copperplate",
        @"Corsiva Hebrew",
        @"Courier New",
        @"Courier",
        @"DecoType Naskh",
        @"Devanagari MT",
        @"Didot",
        @"Euphemia UCAS",
        @"Futura",
        @"GB18030 Bitmap",
        @"Geeza Pro",
        @"Geneva CY",
        @"Geneva",
        @"Georgia",
        @"Gill Sans",
        @"Gujarati MT",
        @"GungSeo",
        @"Gurmukhi MT",
        @"HeadLineA",
        @"Hei",
        @"Heiti SC",
        @"Heiti TC",
        @"Helvetica CY",
        @"Helvetica Neue",
        @"Helvetica",
        @"Herculanum",
        @"Hiragino Kaku Gothic Pro",
        @"Hiragino Kaku Gothic ProN",
        @"Hiragino Kaku Gothic Std",
        @"Hiragino Kaku Gothic StdN",
        @"Hiragino Maru Gothic Pro",
        @"Hiragino Maru Gothic ProN",
        @"Hiragino Mincho Pro",
        @"Hiragino Mincho ProN",
        @"Hiragino Sans",
        @"Hiragino Sans GB",
        @"Hoefler Text",
        @"Impact",
        @"InaiMathi",
        @"Kai",
        @"Kailasa",
        @"Kokonor",
        @"Krungthep",
        @"KufiStandardGK",
        @"Lao Sangam MN",
        @"LastResort",
        @"LiHei Pro",
        @"LiSong Pro",
        @"Lucida Grande",
        @"Marker Felt",
        @"Menlo",
        @"Microsoft Sans Serif",
        @"Monaco",
        @"Mshtakan",
        @"Nadeem",
        @"New Peninim MT",
        @"Optima",
        @"Osaka",
        @"Palatino",
        @"Papyrus",
        @"PCMyungjo",
        @"PilGi",
        @"PingFang HK",
        @"PingFang SC",
        @"PingFang TC",
        @"Plantagenet Cherokee",
        @"Raanana",
        @"Sathu",
        @"Silom",
        @"Skia",
        @"Snell Roundhand",
        @"Songti SC",
        @"Songti TC",
        @"STFangsong",
        @"STHeiti",
        @"STIXGeneral",
        @"STIXSizeOneSym",
        @"STKaiti",
        @"STSong",
        @"Symbol",
        @"Tahoma",
        @"Thonburi",
        @"Times New Roman",
        @"Times",
        @"Trebuchet MS",
        @"Verdana",
        @"Webdings",
        @"WebKit WeightWatcher",
        @"FontWithFeaturesOTF",
        @"FontWithFeaturesTTF",
        @"Wingdings 2",
        @"Wingdings 3",
        @"Wingdings",
        @"Zapf Dingbats",
        @"Zapfino",
        nil] retain];

    return fontFamilySet;
}

static NSArray *fontWhitelist()
{
    static NSArray *availableFonts;
    if (availableFonts)
        return availableFonts;

    NSMutableArray *availableFontList = [[NSMutableArray alloc] init];
    for (NSString *fontFamily in allowedFontFamilySet()) {
        NSArray* fontsForFamily = [[NSFontManager sharedFontManager] availableMembersOfFontFamily:fontFamily];
        [availableFontList addObject:fontFamily];
        for (NSArray* fontInfo in fontsForFamily) {
            // Font name is the first entry in the array.
            [availableFontList addObject:[fontInfo objectAtIndex:0]];
        }
    }

    availableFonts = availableFontList;
    return availableFonts;
}

// Activating system copies of these fonts overrides any others that could be preferred, such as ones
// in /Library/Fonts/Microsoft, and which don't always have the same metrics.
// FIXME: Switch to a solution from <rdar://problem/19553550> once it's available.
static void activateSystemCoreWebFonts()
{
    NSArray *coreWebFontNames = @[
        @"Andale Mono",
        @"Arial",
        @"Arial Black",
        @"Comic Sans MS",
        @"Courier New",
        @"Georgia",
        @"Impact",
        @"Times New Roman",
        @"Trebuchet MS",
        @"Verdana",
        @"Webdings"
    ];

    NSArray *fontFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL fileURLWithPath:@"/Library/Fonts" isDirectory:YES]
        includingPropertiesForKeys:@[NSURLFileResourceTypeKey, NSURLNameKey] options:0 error:0];

    for (NSURL *fontURL in fontFiles) {
        NSString *resourceType;
        NSString *fileName;
        if (![fontURL getResourceValue:&resourceType forKey:NSURLFileResourceTypeKey error:0]
            || ![fontURL getResourceValue:&fileName forKey:NSURLNameKey error:0])
            continue;
        if (![resourceType isEqualToString:NSURLFileResourceTypeRegular])
            continue;

        // Activate all font variations, such as Arial Bold Italic.ttf. This algorithm is not 100% precise, as it
        // also activates e.g. Arial Unicode, which is not a variation of Arial.
        for (NSString *coreWebFontName in coreWebFontNames) {
            if ([fileName hasPrefix:coreWebFontName]) {
                CTFontManagerRegisterFontsForURL((CFURLRef)fontURL, kCTFontManagerScopeProcess, 0);
                break;
            }
        }
    }
}

static void activateTestingFonts()
{
    static const char* fontFileNames[] = {
        "AHEM____.TTF",
        "WebKitWeightWatcher100.ttf",
        "WebKitWeightWatcher200.ttf",
        "WebKitWeightWatcher300.ttf",
        "WebKitWeightWatcher400.ttf",
        "WebKitWeightWatcher500.ttf",
        "WebKitWeightWatcher600.ttf",
        "WebKitWeightWatcher700.ttf",
        "WebKitWeightWatcher800.ttf",
        "WebKitWeightWatcher900.ttf",
        "FontWithFeatures.ttf",
        "FontWithFeatures.otf",
        0
    };

    NSMutableArray *fontURLs = [NSMutableArray array];
    NSURL *resourcesDirectory = [NSURL URLWithString:@"DumpRenderTree.resources" relativeToURL:[[NSBundle mainBundle] executableURL]];
    for (unsigned i = 0; fontFileNames[i]; ++i) {
        NSURL *fontURL = [resourcesDirectory URLByAppendingPathComponent:[NSString stringWithUTF8String:fontFileNames[i]] isDirectory:NO];
        [fontURLs addObject:[fontURL absoluteURL]];
    }

    CFArrayRef errors = 0;
    if (!CTFontManagerRegisterFontsForURLs((CFArrayRef)fontURLs, kCTFontManagerScopeProcess, &errors)) {
        NSLog(@"Failed to activate fonts: %@", errors);
        CFRelease(errors);
        exit(1);
    }
}

static void adjustFonts()
{
    activateSystemCoreWebFonts();
    activateTestingFonts();
}
#else
static void activateFontIOS(const uint8_t* fontData, unsigned long length, std::string sectionName)
{
    CGDataProviderRef data = CGDataProviderCreateWithData(nullptr, fontData, length, nullptr);
    if (!data) {
        fprintf(stderr, "Failed to create CGDataProviderRef for the %s font.\n", sectionName.c_str());
        exit(1);
    }

    CGFontRef cgFont = CGFontCreateWithDataProvider(data);
    CGDataProviderRelease(data);
    if (!cgFont) {
        fprintf(stderr, "Failed to create CGFontRef for the %s font.\n", sectionName.c_str());
        exit(1);
    }

    CFErrorRef error = nullptr;
    CTFontManagerRegisterGraphicsFont(cgFont, &error);
    if (error) {
        fprintf(stderr, "Failed to add CGFont to CoreText for the %s font: %s.\n", sectionName.c_str(), CFStringGetCStringPtr(CFErrorCopyDescription(error), kCFStringEncodingUTF8));
        exit(1);
    }
    CGFontRelease(cgFont);
}

static void activateFontsIOS()
{
    // __asm() requires a string literal, so we can't do this as either local variables or template parameters.
#define fontData(sectionName) \
{ \
    extern const uint8_t start##sectionName __asm("section$start$__DATA$" # sectionName); \
    extern const uint8_t end##sectionName __asm("section$end$__DATA$" # sectionName); \
    activateFontIOS(&start##sectionName, &end##sectionName - &start##sectionName, #sectionName); \
}
    fontData(Ahem);
    fontData(WeightWatcher100);
    fontData(WeightWatcher200);
    fontData(WeightWatcher300);
    fontData(WeightWatcher400);
    fontData(WeightWatcher500);
    fontData(WeightWatcher600);
    fontData(WeightWatcher700);
    fontData(WeightWatcher800);
    fontData(WeightWatcher900);
    fontData(FWFTTF);
    fontData(FWFOTF);
}
#endif // !PLATFORM(IOS_FAMILY)


#if PLATFORM(IOS_FAMILY)
static void adjustWebDocumentForFlexibleViewport(UIWebBrowserView *webBrowserView, UIWebScrollView *scrollView)
{
    // These values match MobileSafari's, see -[TabDocument _createDocumentView].
    [webBrowserView setMinimumScale:0.25f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setMaximumScale:5.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setInitialScale:UIWebViewScalesToFitScale forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setViewportSize:CGSizeMake(UIWebViewStandardViewportWidth, UIWebViewGrowsAndShrinksToFitHeight) forDocumentTypes:UIEveryDocumentMask];

    // Adjust the viewport view and viewport to have similar behavior
    // as the browser.
    [(DumpRenderTreeBrowserView *)webBrowserView setScrollingUsesUIWebScrollView:YES];
    [webBrowserView setDelegate:scrollViewResizerDelegate];

    CGRect screenBounds = [UIScreen mainScreen].bounds;
    CGRect viewportRect = CGRectMake(0, 0, screenBounds.size.width, screenBounds.size.height);

    [scrollView setBounds:viewportRect];
    [scrollView setFrame:viewportRect];

    [webBrowserView setMinimumSize:viewportRect.size];
    [webBrowserView setAutoresizes:YES];
    [webBrowserView setFrame:screenBounds];

    // This just affects text autosizing.
    [mainFrame _setVisibleSize:CGSizeMake(screenBounds.size.width, screenBounds.size.height)];
}

static void adjustWebDocumentForStandardViewport(UIWebBrowserView *webBrowserView, UIWebScrollView *scrollView)
{
    [webBrowserView setMinimumScale:1.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setMaximumScale:5.0f forDocumentTypes:UIEveryDocumentMask];
    [webBrowserView setInitialScale:1.0f forDocumentTypes:UIEveryDocumentMask];

    [(DumpRenderTreeBrowserView *)webBrowserView setScrollingUsesUIWebScrollView:NO];
    [webBrowserView setDelegate: nil];

    [scrollView setBounds:layoutTestViewportRect];
    [scrollView setFrame:layoutTestViewportRect];

    [webBrowserView setMinimumSize:layoutTestViewportRect.size];
    [webBrowserView setAutoresizes:NO];
    [webBrowserView setFrame:layoutTestViewportRect];

    // This just affects text autosizing.
    [mainFrame _setVisibleSize:CGSizeMake(layoutTestViewportRect.size.width, layoutTestViewportRect.size.height)];

}
#endif

#if !PLATFORM(IOS_FAMILY)
@interface DRTMockScroller : NSScroller
@end

@implementation DRTMockScroller

- (NSRect)rectForPart:(NSScrollerPart)partCode
{
    if (partCode != NSScrollerKnob)
        return [super rectForPart:partCode];

    NSRect frameRect = [self frame];
    NSRect bounds = [self bounds];
    BOOL isHorizontal = frameRect.size.width > frameRect.size.height;
    CGFloat trackLength = isHorizontal ? bounds.size.width : bounds.size.height;
    CGFloat minKnobSize = isHorizontal ? bounds.size.height : bounds.size.width;
    CGFloat knobLength = max(minKnobSize, static_cast<CGFloat>(round(trackLength * [self knobProportion])));
    CGFloat knobPosition = static_cast<CGFloat>((round([self doubleValue] * (trackLength - knobLength))));

    if (isHorizontal)
        return NSMakeRect(bounds.origin.x + knobPosition, bounds.origin.y, knobLength, bounds.size.height);

    return NSMakeRect(bounds.origin.x, bounds.origin.y +  + knobPosition, bounds.size.width, knobLength);
}

- (void)drawKnob
{
    if (![self isEnabled])
        return;

    NSRect knobRect = [self rectForPart:NSScrollerKnob];

    static NSColor *knobColor = [[NSColor colorWithDeviceRed:0x80 / 255.0 green:0x80 / 255.0 blue:0x80 / 255.0 alpha:1] retain];
    [knobColor set];

    NSRectFill(knobRect);
}

- (void)drawRect:(NSRect)dirtyRect
{
    static NSColor *trackColor = [[NSColor colorWithDeviceRed:0xC0 / 255.0 green:0xC0 / 255.0 blue:0xC0 / 255.0 alpha:1] retain];
    static NSColor *disabledTrackColor = [[NSColor colorWithDeviceRed:0xE0 / 255.0 green:0xE0 / 255.0 blue:0xE0 / 255.0 alpha:1] retain];

    if ([self isEnabled])
        [trackColor set];
    else
        [disabledTrackColor set];

    NSRectFill(dirtyRect);

    [self drawKnob];
}

@end

static void registerMockScrollbars()
{
    [WebDynamicScrollBarsView setCustomScrollerClass:[DRTMockScroller class]];
}
#endif

WebView *createWebViewAndOffscreenWindow()
{
#if !PLATFORM(IOS_FAMILY)
    NSRect rect = NSMakeRect(0, 0, TestRunner::viewWidth, TestRunner::viewHeight);
    WebView *webView = [[WebView alloc] initWithFrame:rect frameName:nil groupName:@"org.webkit.DumpRenderTree"];
#else
    DumpRenderTreeBrowserView *webBrowserView = [[[DumpRenderTreeBrowserView alloc] initWithFrame:layoutTestViewportRect] autorelease];
    [webBrowserView setInputViewObeysDOMFocus:YES];
    WebView *webView = [[webBrowserView webView] retain];
    [webView setGroupName:@"org.webkit.DumpRenderTree"];
#endif

    [webView setUIDelegate:uiDelegate];
    [webView setFrameLoadDelegate:frameLoadDelegate];
    [webView setEditingDelegate:editingDelegate];
    [webView setResourceLoadDelegate:resourceLoadDelegate];
    [webView _setGeolocationProvider:[MockGeolocationProvider shared]];
    [webView _setDeviceOrientationProvider:[WebDeviceOrientationProviderMock shared]];
    [webView _setNotificationProvider:[MockWebNotificationProvider shared]];

    // Register the same schemes that Safari does
    [WebView registerURLSchemeAsLocal:@"feed"];
    [WebView registerURLSchemeAsLocal:@"feeds"];
    [WebView registerURLSchemeAsLocal:@"feedsearch"];

    [[webView preferences] _setMediaRecorderEnabled:YES];

#if PLATFORM(MAC)
    [webView setWindowOcclusionDetectionEnabled:NO];
    [WebView _setFontWhitelist:fontWhitelist()];
#endif

#if !PLATFORM(IOS_FAMILY)
    [webView setContinuousSpellCheckingEnabled:YES];
    [webView setAutomaticQuoteSubstitutionEnabled:NO];
    [webView setAutomaticLinkDetectionEnabled:NO];
    [webView setAutomaticDashSubstitutionEnabled:NO];
    [webView setAutomaticTextReplacementEnabled:NO];
    [webView setAutomaticSpellingCorrectionEnabled:YES];
    [webView setGrammarCheckingEnabled:YES];

    [webView setDefersCallbacks:NO];
    [webView setInteractiveFormValidationEnabled:YES];
    [webView setValidationMessageTimerMagnification:-1];

    // To make things like certain NSViews, dragging, and plug-ins work, put the WebView a window, but put it off-screen so you don't see it.
    // Put it at -10000, -10000 in "flipped coordinates", since WebCore and the DOM use flipped coordinates.
    NSScreen *firstScreen = [[NSScreen screens] firstObject];
    NSRect windowRect = (showWebView) ? NSOffsetRect(rect, 100, 100) : NSOffsetRect(rect, -10000, [firstScreen frame].size.height - rect.size.height + 10000);
    DumpRenderTreeWindow *window = [[DumpRenderTreeWindow alloc] initWithContentRect:windowRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
    mainWindow = window;

    [window setColorSpace:[firstScreen colorSpace]];
    [window setCollectionBehavior:NSWindowCollectionBehaviorStationary];
    [[window contentView] addSubview:webView];
    if (showWebView)
        [window orderFront:nil];
    else
        [window orderBack:nil];
    [window setAutodisplay:NO];

    [window startListeningForAcceleratedCompositingChanges];
#else
    DumpRenderTreeWindow *drtWindow = [[DumpRenderTreeWindow alloc] initWithLayer:[webBrowserView layer]];
    [drtWindow setContentView:webView];
    [webBrowserView setWAKWindow:drtWindow];

    [[webView window] makeFirstResponder:[[[webView mainFrame] frameView] documentView]];

    CGRect uiWindowRect = layoutTestViewportRect;
    uiWindowRect.origin.y += [UIApp statusBarHeight];
    UIWindow *uiWindow = [[[UIWindow alloc] initWithFrame:uiWindowRect] autorelease];

    UIViewController *viewController = [[UIViewController alloc] init];
    [uiWindow setRootViewController:viewController];
    [viewController release];

    // The UIWindow and UIWebBrowserView are released when the DumpRenderTreeWindow is closed.
    drtWindow.uiWindow = uiWindow;
    drtWindow.browserView = webBrowserView;

    DumpRenderTreeWebScrollView *scrollView = [[DumpRenderTreeWebScrollView alloc] initWithFrame:layoutTestViewportRect];
    [scrollView addSubview:webBrowserView];

    [viewController.view addSubview:scrollView];
    [scrollView release];

    adjustWebDocumentForStandardViewport(webBrowserView, scrollView);
#endif

#if !PLATFORM(IOS_FAMILY)
    // For reasons that are not entirely clear, the following pair of calls makes WebView handle its
    // dynamic scrollbars properly. Without it, every frame will always have scrollbars.
    NSBitmapImageRep *imageRep = [webView bitmapImageRepForCachingDisplayInRect:[webView bounds]];
    [webView cacheDisplayInRect:[webView bounds] toBitmapImageRep:imageRep];
#else
    [[webView preferences] _setTelephoneNumberParsingEnabled:NO];

    // Initialize the global UIViews, and set the key UIWindow to be painted.
    if (!gWebBrowserView) {
        gWebBrowserView = [webBrowserView retain];
        gWebScrollView = [scrollView retain];
        gDrtWindow = [drtWindow retain];
        [uiWindow makeKeyAndVisible];
        [uiWindow retain];
    }
#endif

    [webView setMediaVolume:0];

    return webView;
}

static void destroyWebViewAndOffscreenWindow(WebView *webView)
{
    ASSERT(webView == [mainFrame webView]);
#if !PLATFORM(IOS_FAMILY)
    NSWindow *window = [webView window];
#endif
    [webView close];
    mainFrame = nil;

#if !PLATFORM(IOS_FAMILY)
    // Work around problem where registering drag types leaves an outstanding
    // "perform selector" on the window, which retains the window. It's a bit
    // inelegant and perhaps dangerous to just blow them all away, but in practice
    // it probably won't cause any trouble (and this is just a test tool, after all).
    [NSObject cancelPreviousPerformRequestsWithTarget:window];

    [window close]; // releases when closed
#else
    UIWindow *uiWindow = [gWebBrowserView window];
    [uiWindow removeFromSuperview];
    [uiWindow release];
#endif

    [webView release];
}

static NSString *libraryPathForDumpRenderTree()
{
    char* dumpRenderTreeTemp = getenv("DUMPRENDERTREE_TEMP");
    if (dumpRenderTreeTemp)
        return [[NSFileManager defaultManager] stringWithFileSystemRepresentation:dumpRenderTreeTemp length:strlen(dumpRenderTreeTemp)];
    else
        return [@"~/Library/Application Support/DumpRenderTree" stringByExpandingTildeInPath];
}

static void enableExperimentalFeatures(WebPreferences* preferences)
{
    // FIXME: SpringTimingFunction
    [preferences setGamepadsEnabled:YES];
    [preferences setLinkPreloadEnabled:YES];
    [preferences setMediaPreloadingEnabled:YES];
    // FIXME: InputEvents
    [preferences setFetchAPIKeepAliveEnabled:YES];
    [preferences setWebAnimationsEnabled:YES];
    [preferences setWebGL2Enabled:YES];
    // FIXME: AsyncFrameScrollingEnabled
    [preferences setCacheAPIEnabled:NO];
    [preferences setReadableByteStreamAPIEnabled:YES];
    [preferences setWritableStreamAPIEnabled:YES];
    preferences.encryptedMediaAPIEnabled = YES;
    [preferences setAccessibilityObjectModelEnabled:YES];
    [preferences setAriaReflectionEnabled:YES];
    [preferences setVisualViewportAPIEnabled:YES];
    [preferences setColorFilterEnabled:YES];
    [preferences setServerTimingEnabled:YES];
    [preferences setIntersectionObserverEnabled:YES];
    preferences.sourceBufferChangeTypeEnabled = YES;
    [preferences setCSSOMViewScrollingAPIEnabled:YES];
    [preferences setMediaRecorderEnabled:YES];
    [preferences setReferrerPolicyAttributeEnabled:YES];
    [preferences setLinkPreloadResponsiveImagesEnabled:YES];
    [preferences setCSSShadowPartsEnabled:YES];
}

// Called before each test.
static void resetWebPreferencesToConsistentValues()
{
    WebPreferences *preferences = [WebPreferences standardPreferences];
    enableExperimentalFeatures(preferences);

    [preferences setNeedsStorageAccessFromFileURLsQuirk: NO];
    [preferences setAllowUniversalAccessFromFileURLs:YES];
    [preferences setAllowFileAccessFromFileURLs:YES];
    [preferences setStandardFontFamily:@"Times"];
    [preferences setFixedFontFamily:@"Courier"];
    [preferences setSerifFontFamily:@"Times"];
    [preferences setSansSerifFontFamily:@"Helvetica"];
    [preferences setCursiveFontFamily:@"Apple Chancery"];
    [preferences setFantasyFontFamily:@"Papyrus"];
    [preferences setPictographFontFamily:@"Apple Color Emoji"];
    [preferences setDefaultFontSize:16];
    [preferences setDefaultFixedFontSize:13];
    [preferences setMinimumFontSize:0];
    [preferences setDefaultTextEncodingName:@"ISO-8859-1"];
    [preferences setJavaEnabled:NO];
    [preferences setJavaScriptEnabled:YES];
    [preferences setEditableLinkBehavior:WebKitEditableLinkOnlyLiveWithShiftKey];
#if !PLATFORM(IOS_FAMILY)
    [preferences setTabsToLinks:NO];
#endif
    [preferences setDOMPasteAllowed:YES];
#if !PLATFORM(IOS_FAMILY)
    [preferences setShouldPrintBackgrounds:YES];
#endif
    [preferences setCacheModel:WebCacheModelDocumentBrowser];
    [preferences setXSSAuditorEnabled:NO];
    [preferences setExperimentalNotificationsEnabled:NO];
    [preferences setPlugInsEnabled:YES];
#if !PLATFORM(IOS_FAMILY)
    [preferences setTextAreasAreResizable:YES];
#endif

    [preferences setPrivateBrowsingEnabled:NO];
    [preferences setAuthorAndUserStylesEnabled:YES];
    [preferences setShrinksStandaloneImagesToFit:YES];
    [preferences setJavaScriptCanOpenWindowsAutomatically:YES];
    [preferences setJavaScriptCanAccessClipboard:YES];
    [preferences setOfflineWebApplicationCacheEnabled:YES];
    [preferences setDeveloperExtrasEnabled:NO];
    [preferences setJavaScriptRuntimeFlags:WebKitJavaScriptRuntimeFlagsAllEnabled];
    [preferences setLoadsImagesAutomatically:YES];
    [preferences setLoadsSiteIconsIgnoringImageLoadingPreference:NO];
    [preferences setFrameFlattening:WebKitFrameFlatteningDisabled];
    [preferences setAsyncFrameScrollingEnabled:NO];
    [preferences setSpatialNavigationEnabled:NO];
    [preferences setMetaRefreshEnabled:YES];

    if (persistentUserStyleSheetLocation) {
        [preferences setUserStyleSheetLocation:[NSURL URLWithString:(__bridge NSString *)persistentUserStyleSheetLocation.get()]];
        [preferences setUserStyleSheetEnabled:YES];
    } else
        [preferences setUserStyleSheetEnabled:NO];

    [preferences setMediaPlaybackAllowsInline:YES];
    [preferences setMediaPlaybackRequiresUserGesture:NO];
    [preferences setVideoPlaybackRequiresUserGesture:NO];
    [preferences setAudioPlaybackRequiresUserGesture:NO];
    [preferences setMediaDataLoadsAutomatically:YES];
    [preferences setInvisibleAutoplayNotPermitted:NO];
    [preferences setSubpixelAntialiasedLayerTextEnabled:NO];

#if PLATFORM(IOS_FAMILY)
    // Enable the tracker before creating the first WebView will
    // cause initialization to use the correct database paths.
    [preferences setStorageTrackerEnabled:YES];
#endif

    [preferences _setTextAutosizingEnabled:NO];

    // The back/forward cache is causing problems due to layouts during transition from one page to another.
    // So, turn it off for now, but we might want to turn it back on some day.
    [preferences setUsesPageCache:NO];
    [preferences setAcceleratedCompositingEnabled:YES];
#if USE(CA)
    [preferences setCanvasUsesAcceleratedDrawing:YES];
    [preferences setAcceleratedDrawingEnabled:useAcceleratedDrawing];
#endif
    [preferences setUsePreHTML5ParserQuirks:NO];
    [preferences setAsynchronousSpellCheckingEnabled:NO];
#if !PLATFORM(IOS_FAMILY)
    ASSERT([preferences mockScrollbarsEnabled]);
#endif

    [preferences setWebAudioEnabled:YES];
    [preferences setMediaSourceEnabled:YES];
    [preferences setSourceBufferChangeTypeEnabled:YES];

    [preferences setShadowDOMEnabled:YES];
    [preferences setCustomElementsEnabled:YES];

    [preferences setDataTransferItemsEnabled:YES];
    [preferences setCustomPasteboardDataEnabled:YES];
    [preferences setDialogElementEnabled:YES];

    [preferences setWebGL2Enabled:YES];

    [preferences setDownloadAttributeEnabled:YES];
    [preferences setDirectoryUploadEnabled:YES];

    [preferences setHiddenPageDOMTimerThrottlingEnabled:NO];
    [preferences setHiddenPageCSSAnimationSuspensionEnabled:NO];

    [preferences setMediaDevicesEnabled:YES];

    [preferences setLargeImageAsyncDecodingEnabled:NO];

    [preferences setModernMediaControlsEnabled:YES];
    [preferences setResourceTimingEnabled:YES];
    [preferences setUserTimingEnabled:YES];

    [preferences setCacheAPIEnabled:NO];
    preferences.mediaCapabilitiesEnabled = YES;

    preferences.selectionAcrossShadowBoundariesEnabled = YES;

    [WebPreferences _clearNetworkLoaderSession];
    [WebPreferences _setCurrentNetworkLoaderSessionCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain];
}

static void setWebPreferencesForTestOptions(const TestOptions& options)
{
    WebPreferences *preferences = [WebPreferences standardPreferences];

    preferences.attachmentElementEnabled = options.enableAttachmentElement;
    preferences.acceleratedDrawingEnabled = options.useAcceleratedDrawing;
    preferences.menuItemElementEnabled = options.enableMenuItemElement;
    preferences.keygenElementEnabled = options.enableKeygenElement;
    preferences.modernMediaControlsEnabled = options.enableModernMediaControls;
    preferences.isSecureContextAttributeEnabled = options.enableIsSecureContextAttribute;
    preferences.inspectorAdditionsEnabled = options.enableInspectorAdditions;
    preferences.allowCrossOriginSubresourcesToAskForCredentials = options.allowCrossOriginSubresourcesToAskForCredentials;
    preferences.webAnimationsCSSIntegrationEnabled = options.enableWebAnimationsCSSIntegration;
    preferences.colorFilterEnabled = options.enableColorFilter;
    preferences.selectionAcrossShadowBoundariesEnabled = options.enableSelectionAcrossShadowBoundaries;
    preferences.webGPUEnabled = options.enableWebGPU;
    preferences.CSSLogicalEnabled = options.enableCSSLogical;
    preferences.adClickAttributionEnabled = options.adClickAttributionEnabled;
    preferences.resizeObserverEnabled = options.enableResizeObserver;
    preferences.coreMathMLEnabled = options.enableCoreMathML;
    preferences.requestIdleCallbackEnabled = options.enableRequestIdleCallback;
    preferences.asyncClipboardAPIEnabled = options.enableAsyncClipboardAPI;
    preferences.privateBrowsingEnabled = options.useEphemeralSession;
    preferences.usesPageCache = options.enablePageCache;
}

// Called once on DumpRenderTree startup.
static void setDefaultsToConsistentValuesForTesting()
{
#if PLATFORM(IOS_FAMILY)
    WebThreadLock();
#endif

    static const int NoFontSmoothing = 0;
    static const int BlueTintedAppearance = 1;

    NSString *libraryPath = libraryPathForDumpRenderTree();

    NSDictionary *dict = @{
        @"AppleKeyboardUIMode": @1,
        @"AppleAntiAliasingThreshold": @4,
        @"AppleFontSmoothing": @(NoFontSmoothing),
        @"AppleAquaColorVariant": @(BlueTintedAppearance),
        @"AppleHighlightColor": @"0.709800 0.835300 1.000000",
        @"AppleOtherHighlightColor":@"0.500000 0.500000 0.500000",
        @"AppleLanguages": @[ @"en" ],
        WebKitEnableFullDocumentTeardownPreferenceKey: @YES,
        WebKitFullScreenEnabledPreferenceKey: @YES,
        WebKitAllowsInlineMediaPlaybackPreferenceKey: @YES,
        WebKitInlineMediaPlaybackRequiresPlaysInlineAttributeKey: @NO,
        @"UseWebKitWebInspector": @YES,
#if !PLATFORM(IOS_FAMILY)
        @"NSPreferredSpellServerLanguage": @"en_US",
        @"NSUserDictionaryReplacementItems": @[],
        @"NSTestCorrectionDictionary": @{
            @"notationl": @"notational",
            @"mesage": @"message",
            @"wouldn": @"would",
            @"wellcome": @"welcome",
            @"hellolfworld": @"hello\nworld"
        },
#endif
        @"AppleScrollBarVariant": @"DoubleMax",
#if !PLATFORM(IOS_FAMILY)
        @"NSScrollAnimationEnabled": @NO,
#endif
        @"NSOverlayScrollersEnabled": @NO,
        @"AppleShowScrollBars": @"Always",
        @"NSButtonAnimationsEnabled": @NO, // Ideally, we should find a way to test animations, but for now, make sure that the dumped snapshot matches actual state.
        @"NSWindowDisplayWithRunLoopObserver": @YES, // Temporary workaround, see <rdar://problem/20351297>.
        @"AppleEnableSwipeNavigateWithScrolls": @YES,
        @"com.apple.swipescrolldirection": @1,
    };

    [[NSUserDefaults standardUserDefaults] setValuesForKeysWithDictionary:dict];

    NSDictionary *processInstanceDefaults = @{
        WebDatabaseDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"Databases"],
        WebStorageDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalStorage"],
        WebKitLocalCacheDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalCache"],
        WebKitResourceLoadStatisticsDirectoryDefaultsKey: [libraryPath stringByAppendingPathComponent:@"LocalStorage"],
    };

    [[NSUserDefaults standardUserDefaults] setVolatileDomain:processInstanceDefaults forName:NSArgumentDomain];
}

static void allocateGlobalControllers()
{
    // FIXME: We should remove these and move to the ObjC standard [Foo sharedInstance] model
    gNavigationController = [[NavigationController alloc] init];
    frameLoadDelegate = [[FrameLoadDelegate alloc] init];
    uiDelegate = [[UIDelegate alloc] init];
    editingDelegate = [[EditingDelegate alloc] init];
    resourceLoadDelegate = [[ResourceLoadDelegate alloc] init];
    policyDelegate = [[PolicyDelegate alloc] init];
    historyDelegate = [[HistoryDelegate alloc] init];
    defaultPolicyDelegate = [[DefaultPolicyDelegate alloc] init];
#if PLATFORM(IOS_FAMILY)
    scrollViewResizerDelegate = [[ScrollViewResizerDelegate alloc] init];
#endif
}

// ObjC++ doens't seem to let me pass NSObject*& sadly.
static inline void releaseAndZero(NSObject** object)
{
    [*object release];
    *object = nil;
}

static void releaseGlobalControllers()
{
    releaseAndZero(&gNavigationController);
    releaseAndZero(&frameLoadDelegate);
    releaseAndZero(&editingDelegate);
    releaseAndZero(&resourceLoadDelegate);
    releaseAndZero(&uiDelegate);
    releaseAndZero(&policyDelegate);
#if PLATFORM(IOS_FAMILY)
    releaseAndZero(&scrollViewResizerDelegate);
#endif
}

static void initializeGlobalsFromCommandLineOptions(int argc, const char *argv[])
{
    struct option options[] = {
        {"notree", no_argument, &dumpTree, NO},
        {"pixel-tests", no_argument, &dumpPixelsForAllTests, YES},
        {"tree", no_argument, &dumpTree, YES},
        {"threaded", no_argument, &threaded, YES},
        {"complex-text", no_argument, &forceComplexText, YES},
        {"accelerated-drawing", no_argument, &useAcceleratedDrawing, YES},
        {"gc-between-tests", no_argument, &gcBetweenTests, YES},
        {"no-timeout", no_argument, &useTimeoutWatchdog, NO},
        {"allowed-host", required_argument, nullptr, 'a'},
        {"allow-any-certificate-for-allowed-hosts", no_argument, &allowAnyHTTPSCertificateForAllowedHosts, YES},
        {"show-webview", no_argument, &showWebView, YES},
        {"print-test-count", no_argument, &printTestCount, YES},
        {"world-leaks", no_argument, &checkForWorldLeaks, NO},
        {nullptr, 0, nullptr, 0}
    };

    int option;
    while ((option = getopt_long(argc, (char * const *)argv, "", options, nullptr)) != -1) {
        switch (option) {
            case '?':   // unknown or ambiguous option
            case ':':   // missing argument
                exit(1);
                break;
            case 'a': // "allowed-host"
                allowedHosts.insert(optarg);
                break;
        }
    }
}

static void addTestPluginsToPluginSearchPath(const char* executablePath)
{
#if !PLATFORM(IOS_FAMILY)
    NSString *pwd = [[NSString stringWithUTF8String:executablePath] stringByDeletingLastPathComponent];
    [WebPluginDatabase setAdditionalWebPlugInPaths:[NSArray arrayWithObject:pwd]];
    [[WebPluginDatabase sharedDatabase] refresh];
#endif
}

static bool useLongRunningServerMode(int argc, const char *argv[])
{
    // This assumes you've already called getopt_long
    return (argc == optind+1 && strcmp(argv[optind], "-") == 0);
}

static bool handleControlCommand(const char* command)
{
    if (!strncmp("#CHECK FOR WORLD LEAKS", command, 22) || !strncmp("#LIST CHILD PROCESSES", command, 21)) {
        // DumpRenderTree does not support checking for world leaks or listing child processes.
        WTF::String result("\n");
        unsigned resultLength = result.length();
        printf("Content-Type: text/plain\n");
        printf("Content-Length: %u\n", resultLength);
        fwrite(result.utf8().data(), 1, resultLength, stdout);
        printf("#EOF\n");
        fprintf(stderr, "#EOF\n");
        fflush(stdout);
        fflush(stderr);
        return true;
    }
    return false;
}

static void runTestingServerLoop()
{
    // When DumpRenderTree run in server mode, we just wait around for file names
    // to be passed to us and read each in turn, passing the results back to the client
    char filenameBuffer[2048];
    unsigned testCount = 0;
    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);

        if (printTestCount) {
            ++testCount;
            printf("\nServer mode has completed %u tests.\n\n", testCount);
        }
    }
}

#if PLATFORM(IOS_FAMILY)
static BOOL overrideIsInHardwareKeyboardMode()
{
    return NO;
}
#endif

static void prepareConsistentTestingEnvironment()
{
#if !PLATFORM(IOS_FAMILY)
    poseAsClass("DumpRenderTreePasteboard", "NSPasteboard");
    poseAsClass("DumpRenderTreeEvent", "NSEvent");
#else
    poseAsClass("DumpRenderTreeEvent", "GSEvent");

    // Override the implementation of +[UIKeyboard isInHardwareKeyboardMode] to ensure that test runs are deterministic
    // regardless of whether a hardware keyboard is attached. We intentionally never restore the original implementation.
    method_setImplementation(class_getClassMethod([UIKeyboard class], @selector(isInHardwareKeyboardMode)), reinterpret_cast<IMP>(overrideIsInHardwareKeyboardMode));
#endif

    [[WebPreferences standardPreferences] setAutosaves:NO];

    // +[WebPreferences _switchNetworkLoaderToNewTestingSession] calls +[NSURLCache sharedURLCache], which initializes a default cache on disk.
    // Making the shared cache memory-only avoids touching the file system.
    RetainPtr<NSURLCache> sharedCache =
        adoptNS([[NSURLCache alloc] initWithMemoryCapacity:1024 * 1024
                                      diskCapacity:0
                                          diskPath:nil]);
    [NSURLCache setSharedURLCache:sharedCache.get()];

    [WebPreferences _switchNetworkLoaderToNewTestingSession];

#if !PLATFORM(IOS_FAMILY)
    adjustFonts();
    registerMockScrollbars();

    // The mock scrollbars setting cannot be modified after creating a view, so we have to do it now.
    [[WebPreferences standardPreferences] setMockScrollbarsEnabled:YES];
#else
    activateFontsIOS();
#endif

    allocateGlobalControllers();

#if PLATFORM(MAC)
    NSActivityOptions options = (NSActivityUserInitiatedAllowingIdleSystemSleep | NSActivityLatencyCritical) & ~(NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled);
    static id assertion = [[[NSProcessInfo processInfo] beginActivityWithOptions:options reason:@"DumpRenderTree should not be subject to process suppression"] retain];
    ASSERT_UNUSED(assertion, assertion);
#endif
}

const char crashedMessage[] = "#CRASHED\n";

void writeCrashedMessageOnFatalError(int signalCode)
{
    // Reset the default action for the signal so that we run ReportCrash(8) on pending and
    // subsequent instances of the signal.
    signal(signalCode, SIG_DFL);

    // WRITE(2) and FSYNC(2) are considered safe to call from a signal handler by SIGACTION(2).
    write(STDERR_FILENO, &crashedMessage[0], sizeof(crashedMessage) - 1);
    fsync(STDERR_FILENO);
}

void dumpRenderTree(int argc, const char *argv[])
{
    JSC::Config::configureForTesting();

#if PLATFORM(IOS_FAMILY)
    setUpIOSLayoutTestCommunication();
    [UIApplication sharedApplication].idleTimerDisabled = YES;
    [[UIScreen mainScreen] _setScale:2.0];
#endif

    signal(SIGILL, &writeCrashedMessageOnFatalError);
    signal(SIGFPE, &writeCrashedMessageOnFatalError);
    signal(SIGBUS, &writeCrashedMessageOnFatalError);
    signal(SIGSEGV, &writeCrashedMessageOnFatalError);

    initializeGlobalsFromCommandLineOptions(argc, argv);
    prepareConsistentTestingEnvironment();
    addTestPluginsToPluginSearchPath(argv[0]);

    if (forceComplexText)
        [WebView _setAlwaysUsesComplexTextCodePath:YES];

#if USE(APPKIT)
    [NSSound _setAlertType:0];
#endif

    [[NSURLCache sharedURLCache] removeAllCachedResponses];
    [WebCache empty];

    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:@"localhost"];
    [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:@"127.0.0.1"];
    if (allowAnyHTTPSCertificateForAllowedHosts) {
        for (auto& host : allowedHosts)
            [NSURLRequest setAllowsAnyHTTPSCertificate:YES forHost:[NSString stringWithUTF8String:host.c_str()]];
    }

    if (threaded)
        startJavaScriptThreads();

    if (useLongRunningServerMode(argc, argv)) {
        printSeparators = YES;
        runTestingServerLoop();
    } else {
        printSeparators = optind < argc - 1;
        for (int i = optind; i != argc; ++i)
            runTest(argv[i]);
    }

    if (threaded)
        stopJavaScriptThreads();

    destroyWebViewAndOffscreenWindow([mainFrame webView]);

    releaseGlobalControllers();

#if !PLATFORM(IOS_FAMILY)
    [DumpRenderTreePasteboard releaseLocalPasteboards];
#endif

    // FIXME: This should be moved onto TestRunner and made into a HashSet
    if (disallowedURLs) {
        CFRelease(disallowedURLs);
        disallowedURLs = 0;
    }

#if PLATFORM(IOS_FAMILY)
    tearDownIOSLayoutTestCommunication();
#endif
}

#if PLATFORM(IOS_FAMILY)
static int _argc;
static const char **_argv;

@implementation DumpRenderTree

- (void)_runDumpRenderTree
{
    dumpRenderTree(_argc, _argv);
}

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
    [self performSelectorOnMainThread:@selector(_runDumpRenderTree) withObject:nil waitUntilDone:NO];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    RELEASE_ASSERT_NOT_REACHED();
}

- (void)_webThreadEventLoopHasRun
{
    ASSERT(!WebThreadIsCurrent());
    _hasFlushedWebThreadRunQueue = YES;
}

- (void)_webThreadInvoked
{
    ASSERT(WebThreadIsCurrent());
    dispatch_async(dispatch_get_main_queue(), ^{
        [self _webThreadEventLoopHasRun];
    });
}

// The test can end in response to a delegate callback while there are still methods queued on the Web Thread.
// If we do not ensure the Web Thread has been run, the callback can be done on a WebView that no longer exists.
// To avoid this, _waitForWebThread dispatches a call to the WebThread event loop, actively processing the delegate
// callbacks in the main thread while waiting for the call to be invoked on the Web Thread.
- (void)_waitForWebThread
{
    ASSERT(!WebThreadIsCurrent());
    _hasFlushedWebThreadRunQueue = NO;
    WebThreadRun(^{
        [self _webThreadInvoked];
    });
    while (!_hasFlushedWebThreadRunQueue) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
        }
    }
}

@end
#endif

static bool returningFromMain = false;

void atexitFunction()
{
    if (returningFromMain)
        return;

    NSLog(@"DumpRenderTree is exiting unexpectedly. Generating a crash log.");
    __builtin_trap();
}

int DumpRenderTreeMain(int argc, const char *argv[])
{
    atexit(atexitFunction);

    WTF::setProcessPrivileges(allPrivileges());
    WebCore::NetworkStorageSession::permitProcessToUseCookieAPI(true);

#if PLATFORM(IOS_FAMILY)
    _UIApplicationLoadWebKit();
#endif

    @autoreleasepool {
        setDefaultsToConsistentValuesForTesting(); // Must be called before NSApplication initialization.

#if !PLATFORM(IOS_FAMILY)
        [DumpRenderTreeApplication sharedApplication]; // Force AppKit to init itself

        dumpRenderTree(argc, argv);
#else
        _argc = argc;
        _argv = argv;
        UIApplicationMain(argc, (char**)argv, @"DumpRenderTree", @"DumpRenderTree");
#endif

        [WebCoreStatistics garbageCollectJavaScriptObjects];
        [WebCoreStatistics emptyCache]; // Otherwise SVGImages trigger false positives for Frame/Node counts
        JSC::finalizeStatsAtEndOfTesting();
    }

    returningFromMain = true;
    return 0;
}

static NSInteger compareHistoryItems(id item1, id item2, void *context)
{
    return [[item1 target] caseInsensitiveCompare:[item2 target]];
}

static NSData *dumpAudio()
{
    const vector<char>& dataVector = gTestRunner->audioResult();

    NSData *data = [NSData dataWithBytes:dataVector.data() length:dataVector.size()];
    return data;
}

static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current)
{
    int start = 0;
    if (current) {
        printf("curr->");
        start = 6;
    }
    for (int i = start; i < indent; i++)
        putchar(' ');

    NSString *urlString = [item URLString];
    if ([[NSURL URLWithString:urlString] isFileURL]) {
        NSRange range = [urlString rangeOfString:@"/LayoutTests/"];
        urlString = [@"(file test):" stringByAppendingString:[urlString substringFromIndex:(range.length + range.location)]];
    }

    printf("%s", [urlString UTF8String]);
    NSString *target = [item target];
    if (target && [target length] > 0)
        printf(" (in frame \"%s\")", [target UTF8String]);
    if ([item isTargetItem])
        printf("  **nav target**");
    putchar('\n');
    NSArray *kids = [item children];
    if (kids) {
        // must sort to eliminate arbitrary result ordering which defeats reproducible testing
        kids = [kids sortedArrayUsingFunction:&compareHistoryItems context:nil];
        for (unsigned i = 0; i < [kids count]; i++)
            dumpHistoryItem([kids objectAtIndex:i], indent+4, NO);
    }
}

static void dumpFrameScrollPosition(WebFrame *f)
{
    WebScriptObject* scriptObject = [f windowObject];
    NSPoint scrollPosition = NSMakePoint(
        [[scriptObject valueForKey:@"pageXOffset"] floatValue],
        [[scriptObject valueForKey:@"pageYOffset"] floatValue]);
    if (ABS(scrollPosition.x) > 0.00000001 || ABS(scrollPosition.y) > 0.00000001) {
        if ([f parentFrame] != nil)
            printf("frame '%s' ", [[f name] UTF8String]);
        printf("scrolled to %.f,%.f\n", scrollPosition.x, scrollPosition.y);
    }

    if (gTestRunner->dumpChildFrameScrollPositions()) {
        NSArray *kids = [f childFrames];
        if (kids)
            for (unsigned i = 0; i < [kids count]; i++)
                dumpFrameScrollPosition([kids objectAtIndex:i]);
    }
}

static NSString *dumpFramesAsText(WebFrame *frame)
{
    DOMDocument *document = [frame DOMDocument];
    DOMElement *documentElement = [document documentElement];

    if (!documentElement)
        return @"";

    NSMutableString *result = [[[NSMutableString alloc] init] autorelease];

    // Add header for all but the main frame.
    if ([frame parentFrame])
        result = [NSMutableString stringWithFormat:@"\n--------\nFrame: '%@'\n--------\n", [frame name]];

    NSString *innerText = [documentElement innerText];
    // We use WKStringGetUTF8CStringNonStrict() to convert innerText to a WK String since
    // WKStringGetUTF8CStringNonStrict() can handle dangling surrogates and the NSString
    // conversion methods cannot. After the conversion to a buffer, we turn that buffer into
    // a CFString via fromUTF8WithLatin1Fallback().createCFString() which can be appended to
    // the result without any conversion.
    WKRetainPtr<WKStringRef> stringRef = adoptWK(WKStringCreateWithCFString((__bridge CFStringRef)innerText));
    size_t bufferSize = WKStringGetMaximumUTF8CStringSize(stringRef.get());
    auto buffer = makeUniqueArray<char>(bufferSize);
    size_t stringLength = WKStringGetUTF8CStringNonStrict(stringRef.get(), buffer.get(), bufferSize);
    [result appendFormat:@"%@\n", String::fromUTF8WithLatin1Fallback(buffer.get(), stringLength - 1).createCFString().get()];

    if (gTestRunner->dumpChildFramesAsText()) {
        NSArray *kids = [frame childFrames];
        if (kids) {
            for (unsigned i = 0; i < [kids count]; i++)
                [result appendString:dumpFramesAsText([kids objectAtIndex:i])];
        }
    }

    return result;
}

static NSData *dumpFrameAsPDF(WebFrame *frame)
{
#if !PLATFORM(IOS_FAMILY)
    if (!frame)
        return nil;

    // Sadly we have to dump to a file and then read from that file again
    // +[NSPrintOperation PDFOperationWithView:insideRect:] requires a rect and prints to a single page
    // likewise +[NSView dataWithPDFInsideRect:] also prints to a single continuous page
    // The goal of this function is to test "real" printing across multiple pages.
    // FIXME: It's possible there might be printing SPI to let us print a multi-page PDF to an NSData object
    NSString *path = [libraryPathForDumpRenderTree() stringByAppendingPathComponent:@"test.pdf"];

    NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[[NSPrintInfo sharedPrintInfo] dictionary]];
    [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition];
    [printInfoDict setObject:path forKey:NSPrintSavePath];

    NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict];
    [printInfo setHorizontalPagination:NSAutoPagination];
    [printInfo setVerticalPagination:NSAutoPagination];
    [printInfo setVerticallyCentered:NO];

    NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:[frame frameView] printInfo:printInfo];
    [printOperation setShowPanels:NO];
    [printOperation runOperation];

    [printInfo release];

    NSData *pdfData = [NSData dataWithContentsOfFile:path];
    [[NSFileManager defaultManager] removeFileAtPath:path handler:nil];

    return pdfData;
#else
    return nil;
#endif
}

static void dumpBackForwardListForWebView(WebView *view)
{
    printf("\n============== Back Forward List ==============\n");
    WebBackForwardList *bfList = [view backForwardList];

    // 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
    NSMutableArray *itemsToPrint = [[NSMutableArray alloc] init];
    for (int i = [bfList forwardListCount]; i > 0; i--) {
        WebHistoryItem *item = [bfList itemAtIndex:i];
        // something is wrong if the item from the last test is in the forward part of the b/f list
        assert(item != prevTestBFItem);
        [itemsToPrint addObject:item];
    }

    assert([bfList currentItem] != prevTestBFItem);
    [itemsToPrint addObject:[bfList currentItem]];
    int currentItemIndex = [itemsToPrint count] - 1;

    for (int i = -1; i >= -[bfList backListCount]; i--) {
        WebHistoryItem *item = [bfList itemAtIndex:i];
        if (item == prevTestBFItem)
            break;
        [itemsToPrint addObject:item];
    }

    for (int i = [itemsToPrint count]-1; i >= 0; i--)
        dumpHistoryItem([itemsToPrint objectAtIndex:i], 8, i == currentItemIndex);

    [itemsToPrint release];
    printf("===============================================\n");
}

#if !PLATFORM(IOS_FAMILY)
static void changeWindowScaleIfNeeded(const char* testPathOrUR)
{
    WTF::String localPathOrUrl = String(testPathOrUR);
    float currentScaleFactor = [[[mainFrame webView] window] backingScaleFactor];
    float requiredScaleFactor = 1;
    if (localPathOrUrl.containsIgnoringASCIICase("/hidpi-3x-"))
        requiredScaleFactor = 3;
    else if (localPathOrUrl.containsIgnoringASCIICase("/hidpi-"))
        requiredScaleFactor = 2;
    if (currentScaleFactor == requiredScaleFactor)
        return;
    // When the new scale factor is set on the window first, WebView doesn't see it as a new scale and stops propagating the behavior change to WebCore::Page.
    gTestRunner->setBackingScaleFactor(requiredScaleFactor);
    NSWindow *window = [[mainFrame webView] window];
    if ([window respondsToSelector:@selector(_setWindowResolution:)])
        [window _setWindowResolution:requiredScaleFactor];
    else
        [window _setWindowResolution:requiredScaleFactor displayIfChanged:YES];
}
#endif

static void sizeWebViewForCurrentTest()
{
    [uiDelegate resetWindowOrigin];

    // W3C SVG tests expect to be 480x360
    bool isSVGW3CTest = (gTestRunner->testURL().find("svg/W3C-SVG-1.1") != string::npos);
    NSSize frameSize = isSVGW3CTest ? NSMakeSize(TestRunner::w3cSVGViewWidth, TestRunner::w3cSVGViewHeight) : NSMakeSize(TestRunner::viewWidth, TestRunner::viewHeight);
    [[mainFrame webView] setFrameSize:frameSize];
    [[mainFrame frameView] setFrame:NSMakeRect(0, 0, frameSize.width, frameSize.height)];
}

static const char *methodNameStringForFailedTest()
{
    const char *errorMessage;
    if (gTestRunner->dumpAsText())
        errorMessage = "[documentElement innerText]";
    else if (gTestRunner->dumpDOMAsWebArchive())
        errorMessage = "[[mainFrame DOMDocument] webArchive]";
    else if (gTestRunner->dumpSourceAsWebArchive())
        errorMessage = "[[mainFrame dataSource] webArchive]";
    else
        errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";

    return errorMessage;
}

static void dumpBackForwardListForAllWindows()
{
    for (NSWindow *window in [DumpRenderTreeWindow openWindows]) {
#if !PLATFORM(IOS_FAMILY)
        WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
#else
        ASSERT([[window contentView] isKindOfClass:[WebView class]]);
        WebView *webView = (WebView *)[window contentView];
#endif
        dumpBackForwardListForWebView(webView);
    }
}

static void invalidateAnyPreviousWaitToDumpWatchdog()
{
    if (waitToDumpWatchdog) {
        CFRunLoopTimerInvalidate(waitToDumpWatchdog);
        CFRelease(waitToDumpWatchdog);
        waitToDumpWatchdog = 0;
    }
}

void setWaitToDumpWatchdog(CFRunLoopTimerRef timer)
{
    ASSERT(timer);
    ASSERT(shouldSetWaitToDumpWatchdog());
    waitToDumpWatchdog = timer;
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes);
}

bool shouldSetWaitToDumpWatchdog()
{
    return !waitToDumpWatchdog && useTimeoutWatchdog;
}

static void updateDisplay()
{
    WebView *webView = [mainFrame webView];
#if PLATFORM(IOS_FAMILY)
    [gWebBrowserView layoutIfNeeded]; // Re-enables tile painting, which was disabled when committing the frame load.
    [gDrtWindow layoutTilesNow];
    [webView _flushCompositingChanges];
#else
    if ([webView _isUsingAcceleratedCompositing])
        [webView display];
    else
        [webView displayIfNeeded];
#endif
}

void dump()
{
#if PLATFORM(IOS_FAMILY)
    WebThreadLock();
#endif

    if (done)
        return;

    updateDisplay();

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

    if (dumpTree) {
        NSString *resultString = nil;
        NSData *resultData = nil;
        NSString *resultMimeType = @"text/plain";

        if ([[[mainFrame dataSource] _responseMIMEType] isEqualToString:@"text/plain"]) {
            gTestRunner->setDumpAsText(true);
            gTestRunner->setGeneratePixelResults(false);
        }
        if (gTestRunner->dumpAsAudio()) {
            resultData = dumpAudio();
            resultMimeType = @"audio/wav";
        } else if (gTestRunner->dumpAsText()) {
            resultString = dumpFramesAsText(mainFrame);
        } else if (gTestRunner->dumpAsPDF()) {
            resultData = dumpFrameAsPDF(mainFrame);
            resultMimeType = @"application/pdf";
        } else if (gTestRunner->dumpDOMAsWebArchive()) {
            WebArchive *webArchive = [[mainFrame DOMDocument] webArchive];
            resultString = CFBridgingRelease(WebCoreTestSupport::createXMLStringFromWebArchiveData((__bridge CFDataRef)[webArchive data]));
            resultMimeType = @"application/x-webarchive";
        } else if (gTestRunner->dumpSourceAsWebArchive()) {
            WebArchive *webArchive = [[mainFrame dataSource] webArchive];
            resultString = CFBridgingRelease(WebCoreTestSupport::createXMLStringFromWebArchiveData((__bridge CFDataRef)[webArchive data]));
            resultMimeType = @"application/x-webarchive";
        } else if (gTestRunner->isPrinting())
            resultString = [mainFrame renderTreeAsExternalRepresentationForPrinting];
        else
            resultString = [mainFrame renderTreeAsExternalRepresentationWithOptions:gTestRunner->renderTreeDumpOptions()];

        if (resultString && !resultData)
            resultData = [resultString dataUsingEncoding:NSUTF8StringEncoding];

        printf("Content-Type: %s\n", [resultMimeType UTF8String]);

        WTF::FastMallocStatistics mallocStats = WTF::fastMallocStatistics();
        printf("DumpMalloc: %li\n", mallocStats.committedVMBytes);

        if (gTestRunner->dumpAsAudio())
            printf("Content-Length: %lu\n", static_cast<unsigned long>([resultData length]));

        if (resultData) {
            fwrite([resultData bytes], 1, [resultData length], stdout);

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

            if (gTestRunner->dumpBackForwardList())
                dumpBackForwardListForAllWindows();
        } else
            printf("ERROR: nil result from %s", methodNameStringForFailedTest());

        // Stop the watchdog thread before we leave this test to make sure it doesn't
        // fire in between tests causing the next test to fail.
        // This is a speculative fix for: https://bugs.webkit.org/show_bug.cgi?id=32339
        invalidateAnyPreviousWaitToDumpWatchdog();

        if (printSeparators)
            puts("#EOF");       // terminate the content block
    }

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

    puts("#EOF");   // terminate the (possibly empty) pixels block
    fflush(stdout);

    done = YES;
    CFRunLoopStop(CFRunLoopGetMain());
}

static bool shouldLogFrameLoadDelegates(const char* pathOrURL)
{
    return strstr(pathOrURL, "loading/") && !strstr(pathOrURL, "://localhost");
}

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

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

static bool shouldEnableDeveloperExtras(const char* pathOrURL)
{
    return true;
}

#if PLATFORM(IOS_FAMILY)
static bool shouldMakeViewportFlexible(const char* pathOrURL)
{
    return strstr(pathOrURL, "viewport/") && !strstr(pathOrURL, "visual-viewport/");
}
#endif

static bool shouldUseEphemeralSession(const char* pathOrURL)
{
    return strstr(pathOrURL, "w3c/IndexedDB-private-browsing");
}

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

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

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

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

    WebView *webView = [mainFrame webView];

#if PLATFORM(IOS_FAMILY)
    adjustWebDocumentForStandardViewport(gWebBrowserView, gWebScrollView);
    [webView _setAllowsMessaging:YES];
#endif
    [webView setEditable:NO];
    [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES];
    [webView makeTextStandardSize:nil];
    [webView resetPageZoom:nil];
    [webView _scaleWebView:1.0 atOrigin:NSZeroPoint];
#if !PLATFORM(IOS_FAMILY)
    [webView _setCustomBackingScaleFactor:0];
#endif
    [webView setTabKeyCyclesThroughElements:YES];
    [webView setPolicyDelegate:defaultPolicyDelegate];
    [policyDelegate setPermissive:NO];
    [policyDelegate setControllerToNotifyDone:0];
    [uiDelegate resetToConsistentStateBeforeTesting:options];
    [frameLoadDelegate resetToConsistentState];
    [webView _clearMainFrameName];
    [[webView undoManager] removeAllActions];
    [WebView _removeAllUserContentFromGroup:[webView groupName]];
#if !PLATFORM(IOS_FAMILY)
    [[webView window] setAutodisplay:NO];
#endif
    [webView setTracksRepaints:NO];

    [WebCache clearCachedCredentials];

    resetWebPreferencesToConsistentValues();
    setWebPreferencesForTestOptions(options);
#if PLATFORM(MAC)
    [webView setWantsLayer:options.layerBackedWebView];
#endif

    TestRunner::setSerializeHTTPLoads(false);
    TestRunner::setAllowsAnySSLCertificate(false);

    setlocale(LC_ALL, "");

    ASSERT(gTestRunner);
    gTestRunner->resetPageVisibility();
    // In the case that a test using the chrome input field failed, be sure to clean up for the next test.
    gTestRunner->removeChromeInputField();

    WebCoreTestSupport::resetInternalsObject([mainFrame globalContext]);

#if !PLATFORM(IOS_FAMILY)
    if (WebCore::Frame* frame = [webView _mainCoreFrame])
        WebCoreTestSupport::clearWheelEventTestMonitor(*frame);
#endif

#if !PLATFORM(IOS_FAMILY)
    [webView setContinuousSpellCheckingEnabled:YES];
    [webView setAutomaticQuoteSubstitutionEnabled:NO];
    [webView setAutomaticLinkDetectionEnabled:NO];
    [webView setAutomaticDashSubstitutionEnabled:NO];
    [webView setAutomaticTextReplacementEnabled:NO];
    [webView setAutomaticSpellingCorrectionEnabled:YES];
    [webView setGrammarCheckingEnabled:YES];

    [WebView _setUsesTestModeFocusRingColor:YES];
#endif
    [WebView _resetOriginAccessWhitelists];

    [[MockGeolocationProvider shared] stopTimer];
    [[MockWebNotificationProvider shared] reset];

#if !PLATFORM(IOS_FAMILY)
    // Clear the contents of the general pasteboard
    [[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
#endif

    WebCoreTestSupport::setAdditionalSupportedImageTypesForTesting(options.additionalSupportedImageTypes.c_str());

    [mainFrame _clearOpener];

#if PLATFORM(MAC)
    [LayoutTestSpellChecker uninstallAndReset];
#endif

    resetAccumulatedLogs();
    WebCoreTestSupport::initializeLogChannelsIfNecessary();
}

#if PLATFORM(IOS_FAMILY)
// Work around <rdar://problem/9909073> WebKit's method of calling delegates on
// the main thread is not thread safe. If the web thread is attempting to call
// out to a delegate method on the main thread, we want to spin the main thread
// run loop until the delegate method completes before taking the web thread
// lock to prevent potentially re-entering WebCore.
static void WebThreadLockAfterDelegateCallbacksHaveCompleted()
{
    dispatch_semaphore_t delegateSemaphore = dispatch_semaphore_create(0);
    WebThreadRun(^{
        dispatch_semaphore_signal(delegateSemaphore);
    });

    while (dispatch_semaphore_wait(delegateSemaphore, DISPATCH_TIME_NOW)) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];
        }
    }

    WebThreadLock();

    dispatch_release(delegateSemaphore);
}
#endif

static NSURL *computeTestURL(NSString *pathOrURLString, NSString **relativeTestPath)
{
    *relativeTestPath = nil;

    if ([pathOrURLString hasPrefix:@"http://"] || [pathOrURLString hasPrefix:@"https://"] || [pathOrURLString hasPrefix:@"file://"])
        return [NSURL URLWithString:pathOrURLString];

    NSString *absolutePath = [[[NSURL fileURLWithPath:pathOrURLString] absoluteURL] path];

    NSRange layoutTestsRange = [absolutePath rangeOfString:@"/LayoutTests/"];
    if (layoutTestsRange.location == NSNotFound)
        return [NSURL fileURLWithPath:absolutePath];

    *relativeTestPath = [absolutePath substringFromIndex:NSMaxRange(layoutTestsRange)];
    return [NSURL fileURLWithPath:absolutePath];
}

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

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

    NSString *pathOrURLString = [NSString stringWithUTF8String:pathOrURL.c_str()];
    if (!pathOrURLString) {
        fprintf(stderr, "Failed to parse \"%s\" as UTF-8\n", pathOrURL.c_str());
        return;
    }

    NSString *testPath;
    NSURL *url = computeTestURL(pathOrURLString, &testPath);
    if (!url) {
        fprintf(stderr, "Failed to parse \"%s\" as a URL\n", pathOrURL.c_str());
        return;
    }
    if (!testPath)
        testPath = [url absoluteString];

    NSString *informationString = [@"CRASHING TEST: " stringByAppendingString:testPath];
    WebKit::setCrashReportApplicationSpecificInformation((__bridge CFStringRef)informationString);

    TestOptions options { [url isFileURL] ? [url fileSystemRepresentation] : pathOrURL, command.absolutePath };

    if (!mainFrameTestOptions || !options.webViewIsCompatibleWithOptions(mainFrameTestOptions.value())) {
        if (mainFrame)
            destroyWebViewAndOffscreenWindow([mainFrame webView]);
        WebView *pristineWebView = createWebViewAndOffscreenWindow();
        mainFrame = [pristineWebView mainFrame];
    }
    mainFrameTestOptions = options;

    const char* testURL([[url absoluteString] UTF8String]);
    gTestRunner = TestRunner::create(testURL, command.expectedPixelHash);
    gTestRunner->setAllowedHosts(allowedHosts);
    gTestRunner->setCustomTimeout(command.timeout);
    gTestRunner->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr || options.dumpJSConsoleLogInStdErr);

    resetWebViewToConsistentStateBeforeTesting(options);

#if !PLATFORM(IOS_FAMILY)
    changeWindowScaleIfNeeded(testURL);
#endif

    topLoadingFrame = nil;
#if !PLATFORM(IOS_FAMILY)
    ASSERT(!draggingInfo); // the previous test should have called eventSender.mouseUp to drop!
    releaseAndZero(&draggingInfo);
#endif
    done = NO;

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

    gTestRunner->clearAllDatabases();

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

    if (shouldLogHistoryDelegates(pathOrURL.c_str()))
        [[mainFrame webView] setHistoryDelegate:historyDelegate];
    else
        [[mainFrame webView] setHistoryDelegate:nil];

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

#if PLATFORM(IOS_FAMILY)
    if (shouldMakeViewportFlexible(pathOrURL.c_str()))
        adjustWebDocumentForFlexibleViewport(gWebBrowserView, gWebScrollView);
#endif

    if (shouldUseEphemeralSession(pathOrURL.c_str()))
        [[[mainFrame webView] preferences] setPrivateBrowsingEnabled:YES];

    if ([WebHistory optionalSharedHistory])
        [WebHistory setOptionalSharedHistory:nil];

    lastMousePosition = NSZeroPoint;
    lastClickPosition = NSZeroPoint;

    [prevTestBFItem release];
    prevTestBFItem = [[[[mainFrame webView] backForwardList] currentItem] retain];

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

    bool ignoreWebCoreNodeLeaks = shouldIgnoreWebCoreNodeLeaks(testURL);
    if (ignoreWebCoreNodeLeaks)
        [WebCoreStatistics startIgnoringWebCoreNodeLeaks];

    @autoreleasepool {
        [mainFrame loadRequest:[NSURLRequest requestWithURL:url]];
    }

    while (!done) {
        @autoreleasepool {
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
        }
    }

#if PLATFORM(IOS_FAMILY)
    [(DumpRenderTree *)UIApp _waitForWebThread];
    WebThreadLockAfterDelegateCallbacksHaveCompleted();
#endif

    @autoreleasepool {
        [EventSendingController clearSavedEvents];
        [[mainFrame webView] setSelectedDOMRange:nil affinity:NSSelectionAffinityDownstream];

        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.
        if (shouldEnableDeveloperExtras(pathOrURL.c_str())) {
            gTestRunner->closeWebInspector();
            gTestRunner->setDeveloperExtrasEnabled(false);
        }

#if PLATFORM(MAC)
        // Make sure the WebView is parented, since the test may have unparented it.
        WebView *webView = [mainFrame webView];
        if (![webView superview])
            [[mainWindow contentView] addSubview:webView];
#endif

        if (gTestRunner->closeRemainingWindowsWhenComplete()) {
            NSArray* array = [DumpRenderTreeWindow openWindows];

            unsigned count = [array count];
            for (unsigned i = 0; i < count; i++) {
                NSWindow *window = [array objectAtIndex:i];

                // Don't try to close the main window
                if (window == [[mainFrame webView] window])
                    continue;

#if !PLATFORM(IOS_FAMILY)
                WebView *webView = [[[window contentView] subviews] objectAtIndex:0];
#else
                ASSERT([[window contentView] isKindOfClass:[WebView class]]);
                WebView *webView = (WebView *)[window contentView];
#endif

                [webView close];
                [window close];
            }
        }

        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.
        [mainFrame loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@""]]];
    }

    // We should only have our main window left open when we're done
    ASSERT(CFArrayGetCount(openWindowsRef) == 1);
    ASSERT(CFArrayGetValueAtIndex(openWindowsRef, 0) == (__bridge CFTypeRef)[[mainFrame webView] window]);

    gTestRunner->cleanup();
    gTestRunner = nullptr;

#if PLATFORM(MAC)
    [DumpRenderTreeDraggingInfo clearAllFilePromiseReceivers];
#endif

    if (ignoreWebCoreNodeLeaks)
        [WebCoreStatistics stopIgnoringWebCoreNodeLeaks];

    if (gcBetweenTests)
        [WebCoreStatistics garbageCollectJavaScriptObjects];
    
    JSC::waitForVMDestruction();

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

void displayWebView()
{
#if !PLATFORM(IOS_FAMILY)
    WebView *webView = [mainFrame webView];
    [webView display];
#else
    [gDrtWindow layoutTilesNow];
    [gDrtWindow setNeedsDisplayInRect:[gDrtWindow frame]];
    [CATransaction flush];
#endif
}

void displayAndTrackRepaintsWebView()
{
    displayWebView();
#if !PLATFORM(IOS_FAMILY)
    // FIXME: Tracking repaints is not specific to Mac. We should enable such support on iOS.
    WebView *webView = [mainFrame webView];
    [webView setTracksRepaints:YES];
    [webView resetTrackedRepaints];
#endif
}

#if !PLATFORM(IOS_FAMILY)
@implementation DumpRenderTreeEvent

+ (NSPoint)mouseLocation
{
    return [[[mainFrame webView] window] convertBaseToScreen:lastMousePosition];
}

@end

@implementation DumpRenderTreeApplication

- (BOOL)isRunning
{
    // <rdar://problem/7686123> Java plug-in freezes unless NSApplication is running
    return YES;
}

@end
#endif
