/*
    Copyright (C) 2008 Holger Hans Peter Freyther

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include <QtTest/QtTest>
#include <QAction>

#include "qwebpage.h"
#include "qwebview.h"
#include "qwebframe.h"
#include "qwebhistory.h"
#include "qdebug.h"

class tst_QWebHistory : public QObject
{
    Q_OBJECT

public:
    tst_QWebHistory();
    virtual ~tst_QWebHistory();

protected :
    void loadPage(int nr)
    {
        frame->load(QUrl("qrc:/resources/page" + QString::number(nr) + ".html"));
        waitForLoadFinished.exec();
    }

public slots:
    void init();
    void cleanup();

private slots:
    void title();
    void count();
    void back();
    void forward();
    void itemAt();
    void goToItem();
    void items();
    void serialize_1(); //QWebHistory countity
    void serialize_2(); //QWebHistory index
    void serialize_3(); //QWebHistoryItem
    void saveAndRestore_crash_1();
    void saveAndRestore_crash_2();
    void saveAndRestore_crash_3();
    void clear();


private:
    QWebPage* page;
    QWebFrame* frame;
    QWebHistory* hist;
    QEventLoop waitForLoadFinished;  //operation on history are asynchronous!
    int histsize;
};

tst_QWebHistory::tst_QWebHistory()
{
}

tst_QWebHistory::~tst_QWebHistory()
{
}

void tst_QWebHistory::init()
{
    page = new QWebPage(this);
    frame = page->mainFrame();
    connect(page, SIGNAL(loadFinished(bool)), &waitForLoadFinished, SLOT(quit()));

    for (int i = 1;i < 6;i++) {
        loadPage(i);
    }
    hist = page->history();
    histsize = 5;
}

void tst_QWebHistory::cleanup()
{
    delete page;
}

/**
  * Check QWebHistoryItem::title() method
  */
void tst_QWebHistory::title()
{
    QCOMPARE(hist->currentItem().title(), QString("page5"));
}

/**
  * Check QWebHistory::count() method
  */
void tst_QWebHistory::count()
{
    QCOMPARE(hist->count(), histsize);
}

/**
  * Check QWebHistory::back() method
  */
void tst_QWebHistory::back()
{
    for (int i = histsize;i > 1;i--) {
        QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
        hist->back();
        waitForLoadFinished.exec();
    }
    //try one more time (too many). crash test
    hist->back();
}

/**
  * Check QWebHistory::forward() method
  */
void tst_QWebHistory::forward()
{
    //rewind history :-)
    while (hist->canGoBack()) {
        hist->back();
        waitForLoadFinished.exec();
    }

    for (int i = 1;i < histsize;i++) {
        QCOMPARE(page->mainFrame()->toPlainText(), QString("page") + QString::number(i));
        hist->forward();
        waitForLoadFinished.exec();
    }
    //try one more time (too many). crash test
    hist->forward();
}

/**
  * Check QWebHistory::itemAt() method
  */
void tst_QWebHistory::itemAt()
{
    for (int i = 1;i < histsize;i++) {
        QCOMPARE(hist->itemAt(i - 1).title(), QString("page") + QString::number(i));
        QVERIFY(hist->itemAt(i - 1).isValid());
    }
    //check out of range values
    QVERIFY(!hist->itemAt(-1).isValid());
    QVERIFY(!hist->itemAt(histsize).isValid());
}

/**
  * Check QWebHistory::goToItem() method
  */
void tst_QWebHistory::goToItem()
{
    QWebHistoryItem current = hist->currentItem();
    hist->back();
    waitForLoadFinished.exec();
    hist->back();
    waitForLoadFinished.exec();
    QVERIFY(hist->currentItem().title() != current.title());
    hist->goToItem(current);
    waitForLoadFinished.exec();
    QCOMPARE(hist->currentItem().title(), current.title());
}

/**
  * Check QWebHistory::items() method
  */
void tst_QWebHistory::items() 
{
    QList<QWebHistoryItem> items = hist->items();
    //check count
    QCOMPARE(histsize, items.count());

    //check order
    for (int i = 1;i <= histsize;i++) {
        QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
    }
}

/**
  * Check history state after serialization (pickle, persistent..) method
  * Checks history size, history order
  */
void tst_QWebHistory::serialize_1() 
{
    QByteArray tmp;  //buffer
    QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved
    QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded

    save << *hist;
    QVERIFY(save.status() == QDataStream::Ok);
    QCOMPARE(hist->count(), histsize);

    //check size of history
    //load next page to find differences
    loadPage(6);
    QCOMPARE(hist->count(), histsize + 1);
    load >> *hist;
    QVERIFY(load.status() == QDataStream::Ok);
    QCOMPARE(hist->count(), histsize);

    //check order of historyItems
    QList<QWebHistoryItem> items = hist->items();
    for (int i = 1;i <= histsize;i++) {
        QCOMPARE(items.at(i - 1).title(), QString("page") + QString::number(i));
    }
}

/**
  * Check history state after serialization (pickle, persistent..) method
  * Checks history currentIndex value
  */
void tst_QWebHistory::serialize_2() 
{
    QByteArray tmp;  //buffer
    QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved
    QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded

    int oldCurrentIndex = hist->currentItemIndex();

    hist->back();
    waitForLoadFinished.exec();
    hist->back();
    waitForLoadFinished.exec();
    //check if current index was changed (make sure that it is not last item)
    QVERIFY(hist->currentItemIndex() != oldCurrentIndex);
    //save current index
    oldCurrentIndex = hist->currentItemIndex();

    save << *hist;
    QVERIFY(save.status() == QDataStream::Ok);
    load >> *hist;
    QVERIFY(load.status() == QDataStream::Ok);

    //check current index
    QCOMPARE(hist->currentItemIndex(), oldCurrentIndex);
}

/**
  * Check history state after serialization (pickle, persistent..) method
  * Checks QWebHistoryItem public property after serialization
  */
void tst_QWebHistory::serialize_3() 
{
    QByteArray tmp;  //buffer
    QDataStream save(&tmp, QIODevice::WriteOnly); //here data will be saved
    QDataStream load(&tmp, QIODevice::ReadOnly); //from here data will be loaded

    //prepare two different history items
    QWebHistoryItem a = hist->currentItem();
    a.setUserData("A - user data");

    //check properties BEFORE serialization
    QString title(a.title());
    QDateTime lastVisited(a.lastVisited());
    QUrl originalUrl(a.originalUrl());
    QUrl url(a.url());
    QVariant userData(a.userData());

    save << *hist;
    QVERIFY(save.status() == QDataStream::Ok);
    QVERIFY(!load.atEnd());
    hist->clear();
    QVERIFY(hist->count() == 1);
    load >> *hist;
    QVERIFY(load.status() == QDataStream::Ok);
    QWebHistoryItem b = hist->currentItem();

    //check properties AFTER serialization
    QCOMPARE(b.title(), title);
    QCOMPARE(b.lastVisited(), lastVisited);
    QCOMPARE(b.originalUrl(), originalUrl);
    QCOMPARE(b.url(), url);
    QCOMPARE(b.userData(), userData);

    //Check if all data was read
    QVERIFY(load.atEnd());
}

static void saveHistory(QWebHistory* history, QByteArray* in)
{
    in->clear();
    QDataStream save(in, QIODevice::WriteOnly);
    save << *history;
}

static void restoreHistory(QWebHistory* history, QByteArray* out)
{
    QDataStream load(out, QIODevice::ReadOnly);
    load >> *history;
}

/** The test shouldn't crash */
void tst_QWebHistory::saveAndRestore_crash_1()
{
    QByteArray buffer;
    saveHistory(hist, &buffer);
    for (unsigned i = 0; i < 5; i++) {
        restoreHistory(hist, &buffer);
        saveHistory(hist, &buffer);
    }
}

/** The test shouldn't crash */
void tst_QWebHistory::saveAndRestore_crash_2()
{
    QByteArray buffer;
    saveHistory(hist, &buffer);
    QWebPage* page2 = new QWebPage(this);
    QWebHistory* hist2 = page2->history();
    for (unsigned i = 0; i < 5; i++) {
        restoreHistory(hist2, &buffer);
        saveHistory(hist2, &buffer);
    }
    delete page2;
}

/** The test shouldn't crash */
void tst_QWebHistory::saveAndRestore_crash_3()
{
    QByteArray buffer;
    saveHistory(hist, &buffer);
    QWebPage* page2 = new QWebPage(this);
    QWebHistory* hist1 = hist;
    QWebHistory* hist2 = page2->history();
    for (unsigned i = 0; i < 5; i++) {
        restoreHistory(hist1, &buffer);
        restoreHistory(hist2, &buffer);
        QVERIFY(hist1->count() == hist2->count());
        QVERIFY(hist1->count() == histsize);
        hist2->back();
        saveHistory(hist2, &buffer);
        hist2->clear();
    }
    delete page2;
}

/** ::clear */
void tst_QWebHistory::clear()
{
    QByteArray buffer;

    QAction* actionBack = page->action(QWebPage::Back);
    QVERIFY(actionBack->isEnabled());
    saveHistory(hist, &buffer);
    QVERIFY(hist->count() > 1);
    hist->clear();
    QVERIFY(hist->count() == 1);  // Leave current item.
    QVERIFY(!actionBack->isEnabled());

    QWebPage* page2 = new QWebPage(this);
    QWebHistory* hist2 = page2->history();
    QVERIFY(hist2->count() == 0);
    hist2->clear();
    QVERIFY(hist2->count() == 0); // Do not change anything.
    delete page2;
}

QTEST_MAIN(tst_QWebHistory)
#include "tst_qwebhistory.moc"
