/*
 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2008 Alp Toker <alp@nuanti.com>
 * Copyright (C) 2009 Jan Alonzo <jmalonzo@gmail.com>
 * Copyright (C) 2010, 2011 Igalia S.L.
 *
 * 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 Computer, 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 "AccessibilityController.h"
#include "EditingCallbacks.h"
#include "EventSender.h"
#include "GCController.h"
#include "GOwnPtr.h"
#include "LayoutTestController.h"
#include "PixelDumpSupport.h"
#include "PlainTextController.h"
#include "TextInputController.h"
#include "WebCoreSupport/DumpRenderTreeSupportGtk.h"
#include "WorkQueue.h"
#include "WorkQueueItem.h"
#include <JavaScriptCore/JavaScript.h>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <getopt.h>
#include <gtk/gtk.h>
#include <webkit/webkit.h>
#include <wtf/Assertions.h>

#if PLATFORM(X11)
#include <fontconfig/fontconfig.h>
#endif


using namespace std;

extern "C" {
// This API is not yet public.
extern G_CONST_RETURN gchar* webkit_web_history_item_get_target(WebKitWebHistoryItem*);
extern gboolean webkit_web_history_item_is_target_item(WebKitWebHistoryItem*);
extern GList* webkit_web_history_item_get_children(WebKitWebHistoryItem*);
extern void webkit_web_settings_add_extra_plugin_directory(WebKitWebView* view, const gchar* directory);
extern gchar* webkit_web_frame_get_response_mime_type(WebKitWebFrame* frame);
}

volatile bool done;
static bool printSeparators;
static int dumpPixels;
static int dumpTree = 1;

AccessibilityController* axController = 0;
RefPtr<LayoutTestController> gLayoutTestController;
static GCController* gcController = 0;
static WebKitWebView* webView;
static GtkWidget* window;
static GtkWidget* container;
static GtkWidget* webInspectorWindow;
WebKitWebFrame* mainFrame = 0;
WebKitWebFrame* topLoadingFrame = 0;
guint waitToDumpWatchdog = 0;
bool waitForPolicy = false;

// This is a list of opened webviews
GSList* webViewList = 0;

// current b/f item at the end of the previous test
static WebKitWebHistoryItem* prevTestBFItem = NULL;

const unsigned historyItemIndent = 8;

static void runTest(const string& testPathOrURL);

static bool shouldLogFrameLoadDelegates(const string& pathOrURL)
{
    return pathOrURL.find("loading/") != string::npos;
}

static bool shouldOpenWebInspector(const string& pathOrURL)
{
    return pathOrURL.find("inspector/") != string::npos;
}

static bool shouldDumpAsText(const string& pathOrURL)
{
    return pathOrURL.find("dumpAsText/") != string::npos;
}

static bool shouldEnableDeveloperExtras(const string& pathOrURL)
{
    return true;
}

void dumpFrameScrollPosition(WebKitWebFrame* frame)
{

}

void displayWebView()
{
    gtk_widget_queue_draw(GTK_WIDGET(webView));
}

static void appendString(gchar*& target, gchar* string)
{
    gchar* oldString = target;
    target = g_strconcat(target, string, NULL);
    g_free(oldString);
}

static void initializeGtkFontSettings(const char* testURL)
{
    GtkSettings* settings = gtk_settings_get_default();
    if (!settings)
        return;
    g_object_set(settings,
                 "gtk-xft-dpi", 98304, // This is 96 * 1024 or 96 DPI according to the GTK+ docs.
                 "gtk-xft-antialias", 1,
                 "gtk-xft-hinting", 0,
                 "gtk-font-name", "Liberation Sans 12",
                 NULL);
    gdk_screen_set_resolution(gdk_screen_get_default(), 96.0);

    // One test needs subpixel anti-aliasing turned on, but generally we
    // want all text in other tests to use to grayscale anti-aliasing.
    if (testURL && strstr(testURL, "xsettings_antialias_settings.html"))
        g_object_set(settings, "gtk-xft-rgba", "rgb", NULL);
    else
        g_object_set(settings, "gtk-xft-rgba", "none", NULL);
}

static void initializeFonts(const char* testURL = 0)
{
#if PLATFORM(X11)
    initializeGtkFontSettings(testURL);

    FcInit();

    // If a test resulted a font being added or removed via the @font-face rule, then
    // we want to reset the FontConfig configuration to prevent it from affecting other tests.
    static int numFonts = 0;
    FcFontSet* appFontSet = FcConfigGetFonts(0, FcSetApplication);
    if (appFontSet && numFonts && appFontSet->nfont == numFonts)
        return;

    // Load our configuration file, which sets up proper aliases for family
    // names like sans, serif and monospace.
    FcConfig* config = FcConfigCreate();
    GOwnPtr<gchar> fontConfigFilename(g_build_filename(FONTS_CONF_DIR, "fonts.conf", NULL));
    if (!FcConfigParseAndLoad(config, reinterpret_cast<FcChar8*>(fontConfigFilename.get()), true))
        g_error("Couldn't load font configuration file from: %s", fontConfigFilename.get());

    static const char *const fontPaths[][2] = {
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-BoldItalic.ttf",
          "/usr/share/fonts/liberation/LiberationMono-BoldItalic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Bold.ttf",
          "/usr/share/fonts/liberation/LiberationMono-Bold.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Italic.ttf",
          "/usr/share/fonts/liberation/LiberationMono-Italic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationMono-Regular.ttf",
          "/usr/share/fonts/liberation/LiberationMono-Regular.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-BoldItalic.ttf",
          "/usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Bold.ttf",
          "/usr/share/fonts/liberation/LiberationSans-Bold.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Italic.ttf",
          "/usr/share/fonts/liberation/LiberationSans-Italic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSans-Regular.ttf",
          "/usr/share/fonts/liberation/LiberationSans-Regular.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-BoldItalic.ttf",
          "/usr/share/fonts/liberation/LiberationSerif-BoldItalic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Bold.ttf",
          "/usr/share/fonts/liberation/LiberationSerif-Bold.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Italic.ttf",
          "/usr/share/fonts/liberation/LiberationSerif-Italic.ttf", },
        { "/usr/share/fonts/truetype/ttf-liberation/LiberationSerif-Regular.ttf",
          "/usr/share/fonts/liberation/LiberationSerif-Regular.ttf", },
        { "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf",
          "/usr/share/fonts/dejavu/DejaVuSans.ttf", },
        { "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf",
          "/usr/share/fonts/dejavu/DejaVuSerif.ttf", },

        // MathML tests require the STIX fonts.
        { "/usr/share/fonts/opentype/stix/STIXGeneral.otf",
          "/usr/share/fonts/stix/STIXGeneral.otf" },
        { "/usr/share/fonts/opentype/stix/STIXGeneralBolIta.otf",
          "/usr/share/fonts/stix/STIXGeneralBolIta.otf" },
        { "/usr/share/fonts/opentype/stix/STIXGeneralBol.otf",
          "/usr/share/fonts/stix/STIXGeneralBol.otf" },
        { "/usr/share/fonts/opentype/stix/STIXGeneralItalic.otf",
          "/usr/share/fonts/stix/STIXGeneralItalic.otf" }
    };

    // TODO: Some tests use Lucida. We should load these as well, once it becomes
    // clear how to install these fonts easily on Fedora.
    for (size_t font = 0; font < G_N_ELEMENTS(fontPaths); font++) {
        bool found = false;
        for (size_t path = 0; path < 2; path++) {

            if (g_file_test(fontPaths[font][path], G_FILE_TEST_EXISTS)) {
                found = true;
                if (!FcConfigAppFontAddFile(config, reinterpret_cast<const FcChar8*>(fontPaths[font][path])))
                    g_error("Could not load font at %s!", fontPaths[font][path]);
                else
                    break;
            }
        }

        if (!found)
            g_error("Could not find font at %s. Either install this font or file a bug "
                    "at http://bugs.webkit.org if it is installed in another location.",
                    fontPaths[font][0]);
    }

    // Ahem is used by many layout tests.
    GOwnPtr<gchar> ahemFontFilename(g_build_filename(FONTS_CONF_DIR, "AHEM____.TTF", NULL));
    if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(ahemFontFilename.get())))
        g_error("Could not load font at %s!", ahemFontFilename.get()); 

    for (int i = 1; i <= 9; i++) {
        GOwnPtr<gchar> fontFilename(g_strdup_printf("WebKitWeightWatcher%i00.ttf", i));
        GOwnPtr<gchar> fontPath(g_build_filename(FONTS_CONF_DIR, "..", "..", "fonts", fontFilename.get(), NULL));
        if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontPath.get())))
            g_error("Could not load font at %s!", fontPath.get()); 
    }

    // A font with no valid Fontconfig encoding to test https://bugs.webkit.org/show_bug.cgi?id=47452
    GOwnPtr<gchar> fontWithNoValidEncodingFilename(g_build_filename(FONTS_CONF_DIR, "FontWithNoValidEncoding.fon", NULL));
    if (!FcConfigAppFontAddFile(config, reinterpret_cast<FcChar8*>(fontWithNoValidEncodingFilename.get())))
        g_error("Could not load font at %s!", fontWithNoValidEncodingFilename.get()); 

    if (!FcConfigSetCurrent(config))
        g_error("Could not set the current font configuration!");

    numFonts = FcConfigGetFonts(config, FcSetApplication)->nfont;
#endif
}

static gchar* dumpFramesAsText(WebKitWebFrame* frame)
{
    gchar* result = 0;

    // Add header for all but the main frame.
    bool isMainFrame = (webkit_web_view_get_main_frame(webView) == frame);

    CString innerText = DumpRenderTreeSupportGtk::getInnerText(frame);
    if (isMainFrame)
        result = g_strdup_printf("%s\n", innerText.data());
    else {
        const gchar* frameName = webkit_web_frame_get_name(frame);
        result = g_strdup_printf("\n--------\nFrame: '%s'\n--------\n%s\n", frameName, innerText.data());
    }

    if (gLayoutTestController->dumpChildFramesAsText()) {
        GSList* children = DumpRenderTreeSupportGtk::getFrameChildren(frame);
        for (GSList* child = children; child; child = g_slist_next(child))
            appendString(result, dumpFramesAsText(static_cast<WebKitWebFrame* >(child->data)));
        g_slist_free(children);
    }

    return result;
}

static gint compareHistoryItems(gpointer* item1, gpointer* item2)
{
    return g_ascii_strcasecmp(webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item1)),
                              webkit_web_history_item_get_target(WEBKIT_WEB_HISTORY_ITEM(item2)));
}

static void dumpHistoryItem(WebKitWebHistoryItem* item, int indent, bool current)
{
    ASSERT(item != NULL);
    int start = 0;
    g_object_ref(item);
    if (current) {
        printf("curr->");
        start = 6;
    }
    for (int i = start; i < indent; i++)
        putchar(' ');

    // normalize file URLs.
    const gchar* uri = webkit_web_history_item_get_uri(item);
    gchar* uriScheme = g_uri_parse_scheme(uri);
    if (g_strcmp0(uriScheme, "file") == 0) {
        gchar* pos = g_strstr_len(uri, -1, "/LayoutTests/");
        if (!pos)
            return;

        GString* result = g_string_sized_new(strlen(uri));
        result = g_string_append(result, "(file test):");
        result = g_string_append(result, pos + strlen("/LayoutTests/"));
        printf("%s", result->str);
        g_string_free(result, TRUE);
    } else
        printf("%s", uri);

    g_free(uriScheme);

    const gchar* target = webkit_web_history_item_get_target(item);
    if (target && strlen(target) > 0)
        printf(" (in frame \"%s\")", target);
    if (webkit_web_history_item_is_target_item(item))
        printf("  **nav target**");
    putchar('\n');
    GList* kids = webkit_web_history_item_get_children(item);
    if (kids) {
        // must sort to eliminate arbitrary result ordering which defeats reproducible testing
        kids = g_list_sort(kids, (GCompareFunc) compareHistoryItems);
        for (unsigned i = 0; i < g_list_length(kids); i++)
            dumpHistoryItem(WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(kids, i)), indent+4, FALSE);
    }
    g_object_unref(item);
}

static void dumpBackForwardListForWebView(WebKitWebView* view)
{
    printf("\n============== Back Forward List ==============\n");
    WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(view);

    // 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
    GList* itemsToPrint = NULL;
    gint forwardListCount = webkit_web_back_forward_list_get_forward_length(bfList);
    for (int i = forwardListCount; i > 0; i--) {
        WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
        // something is wrong if the item from the last test is in the forward part of the b/f list
        ASSERT(item != prevTestBFItem);
        g_object_ref(item);
        itemsToPrint = g_list_append(itemsToPrint, item);
    }

    WebKitWebHistoryItem* currentItem = webkit_web_back_forward_list_get_current_item(bfList);

    g_object_ref(currentItem);
    itemsToPrint = g_list_append(itemsToPrint, currentItem);

    gint currentItemIndex = g_list_length(itemsToPrint) - 1;
    gint backListCount = webkit_web_back_forward_list_get_back_length(bfList);
    for (int i = -1; i >= -(backListCount); i--) {
        WebKitWebHistoryItem* item = webkit_web_back_forward_list_get_nth_item(bfList, i);
        if (item == prevTestBFItem)
            break;
        g_object_ref(item);
        itemsToPrint = g_list_append(itemsToPrint, item);
    }

    for (int i = g_list_length(itemsToPrint) - 1; i >= 0; i--) {
        WebKitWebHistoryItem* item = WEBKIT_WEB_HISTORY_ITEM(g_list_nth_data(itemsToPrint, i));
        dumpHistoryItem(item, historyItemIndent, i == currentItemIndex);
        g_object_unref(item);
    }
    g_list_free(itemsToPrint);
    printf("===============================================\n");
}

static void dumpBackForwardListForAllWebViews()
{
    // Dump the back forward list of the main WebView first
    dumpBackForwardListForWebView(webView);

    // The view list is prepended. Reverse the list so we get the order right.
    GSList* viewList = g_slist_reverse(webViewList);
    for (unsigned i = 0; i < g_slist_length(viewList); ++i)
        dumpBackForwardListForWebView(WEBKIT_WEB_VIEW(g_slist_nth_data(viewList, i)));
}

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

    waitForPolicy = false;
}

static void resetDefaultsToConsistentValues()
{
    WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
    g_object_set(G_OBJECT(settings),
                 "enable-private-browsing", FALSE,
                 "enable-developer-extras", FALSE,
                 "enable-spell-checking", TRUE,
                 "enable-html5-database", TRUE,
                 "enable-html5-local-storage", TRUE,
                 "enable-xss-auditor", FALSE,
                 "enable-spatial-navigation", FALSE,
                 "enable-frame-flattening", FALSE,
                 "javascript-can-access-clipboard", TRUE,
                 "javascript-can-open-windows-automatically", TRUE,
                 "enable-offline-web-application-cache", TRUE,
                 "enable-universal-access-from-file-uris", TRUE,
                 "enable-scripts", TRUE,
                 "enable-dom-paste", TRUE,
                 "default-font-family", "Times",
                 "monospace-font-family", "Courier",
                 "serif-font-family", "Times",
                 "sans-serif-font-family", "Helvetica",
                 "cursive-font-family", "cursive",
                 "fantasy-font-family", "fantasy",
                 "default-font-size", 12,
                 "default-monospace-font-size", 10,
                 "minimum-font-size", 0,
                 "enable-caret-browsing", FALSE,
                 "enable-page-cache", FALSE,
                 "auto-resize-window", TRUE,
                 "enable-java-applet", FALSE,
                 "enable-plugins", TRUE,
                 "enable-hyperlink-auditing", FALSE,
                 "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX,
                 "enable-fullscreen", TRUE,
                 NULL);
    webkit_web_view_set_settings(webView, settings);
    webkit_set_cache_model(WEBKIT_CACHE_MODEL_DOCUMENT_BROWSER);

    DumpRenderTreeSupportGtk::clearMainFrameName(mainFrame);

    WebKitWebInspector* inspector = webkit_web_view_get_inspector(webView);
    g_object_set(G_OBJECT(inspector), "javascript-profiling-enabled", FALSE, NULL);

    webkit_web_view_set_zoom_level(webView, 1.0);
    DumpRenderTreeSupportGtk::setMinimumTimerInterval(webView, DumpRenderTreeSupportGtk::defaultMinimumTimerInterval());

    DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists();

    WebKitWebBackForwardList* list = webkit_web_view_get_back_forward_list(webView);
    webkit_web_back_forward_list_clear(list);

    SoupSession* session = webkit_get_default_session();
    SoupCookieJar* jar = reinterpret_cast<SoupCookieJar*>(soup_session_get_feature(session, SOUP_TYPE_COOKIE_JAR));

    // We only create the jar when the soup backend needs to do
    // HTTP. Should we initialize it earlier, perhaps?
    if (jar)
        g_object_set(G_OBJECT(jar), SOUP_COOKIE_JAR_ACCEPT_POLICY, SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY, NULL);

    setlocale(LC_ALL, "");

    DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(true);
    webkit_icon_database_set_path(webkit_get_icon_database(), 0);
    DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(false);

    if (axController)
        axController->resetToConsistentState();

    DumpRenderTreeSupportGtk::clearOpener(mainFrame);
}

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

static void runTestingServerLoop()
{
    // When DumpRenderTree runs 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];
    while (fgets(filenameBuffer, sizeof(filenameBuffer), stdin)) {
        char* newLineCharacter = strchr(filenameBuffer, '\n');
        if (newLineCharacter)
            *newLineCharacter = '\0';

        if (!strlen(filenameBuffer))
            continue;

        runTest(filenameBuffer);
    }
}

static void initializeGlobalsFromCommandLineOptions(int argc, char *argv[])
{
    struct option options[] = {
        {"notree", no_argument, &dumpTree, false},
        {"pixel-tests", no_argument, &dumpPixels, true},
        {"tree", no_argument, &dumpTree, true},
        {NULL, 0, NULL, 0}
    };
    
    int option;
    while ((option = getopt_long(argc, (char * const *)argv, "", options, NULL)) != -1) {
        switch (option) {
        case '?': // unknown or ambiguous option
        case ':': // missing argument
            exit(1);
            break;
        }
    }
}


void dump()
{
    invalidateAnyPreviousWaitToDumpWatchdog();

    if (dumpTree) {
        char* result = 0;
        gchar* responseMimeType = webkit_web_frame_get_response_mime_type(mainFrame);

        if (g_str_equal(responseMimeType, "text/plain")) {
            gLayoutTestController->setDumpAsText(true);
            gLayoutTestController->setGeneratePixelResults(false);
        }
        g_free(responseMimeType);

        if (gLayoutTestController->dumpAsText())
            result = dumpFramesAsText(mainFrame);
        else {
            // Widget resizing is done asynchronously in GTK+. We pump the main
            // loop here, to flush any pending resize requests. This prevents
            // timing issues which affect the size of elements in the output.
            // We only enable this workaround for tests that print the render tree
            // because this seems to break some dumpAsText tests: see bug 39988
            // After fixing that test, we should apply this approach to all dumps.
            while (gtk_events_pending())
                gtk_main_iteration();

            result = g_strdup(DumpRenderTreeSupportGtk::dumpRenderTree(mainFrame).data());
        }

        if (!result) {
            const char* errorMessage;
            if (gLayoutTestController->dumpAsText())
                errorMessage = "[documentElement innerText]";
            else if (gLayoutTestController->dumpDOMAsWebArchive())
                errorMessage = "[[mainFrame DOMDocument] webArchive]";
            else if (gLayoutTestController->dumpSourceAsWebArchive())
                errorMessage = "[[mainFrame dataSource] webArchive]";
            else
                errorMessage = "[mainFrame renderTreeAsExternalRepresentation]";
            printf("ERROR: nil result from %s", errorMessage);
        } else {
            printf("%s", result);
            g_free(result);
            if (!gLayoutTestController->dumpAsText() && !gLayoutTestController->dumpDOMAsWebArchive() && !gLayoutTestController->dumpSourceAsWebArchive())
                dumpFrameScrollPosition(mainFrame);

            if (gLayoutTestController->dumpBackForwardList())
                dumpBackForwardListForAllWebViews();
        }

        if (printSeparators) {
            puts("#EOF"); // terminate the content block
            fputs("#EOF\n", stderr);
            fflush(stdout);
            fflush(stderr);
        }
    }

    if (dumpPixels
     && gLayoutTestController->generatePixelResults()
     && !gLayoutTestController->dumpDOMAsWebArchive()
     && !gLayoutTestController->dumpSourceAsWebArchive())
        dumpWebViewAsPixelsAndCompareWithExpected(gLayoutTestController->expectedPixelHash());

    // FIXME: call displayWebView here when we support --paint

    done = true;
    gtk_main_quit();
}

static void setDefaultsToConsistentStateValuesForTesting()
{
    resetDefaultsToConsistentValues();

    /* Disable the default auth dialog for testing */
    SoupSession* session = webkit_get_default_session();
    soup_session_remove_feature_by_type(session, WEBKIT_TYPE_SOUP_AUTH_DIALOG);

#if PLATFORM(X11)
    webkit_web_settings_add_extra_plugin_directory(webView, TEST_PLUGIN_DIR);
#endif

    gchar* databaseDirectory = g_build_filename(g_get_user_data_dir(), "gtkwebkitdrt", "databases", NULL);
    webkit_set_web_database_directory_path(databaseDirectory);
    g_free(databaseDirectory);

#if defined(GTK_API_VERSION_2)
    gtk_rc_parse_string("style \"nix_scrollbar_spacing\"                    "
                        "{                                                  "
                        "    GtkScrolledWindow::scrollbar-spacing = 0       "
                        "}                                                  "
                        "class \"GtkWidget\" style \"nix_scrollbar_spacing\"");

#else
    GtkCssProvider* cssProvider = gtk_css_provider_new();
    gtk_css_provider_load_from_data(cssProvider,
                                    " * {                                       "
                                    "   -GtkScrolledWindow-scrollbar-spacing: 0;"
                                    "}                                          ",
                                    -1, 0);
    gtk_style_context_add_provider_for_screen(gdk_display_get_default_screen(gdk_display_get_default()),
                                              GTK_STYLE_PROVIDER(cssProvider),
                                              GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
    g_object_unref(cssProvider);
#endif
}

static void sendPixelResultsEOF()
{
    puts("#EOF");

    fflush(stdout);
    fflush(stderr);
}

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

    // Look for "'" as a separator between the path or URL, and the pixel dump hash that follows.
    string testURL(testPathOrURL);
    string expectedPixelHash;
    size_t separatorPos = testURL.find("'");
    if (separatorPos != string::npos) {
        testURL = string(testPathOrURL, 0, separatorPos);
        expectedPixelHash = string(testPathOrURL, separatorPos + 1);
    }

    // Convert the path into a full file URL if it does not look
    // like an HTTP/S URL (doesn't start with http:// or https://).
    if (testURL.find("http://") && testURL.find("https://")) {
        GFile* testFile = g_file_new_for_path(testURL.c_str());
        gchar* testURLCString = g_file_get_uri(testFile);
        testURL = testURLCString;
        g_free(testURLCString);
        g_object_unref(testFile);
    }

    resetDefaultsToConsistentValues();

    gLayoutTestController = LayoutTestController::create(testURL, expectedPixelHash);
    topLoadingFrame = 0;
    done = false;

    gLayoutTestController->setIconDatabaseEnabled(false);

    if (shouldLogFrameLoadDelegates(testURL))
        gLayoutTestController->setDumpFrameLoadCallbacks(true);

    if (shouldEnableDeveloperExtras(testURL)) {
        gLayoutTestController->setDeveloperExtrasEnabled(true);
        if (shouldOpenWebInspector(testURL))
            gLayoutTestController->showWebInspector();
        if (shouldDumpAsText(testURL)) {
            gLayoutTestController->setDumpAsText(true);
            gLayoutTestController->setGeneratePixelResults(false);
        }
    }

    WorkQueue::shared()->clear();
    WorkQueue::shared()->setFrozen(false);

    bool isSVGW3CTest = (testURL.find("svg/W3C-SVG-1.1") != string::npos);
    GtkAllocation size;
    size.x = size.y = 0;
    size.width = isSVGW3CTest ? 480 : LayoutTestController::maxViewWidth;
    size.height = isSVGW3CTest ? 360 : LayoutTestController::maxViewHeight;
    gtk_window_resize(GTK_WINDOW(window), size.width, size.height);
    gtk_widget_size_allocate(container, &size);

    if (prevTestBFItem)
        g_object_unref(prevTestBFItem);
    WebKitWebBackForwardList* bfList = webkit_web_view_get_back_forward_list(webView);
    prevTestBFItem = webkit_web_back_forward_list_get_current_item(bfList);
    if (prevTestBFItem)
        g_object_ref(prevTestBFItem);

    initializeFonts(testURL.c_str());

    // Focus the web view before loading the test to avoid focusing problems
    gtk_widget_grab_focus(GTK_WIDGET(webView));
    webkit_web_view_open(webView, testURL.c_str());

    gtk_main();

    // If developer extras enabled Web Inspector may have been open by the test.
    if (shouldEnableDeveloperExtras(testURL)) {
        gLayoutTestController->closeWebInspector();
        gLayoutTestController->setDeveloperExtrasEnabled(false);
    }

    // Also check if we still have opened webViews and free them.
    if (gLayoutTestController->closeRemainingWindowsWhenComplete() || webViewList) {
        while (webViewList) {
            g_object_unref(WEBKIT_WEB_VIEW(webViewList->data));
            webViewList = g_slist_next(webViewList);
        }
        g_slist_free(webViewList);
        webViewList = 0;
    }

    // A blank load seems to be necessary to reset state after certain tests.
    webkit_web_view_open(webView, "about:blank");

    gLayoutTestController.clear();

    // terminate the (possibly empty) pixels block after all the state reset
    sendPixelResultsEOF();
}

void webViewLoadStarted(WebKitWebView* view, WebKitWebFrame* frame, void*)
{
    // Make sure we only set this once per test.  If it gets cleared, and then set again, we might
    // end up doing two dumps for one test.
    if (!topLoadingFrame && !done)
        topLoadingFrame = frame;
}

static gboolean processWork(void* data)
{
    // if we finish all the commands, we're ready to dump state
    if (WorkQueue::shared()->processWork() && !gLayoutTestController->waitToDump())
        dump();

    return FALSE;
}

static char* getFrameNameSuitableForTestResult(WebKitWebView* view, WebKitWebFrame* frame)
{
    char* frameName = g_strdup(webkit_web_frame_get_name(frame));

    if (frame == webkit_web_view_get_main_frame(view)) {
        // This is a bit strange. Shouldn't web_frame_get_name return NULL?
        if (frameName && (frameName[0] != '\0')) {
            char* tmp = g_strdup_printf("main frame \"%s\"", frameName);
            g_free(frameName);
            frameName = tmp;
        } else {
            g_free(frameName);
            frameName = g_strdup("main frame");
        }
    } else if (!frameName || (frameName[0] == '\0')) {
        g_free(frameName);
        frameName = g_strdup("frame (anonymous)");
    } else {
        char* tmp = g_strdup_printf("frame \"%s\"", frameName);
        g_free(frameName);
        frameName = tmp;
    }

    return frameName;
}

static void webViewLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
{
    if (frame != topLoadingFrame)
        return;

    topLoadingFrame = 0;
    WorkQueue::shared()->setFrozen(true); // first complete load freezes the queue for the rest of this test
    if (gLayoutTestController->waitToDump())
        return;

    if (WorkQueue::shared()->count())
        g_timeout_add(0, processWork, 0);
    else
        dump();
}

static gboolean webViewLoadError(WebKitWebView*, WebKitWebFrame*, gchar*, gpointer, gpointer)
{
    return TRUE; // Return true here to disable the default error page.
}

static void webViewDocumentLoadFinished(WebKitWebView* view, WebKitWebFrame* frame, void*)
{
    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
        char* frameName = getFrameNameSuitableForTestResult(view, frame);
        printf("%s - didFinishDocumentLoadForFrame\n", frameName);
        g_free(frameName);
    } else if (!done) {
        guint pendingFrameUnloadEvents = DumpRenderTreeSupportGtk::getPendingUnloadEventCount(frame);
        if (pendingFrameUnloadEvents) {
            char* frameName = getFrameNameSuitableForTestResult(view, frame);
            printf("%s - has %u onunload handler(s)\n", frameName, pendingFrameUnloadEvents);
            g_free(frameName);
        }
    }
}

static void webViewOnloadEvent(WebKitWebView* view, WebKitWebFrame* frame, void*)
{
    if (!done && gLayoutTestController->dumpFrameLoadCallbacks()) {
        char* frameName = getFrameNameSuitableForTestResult(view, frame);
        printf("%s - didHandleOnloadEventsForFrame\n", frameName);
        g_free(frameName);
    }
}

static void addControllerToWindow(JSContextRef context, JSObjectRef windowObject, const char* controllerName, JSValueRef controller)
{
    JSStringRef controllerNameStr = JSStringCreateWithUTF8CString(controllerName);
    JSObjectSetProperty(context, windowObject, controllerNameStr, controller, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0);
    JSStringRelease(controllerNameStr); 
}

static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data)
{
    JSValueRef exception = 0;
    ASSERT(gLayoutTestController);

    gLayoutTestController->makeWindowObject(context, windowObject, &exception);
    ASSERT(!exception);

    gcController->makeWindowObject(context, windowObject, &exception);
    ASSERT(!exception);

    axController->makeWindowObject(context, windowObject, &exception);
    ASSERT(!exception);

    addControllerToWindow(context, windowObject, "eventSender", makeEventSender(context, !webkit_web_frame_get_parent(frame)));
    addControllerToWindow(context, windowObject, "plainText", makePlainTextController(context));
    addControllerToWindow(context, windowObject, "textInputController", makeTextInputController(context));
}

static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data)
{
    gchar* testMessage = 0;
    const gchar* uriScheme;

    // Tests expect only the filename part of local URIs
    uriScheme = g_strstr_len(message, -1, "file://");
    if (uriScheme) {
        GString* tempString = g_string_sized_new(strlen(message));
        gchar* filename = g_strrstr(uriScheme, G_DIR_SEPARATOR_S);

        if (filename) {
            filename += strlen(G_DIR_SEPARATOR_S);
            tempString = g_string_append_len(tempString, message, (uriScheme - message));
            tempString = g_string_append_len(tempString, filename, strlen(filename));
            testMessage = g_string_free(tempString, FALSE);
        }
    }

    fprintf(stdout, "CONSOLE MESSAGE: line %d: %s\n", line, testMessage ? testMessage : message);
    g_free(testMessage);

    return TRUE;
}


static gboolean webViewScriptAlert(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gpointer data)
{
    fprintf(stdout, "ALERT: %s\n", message);
    return TRUE;
}

static gboolean webViewScriptPrompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value, gpointer data)
{
    fprintf(stdout, "PROMPT: %s, default text: %s\n", message, defaultValue);
    *value = g_strdup(defaultValue);
    return TRUE;
}

static gboolean webViewScriptConfirm(WebKitWebView* view, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm, gpointer data)
{
    fprintf(stdout, "CONFIRM: %s\n", message);
    *didConfirm = TRUE;
    return TRUE;
}

static void webViewTitleChanged(WebKitWebView* view, WebKitWebFrame* frame, const gchar* title, gpointer data)
{
    if (gLayoutTestController->dumpTitleChanges() && !done)
        printf("TITLE CHANGED: %s\n", title ? title : "");
}

static bool webViewNavigationPolicyDecisionRequested(WebKitWebView* view, WebKitWebFrame* frame,
                                                     WebKitNetworkRequest* request,
                                                     WebKitWebNavigationAction* navAction,
                                                     WebKitWebPolicyDecision* policyDecision)
{
    // Use the default handler if we're not waiting for policy,
    // i.e., LayoutTestController::waitForPolicyDelegate
    if (!waitForPolicy)
        return FALSE;

    gchar* typeDescription;
    WebKitWebNavigationReason reason;
    g_object_get(G_OBJECT(navAction), "reason", &reason, NULL);

    switch(reason) {
        case WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED:
            typeDescription = g_strdup("link clicked");
            break;
        case WEBKIT_WEB_NAVIGATION_REASON_FORM_SUBMITTED:
            typeDescription = g_strdup("form submitted");
            break;
        case WEBKIT_WEB_NAVIGATION_REASON_BACK_FORWARD:
            typeDescription = g_strdup("back/forward");
            break;
        case WEBKIT_WEB_NAVIGATION_REASON_RELOAD:
            typeDescription = g_strdup("reload");
            break;
        case WEBKIT_WEB_NAVIGATION_REASON_FORM_RESUBMITTED:
            typeDescription = g_strdup("form resubmitted");
            break;
        case WEBKIT_WEB_NAVIGATION_REASON_OTHER:
            typeDescription = g_strdup("other");
            break;
        default:
            typeDescription = g_strdup("illegal value");
    }

    printf("Policy delegate: attempt to load %s with navigation type '%s'\n", webkit_network_request_get_uri(request), typeDescription);
    g_free(typeDescription);

    webkit_web_policy_decision_ignore(policyDecision);
    gLayoutTestController->notifyDone();

    return TRUE;
}

static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* message, gpointer data)
{
    // Are we doing anything wrong? One test that does not call
    // dumpStatusCallbacks gets true here
    if (gLayoutTestController->dumpStatusCallbacks())
        printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message);
}

static gboolean webViewClose(WebKitWebView* view)
{
    ASSERT(view);

    webViewList = g_slist_remove(webViewList, view);
    g_object_unref(view);

    return TRUE;
}

static void databaseQuotaExceeded(WebKitWebView* view, WebKitWebFrame* frame, WebKitWebDatabase *database)
{
    ASSERT(view);
    ASSERT(frame);
    ASSERT(database);

    WebKitSecurityOrigin* origin = webkit_web_database_get_security_origin(database);
    if (gLayoutTestController->dumpDatabaseCallbacks()) {
        printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%s, %s, %i} database:%s\n",
            webkit_security_origin_get_protocol(origin),
            webkit_security_origin_get_host(origin),
            webkit_security_origin_get_port(origin),
            webkit_web_database_get_name(database));
    }
    webkit_security_origin_set_web_database_quota(origin, 5 * 1024 * 1024);
}

static bool
geolocationPolicyDecisionRequested(WebKitWebView*, WebKitWebFrame*, WebKitGeolocationPolicyDecision* decision)
{
    if (!gLayoutTestController->isGeolocationPermissionSet())
        return FALSE;
    if (gLayoutTestController->geolocationPermission())
        webkit_geolocation_policy_allow(decision);
    else
        webkit_geolocation_policy_deny(decision);

    return TRUE;
}


static WebKitWebView* webViewCreate(WebKitWebView*, WebKitWebFrame*);

static gboolean webInspectorShowWindow(WebKitWebInspector*, gpointer data)
{
    gtk_window_set_default_size(GTK_WINDOW(webInspectorWindow), 800, 600);
    gtk_widget_show_all(webInspectorWindow);
    return TRUE;
}

static gboolean webInspectorCloseWindow(WebKitWebInspector*, gpointer data)
{
    gtk_widget_destroy(webInspectorWindow);
    webInspectorWindow = 0;
    return TRUE;
}

static WebKitWebView* webInspectorInspectWebView(WebKitWebInspector*, gpointer data)
{
    webInspectorWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    GtkWidget* webView = webkit_web_view_new();
    gtk_container_add(GTK_CONTAINER(webInspectorWindow),
                      webView);

    return WEBKIT_WEB_VIEW(webView);
}

static void webFrameLoadStatusNotified(WebKitWebFrame* frame, gpointer user_data)
{
    WebKitLoadStatus loadStatus = webkit_web_frame_get_load_status(frame);

    if (gLayoutTestController->dumpFrameLoadCallbacks()) {
        GOwnPtr<char> frameName(getFrameNameSuitableForTestResult(webkit_web_frame_get_web_view(frame), frame));

        switch (loadStatus) {
        case WEBKIT_LOAD_PROVISIONAL:
            if (!done)
                printf("%s - didStartProvisionalLoadForFrame\n", frameName.get());
            break;
        case WEBKIT_LOAD_COMMITTED:
            if (!done)
                printf("%s - didCommitLoadForFrame\n", frameName.get());
            break;
        case WEBKIT_LOAD_FINISHED:
            if (frame != topLoadingFrame || !done)
                printf("%s - didFinishLoadForFrame\n", frameName.get());
            break;
        default:
            break;
        }
    }
}

static void frameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* webFrame, gpointer user_data)
{
    g_signal_connect(webFrame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL);
}

static void willSendRequestCallback(WebKitWebView* webView, WebKitWebFrame*, WebKitWebResource*, WebKitNetworkRequest* request, WebKitNetworkResponse*)
{
    if (!done && gLayoutTestController->willSendRequestReturnsNull())
        return;

    SoupMessage* soupMessage = webkit_network_request_get_message(request);
    SoupURI* uri = soup_uri_new(webkit_network_request_get_uri(request));

    if (SOUP_URI_VALID_FOR_HTTP(uri) && g_strcmp0(uri->host, "127.0.0.1")
        && g_strcmp0(uri->host, "255.255.255.255")
        && g_ascii_strncasecmp(uri->host, "localhost", 9)) {
        printf("Blocked access to external URL %s\n", soup_uri_to_string(uri, FALSE));
        soup_uri_free(uri);
        return;
    }
    if (uri)
        soup_uri_free(uri);

    if (soupMessage) {
        const set<string>& clearHeaders = gLayoutTestController->willSendRequestClearHeaders();
        for (set<string>::const_iterator header = clearHeaders.begin(); header != clearHeaders.end(); ++header)
            soup_message_headers_remove(soupMessage->request_headers, header->c_str());
    }
}

static WebKitWebView* createWebView()
{
    WebKitWebView* view = WEBKIT_WEB_VIEW(webkit_web_view_new());

    DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(true);

    g_object_connect(G_OBJECT(view),
                     "signal::load-started", webViewLoadStarted, 0,
                     "signal::load-finished", webViewLoadFinished, 0,
                     "signal::load-error", webViewLoadError, 0,
                     "signal::window-object-cleared", webViewWindowObjectCleared, 0,
                     "signal::console-message", webViewConsoleMessage, 0,
                     "signal::script-alert", webViewScriptAlert, 0,
                     "signal::script-prompt", webViewScriptPrompt, 0,
                     "signal::script-confirm", webViewScriptConfirm, 0,
                     "signal::title-changed", webViewTitleChanged, 0,
                     "signal::navigation-policy-decision-requested", webViewNavigationPolicyDecisionRequested, 0,
                     "signal::status-bar-text-changed", webViewStatusBarTextChanged, 0,
                     "signal::create-web-view", webViewCreate, 0,
                     "signal::close-web-view", webViewClose, 0,
                     "signal::database-quota-exceeded", databaseQuotaExceeded, 0,
                     "signal::document-load-finished", webViewDocumentLoadFinished, 0,
                     "signal::geolocation-policy-decision-requested", geolocationPolicyDecisionRequested, 0,
                     "signal::onload-event", webViewOnloadEvent, 0,
                     "signal::drag-begin", dragBeginCallback, 0,
                     "signal::drag-end", dragEndCallback, 0,
                     "signal::drag-failed", dragFailedCallback, 0,
                     "signal::frame-created", frameCreatedCallback, 0,
                     "signal::resource-request-starting", willSendRequestCallback, 0,

                     NULL);
    connectEditingCallbacks(view);

    WebKitWebInspector* inspector = webkit_web_view_get_inspector(view);
    g_object_connect(G_OBJECT(inspector),
                     "signal::inspect-web-view", webInspectorInspectWebView, 0,
                     "signal::show-window", webInspectorShowWindow, 0,
                     "signal::close-window", webInspectorCloseWindow, 0,
                     NULL);

    if (webView) {
        WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
        webkit_web_view_set_settings(view, settings);
    }

    // frame-created is not issued for main frame. That's why we must do this here
    WebKitWebFrame* frame = webkit_web_view_get_main_frame(view);
    g_signal_connect(frame, "notify::load-status", G_CALLBACK(webFrameLoadStatusNotified), NULL);

    return view;
}

static WebKitWebView* webViewCreate(WebKitWebView* view, WebKitWebFrame* frame)
{
    if (!gLayoutTestController->canOpenWindows())
        return 0;

    // Make sure that waitUntilDone has been called.
    ASSERT(gLayoutTestController->waitToDump());

    WebKitWebView* newWebView = createWebView();
    g_object_ref_sink(G_OBJECT(newWebView));
    webViewList = g_slist_prepend(webViewList, newWebView);
    return newWebView;
}

static void logHandler(const gchar* domain, GLogLevelFlags level, const gchar* message, gpointer data)
{
    if (level < G_LOG_LEVEL_DEBUG)
        fprintf(stderr, "%s\n", message);
}

int main(int argc, char* argv[])
{
    g_thread_init(NULL);
    gtk_init(&argc, &argv);

    // Some plugins might try to use the GLib logger for printing debug
    // messages. This will cause tests to fail because of unexpected output.
    // We squelch all debug messages sent to the logger.
    g_log_set_default_handler(logHandler, 0);

    initializeGlobalsFromCommandLineOptions(argc, argv);
    initializeFonts();

    window = gtk_window_new(GTK_WINDOW_POPUP);
    container = GTK_WIDGET(gtk_scrolled_window_new(NULL, NULL));
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(container), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_container_add(GTK_CONTAINER(window), container);
    gtk_widget_show_all(window);

    webView = createWebView();
    gtk_container_add(GTK_CONTAINER(container), GTK_WIDGET(webView));
    gtk_widget_realize(GTK_WIDGET(webView));
    gtk_widget_show_all(container);
    gtk_widget_grab_focus(GTK_WIDGET(webView));
    mainFrame = webkit_web_view_get_main_frame(webView);

    setDefaultsToConsistentStateValuesForTesting();

    gcController = new GCController();
    axController = new AccessibilityController();

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

    delete gcController;
    gcController = 0;

    delete axController;
    axController = 0;

    gtk_widget_destroy(window);

    return 0;
}
