#include "../util.h"
#include <QAction>
#include <QColor>
#include <QDebug>
#include <QDeclarativeComponent>
#include <QDeclarativeEngine>
#include <QDeclarativeItem>
#include <QDeclarativeProperty>
#include <QDeclarativeView>
#include <QDir>
#include <QGraphicsWebView>
#include <QTest>
#include <QVariant>
#include <QWebFrame>
#include "qdeclarativewebview_p.h"

QT_BEGIN_NAMESPACE

class tst_QDeclarativeWebView : public QObject {
    Q_OBJECT

public:
    tst_QDeclarativeWebView();

private slots:
    void cleanupTestCase();

    void basicProperties();
    void elementAreaAt();
    void historyNav();
    void javaScript();
    void loadError();
    void multipleWindows();
    void newWindowComponent();
    void newWindowParent();
    void preferredWidthTest();
    void preferredHeightTest();
    void preferredWidthDefaultTest();
    void preferredHeightDefaultTest();
    void pressGrabTime();
    void renderingEnabled();
    void setHtml();
    void settings();
#if QT_VERSION >= 0x040703
    void backgroundColor();
#endif

private:
    void checkNoErrors(const QDeclarativeComponent&);
    QString tmpDir() const
    {
        static QString tmpd = QDir::tempPath() + "/tst_qdeclarativewebview-"
            + QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss"));
        return tmpd;
    }
};

tst_QDeclarativeWebView::tst_QDeclarativeWebView()
{
    Q_UNUSED(waitForSignal)
}

static QString strippedHtml(QString html)
{
    html.replace(QRegExp("\\s+"), "");
    return html;
}

static QString fileContents(const QString& filename)
{
    QFile file(filename);
    file.open(QIODevice::ReadOnly);
    return QString::fromUtf8(file.readAll());
}

static void removeRecursive(const QString& dirname)
{
    QDir dir(dirname);
    QFileInfoList entries(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
    for (int i = 0; i < entries.count(); ++i)
        if (entries[i].isDir())
            removeRecursive(entries[i].filePath());
        else
            dir.remove(entries[i].fileName());
    QDir().rmdir(dirname);
}

void tst_QDeclarativeWebView::cleanupTestCase()
{
    removeRecursive(tmpDir());
}

void tst_QDeclarativeWebView::basicProperties()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/basic.qml"));
    checkNoErrors(component);
    QWebSettings::enablePersistentStorage(tmpDir());

    QObject* wv = component.create();
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
    QCOMPARE(wv->property("title").toString(), QLatin1String("Basic"));
    QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 48);
    QEXPECT_FAIL("", "'icon' property isn't working", Continue);
    QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")), QPixmap("qrc:///resources/basic.png"));
    QCOMPARE(wv->property("statusText").toString(), QLatin1String("status here"));
    QCOMPARE(strippedHtml(fileContents(":/resources/basic.html")), strippedHtml(wv->property("html").toString()));
    QEXPECT_FAIL("", "TODO: get preferred width from QGraphicsWebView result", Continue);
    QCOMPARE(wv->property("preferredWidth").toInt(), 0);
    QEXPECT_FAIL("", "TODO: get preferred height from QGraphicsWebView result", Continue);
    QCOMPARE(wv->property("preferredHeight").toInt(), 0);
    QCOMPARE(wv->property("url").toUrl(), QUrl("qrc:///resources/basic.html"));
    QCOMPARE(wv->property("status").toInt(), int(QDeclarativeWebView::Ready));

    QAction* reloadAction = wv->property("reload").value<QAction*>();
    QVERIFY(reloadAction);
    QVERIFY(reloadAction->isEnabled());
    QAction* backAction = wv->property("back").value<QAction*>();
    QVERIFY(backAction);
    QVERIFY(!backAction->isEnabled());
    QAction* forwardAction = wv->property("forward").value<QAction*>();
    QVERIFY(forwardAction);
    QVERIFY(!forwardAction->isEnabled());
    QAction* stopAction = wv->property("stop").value<QAction*>();
    QVERIFY(stopAction);
    QVERIFY(!stopAction->isEnabled());

    wv->setProperty("pixelCacheSize", 0); // mainly testing that it doesn't crash or anything!
    QCOMPARE(wv->property("pixelCacheSize").toInt(), 0);
    reloadAction->trigger();
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
}

void tst_QDeclarativeWebView::elementAreaAt()
{
    QSKIP("This test should be changed to test 'heuristicZoom' instead.", SkipAll);
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/elements.qml"));
    checkNoErrors(component);
    QDeclarativeWebView* wv = qobject_cast<QDeclarativeWebView*>(component.create());
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    // Areas from elements.html.
//    const QRect areaA(1, 1, 75, 54);
//    const QRect areaB(78, 3, 110, 50);
//    const QRect wholeView(0, 0, 310, 100);
//    const QRect areaBC(76, 1, 223, 54);

//    QCOMPARE(wv->elementAreaAt(40, 30, 100, 100), areaA);
//    QCOMPARE(wv->elementAreaAt(130, 30, 200, 100), areaB);
//    QCOMPARE(wv->elementAreaAt(40, 30, 400, 400), wholeView);
//    QCOMPARE(wv->elementAreaAt(130, 30, 280, 280), areaBC);
//    QCOMPARE(wv->elementAreaAt(130, 30, 400, 400), wholeView);
}

void tst_QDeclarativeWebView::historyNav()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/basic.qml"));
    checkNoErrors(component);
    QWebSettings::enablePersistentStorage(tmpDir());

    QObject* wv = component.create();
    QVERIFY(wv);

    QAction* reloadAction = wv->property("reload").value<QAction*>();
    QVERIFY(reloadAction);
    QAction* backAction = wv->property("back").value<QAction*>();
    QVERIFY(backAction);
    QAction* forwardAction = wv->property("forward").value<QAction*>();
    QVERIFY(forwardAction);
    QAction* stopAction = wv->property("stop").value<QAction*>();
    QVERIFY(stopAction);

    for (int i = 1; i <= 2; ++i) {
        QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
        QCOMPARE(wv->property("title").toString(), QLatin1String("Basic"));
        QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 48);
        QEXPECT_FAIL("", "'icon' property isn't working", Continue);
        QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")), QPixmap("qrc:///data/basic.png"));
        QCOMPARE(wv->property("statusText").toString(), QLatin1String("status here"));
        QCOMPARE(strippedHtml(fileContents(":/resources/basic.html")), strippedHtml(wv->property("html").toString()));
        QEXPECT_FAIL("", "TODO: get preferred width from QGraphicsWebView result", Continue);
        QCOMPARE(wv->property("preferredWidth").toDouble(), 0.0);
        QCOMPARE(wv->property("url").toUrl(), QUrl("qrc:///resources/basic.html"));
        QCOMPARE(wv->property("status").toInt(), int(QDeclarativeWebView::Ready));
        QVERIFY(reloadAction->isEnabled());
        QVERIFY(!backAction->isEnabled());
        QVERIFY(!forwardAction->isEnabled());
        QVERIFY(!stopAction->isEnabled());
        reloadAction->trigger();
    }

    wv->setProperty("url", QUrl("qrc:///resources/forward.html"));
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
    QCOMPARE(wv->property("title").toString(), QLatin1String("Forward"));
    QTRY_COMPARE(qvariant_cast<QPixmap>(wv->property("icon")).width(), 32);
    QEXPECT_FAIL("", "'icon' property isn't working", Continue);
    QCOMPARE(qvariant_cast<QPixmap>(wv->property("icon")), QPixmap("qrc:///resources/forward.png"));
    QCOMPARE(strippedHtml(fileContents(":/resources/forward.html")), strippedHtml(wv->property("html").toString()));
    QCOMPARE(wv->property("url").toUrl(), QUrl("qrc:///resources/forward.html"));
    QCOMPARE(wv->property("status").toInt(), int(QDeclarativeWebView::Ready));
    QCOMPARE(wv->property("statusText").toString(), QString());

    QVERIFY(reloadAction->isEnabled());
    QVERIFY(backAction->isEnabled());
    QVERIFY(!forwardAction->isEnabled());
    QVERIFY(!stopAction->isEnabled());

    backAction->trigger();

    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
    QCOMPARE(wv->property("title").toString(), QLatin1String("Basic"));
    QCOMPARE(strippedHtml(fileContents(":/resources/basic.html")), strippedHtml(wv->property("html").toString()));
    QCOMPARE(wv->property("url").toUrl(), QUrl("qrc:///resources/basic.html"));
    QCOMPARE(wv->property("status").toInt(), int(QDeclarativeWebView::Ready));

    QVERIFY(reloadAction->isEnabled());
    QVERIFY(!backAction->isEnabled());
    QVERIFY(forwardAction->isEnabled());
    QVERIFY(!stopAction->isEnabled());
}

static inline QVariant callEvaluateJavaScript(QObject *object, const QString& snippet)
{
    QVariant result;
    QMetaObject::invokeMethod(object, "evaluateJavaScript", Q_RETURN_ARG(QVariant, result), Q_ARG(QString, snippet));
    return result;
}

void tst_QDeclarativeWebView::javaScript()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/javaScript.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    QCOMPARE(callEvaluateJavaScript(wv, "123").toInt(), 123);
    QCOMPARE(callEvaluateJavaScript(wv, "window.status").toString(), QLatin1String("status here"));
    QCOMPARE(callEvaluateJavaScript(wv, "window.myjsname.qmlprop").toString(), QLatin1String("qmlvalue"));
}

void tst_QDeclarativeWebView::loadError()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/loadError.qml"));
    checkNoErrors(component);
    QWebSettings::enablePersistentStorage(tmpDir());

    QObject* wv = component.create();
    QVERIFY(wv);
    QAction* reloadAction = wv->property("reload").value<QAction*>();
    QVERIFY(reloadAction);

    for (int i = 1; i <= 2; ++i) {
        QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
        QCOMPARE(wv->property("title").toString(), QString());
        QCOMPARE(wv->property("statusText").toString(), QString()); // HTML 'status bar' text, not error message
        QCOMPARE(wv->property("url").toUrl(), QUrl("qrc:///resources/does-not-exist.html")); // Unlike QWebPage, which loses url
        QCOMPARE(wv->property("status").toInt(), int(QDeclarativeWebView::Error));
        reloadAction->trigger();
    }
}

void tst_QDeclarativeWebView::multipleWindows()
{
    QSKIP("Rework this test to not depend on QDeclarativeGrid", SkipAll);
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/newwindows.qml"));
    checkNoErrors(component);

//    QDeclarativeGrid *grid = qobject_cast<QDeclarativeGrid*>(component.create());
//    QVERIFY(grid != 0);
//    QTRY_COMPARE(grid->children().count(), 2+4); // Component, Loader (with 1 WebView), 4 new-window WebViews
//    QDeclarativeItem* popup = qobject_cast<QDeclarativeItem*>(grid->children().at(2)); // first popup after Component and Loader.
//    QVERIFY(popup != 0);
//    QTRY_COMPARE(popup->x(), 150.0);
}

void tst_QDeclarativeWebView::newWindowComponent()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/propertychanges.qml"));
    checkNoErrors(component);
    QDeclarativeItem* rootItem = qobject_cast<QDeclarativeItem*>(component.create());
    QVERIFY(rootItem);
    QObject* wv = rootItem->findChild<QObject*>("webView");
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    QDeclarativeComponent substituteComponent(&engine);
    substituteComponent.setData("import QtQuick 1.0; WebView { objectName: 'newWebView'; url: 'basic.html'; }", QUrl::fromLocalFile(""));
    QSignalSpy newWindowComponentSpy(wv, SIGNAL(newWindowComponentChanged()));

    wv->setProperty("newWindowComponent", QVariant::fromValue(&substituteComponent));
    QCOMPARE(wv->property("newWindowComponent"), QVariant::fromValue(&substituteComponent));
    QCOMPARE(newWindowComponentSpy.count(), 1);

    wv->setProperty("newWindowComponent", QVariant::fromValue(&substituteComponent));
    QCOMPARE(newWindowComponentSpy.count(), 1);

    wv->setProperty("newWindowComponent", QVariant::fromValue((QDeclarativeComponent*)0));
    QCOMPARE(newWindowComponentSpy.count(), 2);
}

void tst_QDeclarativeWebView::newWindowParent()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/propertychanges.qml"));
    checkNoErrors(component);
    QDeclarativeItem* rootItem = qobject_cast<QDeclarativeItem*>(component.create());
    QVERIFY(rootItem);
    QObject* wv = rootItem->findChild<QObject*>("webView");
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    QDeclarativeItem* oldWindowParent = rootItem->findChild<QDeclarativeItem*>("oldWindowParent");
    QCOMPARE(qvariant_cast<QDeclarativeItem*>(wv->property("newWindowParent")), oldWindowParent);
    QSignalSpy newWindowParentSpy(wv, SIGNAL(newWindowParentChanged()));

    QDeclarativeItem* newWindowParent = rootItem->findChild<QDeclarativeItem*>("newWindowParent");
    wv->setProperty("newWindowParent", QVariant::fromValue(newWindowParent));
    QVERIFY(newWindowParent);
    QVERIFY(oldWindowParent);
    QCOMPARE(oldWindowParent->childItems().count(), 0);
    QCOMPARE(wv->property("newWindowParent"), QVariant::fromValue(newWindowParent));
    QCOMPARE(newWindowParentSpy.count(), 1);

    wv->setProperty("newWindowParent", QVariant::fromValue(newWindowParent));
    QCOMPARE(newWindowParentSpy.count(), 1);

    wv->setProperty("newWindowParent", QVariant::fromValue((QDeclarativeItem*)0));
    QCOMPARE(newWindowParentSpy.count(), 2);
}

void tst_QDeclarativeWebView::preferredWidthTest()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/webviewtest.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    wv->setProperty("testUrl", QUrl("qrc:///resources/sample.html"));
    QCOMPARE(wv->property("prefWidth").toInt(), 600);
}

void tst_QDeclarativeWebView::preferredHeightTest()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/webviewtest.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    wv->setProperty("testUrl", QUrl("qrc:///resources/sample.html"));
    QCOMPARE(wv->property("prefHeight").toInt(), 500);
}

void tst_QDeclarativeWebView::preferredWidthDefaultTest()
{
    QGraphicsWebView view;
    view.load(QUrl("qrc:///resources/sample.html"));

    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/webviewtestdefault.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    wv->setProperty("testUrl", QUrl("qrc:///resources/sample.html"));
    QCOMPARE(wv->property("prefWidth").toDouble(), view.preferredWidth());
}

void tst_QDeclarativeWebView::preferredHeightDefaultTest()
{
    QGraphicsWebView view;
    view.load(QUrl("qrc:///resources/sample.html"));

    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/webviewtestdefault.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    wv->setProperty("testUrl", QUrl("qrc:///resources/sample.html"));
    QCOMPARE(wv->property("prefHeight").toDouble(), view.preferredHeight());
}

void tst_QDeclarativeWebView::pressGrabTime()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/propertychanges.qml"));
    checkNoErrors(component);
    QDeclarativeItem* rootItem = qobject_cast<QDeclarativeItem*>(component.create());
    QVERIFY(rootItem);
    QObject* wv = rootItem->findChild<QObject*>("webView");
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);
    QCOMPARE(wv->property("pressGrabTime").toInt(), 200);
    QSignalSpy pressGrabTimeSpy(wv, SIGNAL(pressGrabTimeChanged()));

    wv->setProperty("pressGrabTime", 100);
    QCOMPARE(wv->property("pressGrabTime").toInt(), 100);
    QCOMPARE(pressGrabTimeSpy.count(), 1);

    wv->setProperty("pressGrabTime", 100);
    QCOMPARE(pressGrabTimeSpy.count(), 1);

    wv->setProperty("pressGrabTime", 0);
    QCOMPARE(pressGrabTimeSpy.count(), 2);
}

void tst_QDeclarativeWebView::renderingEnabled()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/propertychanges.qml"));
    checkNoErrors(component);
    QDeclarativeItem* rootItem = qobject_cast<QDeclarativeItem*>(component.create());
    QVERIFY(rootItem);
    QObject* wv = rootItem->findChild<QObject*>("webView");
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    QVERIFY(wv->property("renderingEnabled").toBool());
    QSignalSpy renderingEnabledSpy(wv, SIGNAL(renderingEnabledChanged()));

    wv->setProperty("renderingEnabled", false);
    QVERIFY(!wv->property("renderingEnabled").toBool());
    QCOMPARE(renderingEnabledSpy.count(), 1);

    wv->setProperty("renderingEnabled", false);
    QCOMPARE(renderingEnabledSpy.count(), 1);

    wv->setProperty("renderingEnabled", true);
    QCOMPARE(renderingEnabledSpy.count(), 2);
}

void tst_QDeclarativeWebView::setHtml()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/sethtml.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    QCOMPARE(wv->property("html").toString(), QLatin1String("<html><head></head><body><p>This is a <b>string</b> set on the WebView</p></body></html>"));

    QSignalSpy spy(wv, SIGNAL(htmlChanged()));
    wv->setProperty("html", QLatin1String("<html><head><title>Basic</title></head><body><p>text</p></body></html>"));
    QCOMPARE(spy.count(), 1);
}

void tst_QDeclarativeWebView::settings()
{
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/basic.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    QTRY_COMPARE(wv->property("progress").toDouble(), 1.0);

    QObject* s = QDeclarativeProperty(wv, "settings").object();
    QVERIFY(s);

    QStringList settingsList;
    settingsList << QString::fromAscii("autoLoadImages")
                 << QString::fromAscii("developerExtrasEnabled")
                 << QString::fromAscii("javaEnabled")
                 << QString::fromAscii("javascriptCanAccessClipboard")
                 << QString::fromAscii("javascriptCanOpenWindows")
                 << QString::fromAscii("javascriptEnabled")
                 << QString::fromAscii("linksIncludedInFocusChain")
                 << QString::fromAscii("localContentCanAccessRemoteUrls")
                 << QString::fromAscii("localStorageDatabaseEnabled")
                 << QString::fromAscii("offlineStorageDatabaseEnabled")
                 << QString::fromAscii("offlineWebApplicationCacheEnabled")
                 << QString::fromAscii("pluginsEnabled")
                 << QString::fromAscii("printElementBackgrounds")
                 << QString::fromAscii("privateBrowsingEnabled")
                 << QString::fromAscii("zoomTextOnly");

    // Merely tests that setting gets stored (in QWebSettings), behavioural tests are in WebKit.
    for (int b = 0; b <= 1; b++) {
        bool value = !!b;
        foreach (const QString& name, settingsList)
            s->setProperty(name.toAscii().data(), value);
        for (int i = 0; i < 2; i++) {
            foreach (const QString& name, settingsList)
                QCOMPARE(s->property(name.toAscii().data()).toBool(), value);
        }
    }
}

#if QT_VERSION >= 0x040703
void tst_QDeclarativeWebView::backgroundColor()
{
    // We test here the rendering of the background.
    QDeclarativeEngine engine;
    QDeclarativeComponent component(&engine, QUrl("qrc:///resources/webviewbackgroundcolor.qml"));
    checkNoErrors(component);
    QObject* wv = component.create();
    QVERIFY(wv);
    QCOMPARE(wv->property("backgroundColor").value<QColor>(), QColor(Qt::red));
    QDeclarativeView view;
    view.setSource(QUrl("qrc:///resources/webviewbackgroundcolor.qml"));
    view.show();
    QTest::qWaitForWindowShown(&view);
    QPixmap result(view.width(), view.height());
    QPainter painter(&result);
    view.render(&painter);
    QPixmap reference(view.width(), view.height());
    reference.fill(Qt::red);
    QCOMPARE(reference, result);

    // We test the emission of the backgroundColorChanged signal.
    QSignalSpy spyColorChanged(wv, SIGNAL(backgroundColorChanged()));
    wv->setProperty("backgroundColor", Qt::red);
    QCOMPARE(spyColorChanged.count(), 0);
    wv->setProperty("backgroundColor", Qt::green);
    QCOMPARE(spyColorChanged.count(), 1);
}
#endif

void tst_QDeclarativeWebView::checkNoErrors(const QDeclarativeComponent& component)
{
    // Wait until the component is ready
    QTRY_VERIFY(component.isReady() || component.isError());
    if (component.isError()) {
        QList<QDeclarativeError> errors = component.errors();
        for (int ii = 0; ii < errors.count(); ++ii) {
            const QDeclarativeError &error = errors.at(ii);
            QByteArray errorStr = QByteArray::number(error.line()) + ":" +
                                  QByteArray::number(error.column()) + ":" +
                                  error.description().toUtf8();
            qWarning() << errorStr;
        }
    }
    QVERIFY(!component.isError());
}

QTEST_MAIN(tst_QDeclarativeWebView)
#include "tst_qdeclarativewebview.moc"

QT_END_NAMESPACE
