/*
 * Copyright (C) 2011 ProFUSION Embedded Systems
 * Copyright (C) 2011 Samsung Electronics
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "DumpRenderTree.h"

#include "DumpHistoryItem.h"
#include "DumpRenderTreeChrome.h"
#include "DumpRenderTreeView.h"
#include "EventSender.h"
#include "FontManagement.h"
#include "NotImplemented.h"
#include "PixelDumpSupport.h"
#include "TestRunner.h"
#include "WebCoreSupport/DumpRenderTreeSupportEfl.h"
#include "WebCoreTestSupport.h"
#include "WorkQueue.h"
#include "ewk_private.h"
#include <EWebKit.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_File.h>
#include <Edje.h>
#include <Evas.h>
#include <fontconfig/fontconfig.h>
#include <getopt.h>
#include <stdlib.h>
#include <unistd.h>
#include <wtf/Assertions.h>
#include <wtf/OwnPtr.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>

OwnPtr<DumpRenderTreeChrome> browser;
Evas_Object* topLoadingFrame = 0;
bool waitForPolicy = false;
bool policyDelegateEnabled = false;
bool policyDelegatePermissive = false;
Ecore_Timer* waitToDumpWatchdog = 0;
extern Ewk_History_Item* prevTestBFItem;

// From the top-level DumpRenderTree.h
RefPtr<TestRunner> gTestRunner;
volatile bool done = false;

static bool dumpPixelsForCurrentTest;
static int dumpPixelsForAllTests = false;
static int dumpTree = true;
static int printSeparators = true;

static String dumpFramesAsText(Evas_Object* frame)
{
    String result;

    if (browser->mainFrame() != frame) {
        result.append("\n--------\nFrame: '");
        result.append(String::fromUTF8(ewk_frame_name_get(frame)));
        result.append("'\n--------\n");
    }

    const char* frameContents = ewk_frame_plain_text_get(frame);
    result.append(String::fromUTF8(frameContents));
    result.append("\n");
    eina_stringshare_del(frameContents);

    if (gTestRunner->dumpChildFramesAsText()) {
        Eina_List* children = DumpRenderTreeSupportEfl::frameChildren(frame);
        void* iterator;

        EINA_LIST_FREE(children, iterator) {
            Evas_Object* currentFrame = static_cast<Evas_Object*>(iterator);
            String tempText(dumpFramesAsText(currentFrame));

            if (tempText.isEmpty())
                continue;

            result.append(tempText);
        }
    }

    return result;
}

static void dumpFrameScrollPosition(Evas_Object* frame)
{
    int x, y;
    ewk_frame_scroll_pos_get(frame, &x, &y);
    if (abs(x) > 0 || abs(y) > 0) {
        StringBuilder result;

        Evas_Object* parent = evas_object_smart_parent_get(frame);

        // smart parent of main frame is view object.
        if (parent != browser->mainView()) {
            result.append("frame '");
            result.append(ewk_frame_name_get(frame));
            result.append("' ");
        }

        result.append("scrolled to ");
        result.append(WTF::String::number(x));
        result.append(",");
        result.append(WTF::String::number(y));
        result.append("\n");

        printf("%s", result.toString().utf8().data());
    }

    if (gTestRunner->dumpChildFrameScrollPositions()) {
        Eina_List* children = DumpRenderTreeSupportEfl::frameChildren(frame);
        void* iterator;

        EINA_LIST_FREE(children, iterator) {
            Evas_Object* currentFrame = static_cast<Evas_Object*>(iterator);
            dumpFrameScrollPosition(currentFrame);
        }
    }
}

static bool shouldLogFrameLoadDelegates(const String& pathOrURL)
{
    return pathOrURL.contains("loading/");
}

static bool shouldDumpAsText(const String& pathOrURL)
{
    return pathOrURL.contains("dumpAsText/");
}

static bool shouldOpenWebInspector(const String& pathOrURL)
{
    return pathOrURL.contains("inspector/");
}

static void sendPixelResultsEOF()
{
    puts("#EOF");
    fflush(stdout);
    fflush(stderr);
}

static void invalidateAnyPreviousWaitToDumpWatchdog()
{
    if (waitToDumpWatchdog) {
        ecore_timer_del(waitToDumpWatchdog);
        waitToDumpWatchdog = 0;
    }
    waitForPolicy = false;
}

static void onEcoreEvasResize(Ecore_Evas* ecoreEvas)
{
    int width, height;

    ecore_evas_geometry_get(ecoreEvas, 0, 0, &width, &height);
    evas_object_move(browser->mainView(), 0, 0);
    evas_object_resize(browser->mainView(), width, height);
}

static void onCloseWindow(Ecore_Evas*)
{
    notImplemented();
}

static Eina_Bool useLongRunningServerMode(int argc, char** argv)
{
    return (argc == optind + 1 && !strcmp(argv[optind], "-"));
}

static bool parseCommandLineOptions(int argc, char** argv)
{
    static const option options[] = {
        {"notree", no_argument, &dumpTree, false},
        {"pixel-tests", no_argument, &dumpPixelsForAllTests, true},
        {"tree", no_argument, &dumpTree, true},
        {0, 0, 0, 0}
    };

    int option;
    while ((option = getopt_long(argc, (char* const*)argv, "", options, 0)) != -1) {
        switch (option) {
        case '?':
        case ':':
            return false;
        }
    }

    return true;
}

static inline bool isGlobalHistoryTest(const String& cTestPathOrURL)
{
    return cTestPathOrURL.contains("/globalhistory/");
}

static void createTestRunner(const String& testURL, const String& expectedPixelHash)
{
    gTestRunner =
        TestRunner::create(std::string(testURL.utf8().data()),
                                     std::string(expectedPixelHash.utf8().data()));

    topLoadingFrame = 0;
    done = false;

    gTestRunner->setIconDatabaseEnabled(false);

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

    gTestRunner->setDeveloperExtrasEnabled(true);
    if (shouldOpenWebInspector(testURL))
        gTestRunner->showWebInspector();

    gTestRunner->setDumpHistoryDelegateCallbacks(isGlobalHistoryTest(testURL));

    if (shouldDumpAsText(testURL)) {
        gTestRunner->setDumpAsText(true);
        gTestRunner->setGeneratePixelResults(false);
    }
}

static String getFinalTestURL(const String& testURL)
{
    if (!testURL.startsWith("http://") && !testURL.startsWith("https://")) {
        char* cFilePath = ecore_file_realpath(testURL.utf8().data());
        const String filePath = String::fromUTF8(cFilePath);
        free(cFilePath);

        if (ecore_file_exists(filePath.utf8().data()))
            return String("file://") + filePath;
    }

    return testURL;
}

static void runTest(const char* inputLine)
{
    TestCommand command = parseInputLine(inputLine);
    const String testPathOrURL(command.pathOrURL.c_str());
    ASSERT(!testPathOrURL.isEmpty());
    dumpPixelsForCurrentTest = command.shouldDumpPixels || dumpPixelsForAllTests;
    const String expectedPixelHash(command.expectedPixelHash.c_str());

    // 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://).
    const String testURL = getFinalTestURL(testPathOrURL);

    browser->resetDefaultsToConsistentValues();
    createTestRunner(testURL, expectedPixelHash);

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

    const bool isSVGW3CTest = testURL.contains("svg/W3C-SVG-1.1");
    const int width = isSVGW3CTest ? 480 : TestRunner::maxViewWidth;
    const int height = isSVGW3CTest ? 360 : TestRunner::maxViewHeight;
    evas_object_resize(browser->mainView(), width, height);

    if (prevTestBFItem)
        ewk_history_item_free(prevTestBFItem);
    const Ewk_History* history = ewk_view_history_get(browser->mainView());
    prevTestBFItem = ewk_history_history_item_current_get(history);

    evas_object_focus_set(browser->mainView(), EINA_TRUE);
    ewk_view_uri_set(browser->mainView(), testURL.utf8().data());

    ecore_main_loop_begin();

    gTestRunner->closeWebInspector();
    gTestRunner->setDeveloperExtrasEnabled(false);

    browser->clearExtraViews();

    // FIXME: Move to DRTChrome::resetDefaultsToConsistentValues() after bug 85209 lands.
    WebCoreTestSupport::resetInternalsObject(DumpRenderTreeSupportEfl::globalContextRefForFrame(browser->mainFrame()));

    ewk_view_uri_set(browser->mainView(), "about:blank");

    gTestRunner.clear();
    sendPixelResultsEOF();
}

static void runTestingServerLoop()
{
    char filename[PATH_MAX];

    while (fgets(filename, sizeof(filename), stdin)) {
        char* newLine = strrchr(filename, '\n');
        if (newLine)
            *newLine = '\0';

        if (filename[0] != '\0')
            runTest(filename);
    }
}

static void adjustOutputTypeByMimeType(const Evas_Object* frame)
{
    const String responseMimeType(DumpRenderTreeSupportEfl::responseMimeType(frame));
    if (responseMimeType == "text/plain") {
        gTestRunner->setDumpAsText(true);
        gTestRunner->setGeneratePixelResults(false);
    }
}

static void dumpFrameContentsAsText(Evas_Object* frame)
{
    String result;
    if (gTestRunner->dumpAsText())
        result = dumpFramesAsText(frame);
    else
        result = DumpRenderTreeSupportEfl::renderTreeDump(frame);

    printf("%s", result.utf8().data());
}

static bool shouldDumpFrameScrollPosition()
{
    return !gTestRunner->dumpAsText() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive();
}

static bool shouldDumpPixelsAndCompareWithExpected()
{
    return dumpPixelsForCurrentTest && gTestRunner->generatePixelResults() && !gTestRunner->dumpDOMAsWebArchive() && !gTestRunner->dumpSourceAsWebArchive();
}

static bool shouldDumpBackForwardList()
{
    return gTestRunner->dumpBackForwardList();
}

static bool initEfl()
{
    if (!ecore_evas_init())
        return false;
    if (!ecore_file_init()) {
        ecore_evas_shutdown();
        return false;
    }
    if (!edje_init()) {
        ecore_file_shutdown();
        ecore_evas_shutdown();
        return false;
    }
    if (!ewk_init()) {
        edje_shutdown();
        ecore_file_shutdown();
        ecore_evas_shutdown();
        return false;
    }

    return true;
}

static void shutdownEfl()
{
    ewk_shutdown();
    edje_shutdown();
    ecore_file_shutdown();
    ecore_evas_shutdown();
}

void displayWebView()
{
    DumpRenderTreeSupportEfl::forceLayout(browser->mainFrame());
    DumpRenderTreeSupportEfl::setTracksRepaints(browser->mainFrame(), true);
    DumpRenderTreeSupportEfl::resetTrackedRepaints(browser->mainFrame());
}

void dump()
{
    Evas_Object* frame = browser->mainFrame();

    invalidateAnyPreviousWaitToDumpWatchdog();

    if (dumpTree) {
        adjustOutputTypeByMimeType(frame);
        dumpFrameContentsAsText(frame);

        if (shouldDumpFrameScrollPosition())
            dumpFrameScrollPosition(frame);

        if (shouldDumpBackForwardList())
            dumpBackForwardListForWebViews();

        if (printSeparators) {
            puts("#EOF");
            fputs("#EOF\n", stderr);
            fflush(stdout);
            fflush(stderr);
        }
    }

    if (shouldDumpPixelsAndCompareWithExpected())
        dumpWebViewAsPixelsAndCompareWithExpected(gTestRunner->expectedPixelHash());

    done = true;
    ecore_main_loop_quit();
}

static Ecore_Evas* initEcoreEvas()
{
    const char* engine = 0;
#if defined(WTF_USE_ACCELERATED_COMPOSITING) && defined(HAVE_ECORE_X)
    engine = "opengl_x11";
#endif
    Ecore_Evas* ecoreEvas = ecore_evas_new(engine, 0, 0, 800, 600, 0);
    if (!ecoreEvas) {
        shutdownEfl();
        exit(EXIT_FAILURE);
    }

    ecore_evas_title_set(ecoreEvas, "EFL DumpRenderTree");
    ecore_evas_callback_resize_set(ecoreEvas, onEcoreEvasResize);
    ecore_evas_callback_delete_request_set(ecoreEvas, onCloseWindow);
    ecore_evas_show(ecoreEvas);

    return ecoreEvas;
}

int main(int argc, char** argv)
{
    if (!parseCommandLineOptions(argc, argv))
        return EXIT_FAILURE;

    if (!initEfl())
        return EXIT_FAILURE;

    WTFInstallReportBacktraceOnCrashHook();

    OwnPtr<Ecore_Evas> ecoreEvas = adoptPtr(initEcoreEvas());
    browser = DumpRenderTreeChrome::create(ecore_evas_get(ecoreEvas.get()));
    addFontsToEnvironment();

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

    ecoreEvas.clear();

    shutdownEfl();
    return EXIT_SUCCESS;
}
