/*
    This file is part of the KContacts framework.
    Copyright (c) 2012 Kevin Krammer <krammer@kde.org>

    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 "addressee.h"
#include "converter/vcardconverter.h"

#include <qtest.h>
#include <QDir>
#include <QObject>

using namespace KContacts;

class RoundtripTest : public QObject
{
    Q_OBJECT

private:

    QDir mInputDir;
    QDir mOutput2_1Dir;
    QDir mOutput3_0Dir;
    QDir mOutput4_0Dir;

    QStringList mInputFiles;

private Q_SLOTS:
    void initTestCase();
    void testVCardRoundtrip_data();
    void testVCardRoundtrip();
};

// check the validity of our test data set
void RoundtripTest::initTestCase()
{

    // check that all resource prefixes exist

    mInputDir = QDir(QStringLiteral(":/input"));
    QVERIFY(mInputDir.exists());
    QVERIFY(mInputDir.cd(QStringLiteral("data")));

    mOutput2_1Dir = QDir(QStringLiteral(":/output2.1"));
    QVERIFY(mOutput2_1Dir.exists());
    QVERIFY(mOutput2_1Dir.cd(QStringLiteral("data")));

    mOutput3_0Dir = QDir(QStringLiteral(":/output3.0"));
    QVERIFY(mOutput3_0Dir.exists());
    QVERIFY(mOutput3_0Dir.cd(QStringLiteral("data")));

    mOutput4_0Dir = QDir(QStringLiteral(":/output4.0"));
    QVERIFY(mOutput4_0Dir.exists());
    QVERIFY(mOutput4_0Dir.cd(QStringLiteral("data")));

    // check that there are input files

    mInputFiles = mInputDir.entryList();

    QVERIFY(!mInputFiles.isEmpty());
}

void RoundtripTest::testVCardRoundtrip_data()
{
    QTest::addColumn<QString>("inputFile");
    QTest::addColumn<QString>("output2_1File");
    QTest::addColumn<QString>("output3_0File");
    QTest::addColumn<QString>("output4_0File");

    QString outFile21Pattern = QLatin1String("%1.2_1ref");
    QString outFile4Pattern = QLatin1String("v4_0.%1.ref");
    QString outFilePattern = QLatin1String("%1.ref");
    Q_FOREACH (const QString &inputFile, mInputFiles) {
        const QString outFile = outFilePattern.arg(inputFile);
        const QString outFileV2_1 = outFile21Pattern.arg(inputFile);
        const QString outFileV4 = outFile4Pattern.arg(inputFile);
        QTest::newRow(QFile::encodeName(inputFile).constData())
                << inputFile
                << (mOutput2_1Dir.exists(outFileV2_1) ? outFileV2_1 : QString())
                << (mOutput3_0Dir.exists(outFile) ? outFile : QString())
                << (mOutput4_0Dir.exists(outFileV4) ? outFileV4 : QString());
    }
}

void RoundtripTest::testVCardRoundtrip()
{
    QFETCH(QString, inputFile);
    QFETCH(QString, output2_1File);
    QFETCH(QString, output3_0File);
    QFETCH(QString, output4_0File);

    QVERIFY2(!output2_1File.isEmpty()
             || !output3_0File.isEmpty()
             || !output4_0File.isEmpty(),
             "No reference output file for either format version");

    QFile input(QFileInfo(mInputDir, inputFile).absoluteFilePath());
    QVERIFY(input.open(QIODevice::ReadOnly));

    const QByteArray inputData = input.readAll();
    QVERIFY(!inputData.isEmpty());

    VCardConverter converter;
    const Addressee::List list = converter.parseVCards(inputData);
    QVERIFY(!list.isEmpty());

    if (!output2_1File.isEmpty()) {
        const QByteArray outputData = converter.createVCards(list, VCardConverter::v2_1);

        QFile outputFile(QFileInfo(mOutput2_1Dir, output2_1File).absoluteFilePath());
        QVERIFY(outputFile.open(QIODevice::ReadOnly));

        const QByteArray outputRefData = outputFile.readAll();
        QCOMPARE(outputData.size(), outputRefData.size());

        const QList<QByteArray> outputLines = outputData.split('\n');
        const QList<QByteArray> outputRefLines = outputRefData.split('\n');
        QCOMPARE(outputLines.count(), outputRefLines.count());
        for (int i = 0; i < outputLines.count(); ++i) {
            const QByteArray actual = outputLines[i];
            const QByteArray expect = outputRefLines[i];

            if (actual != expect) {
                qCritical() << "Mismatch in v2.1 output line" << (i + 1);
                QCOMPARE(actual.count(), expect.count());

                qCritical() << "\nActual:" << actual << "\nExpect:" << expect;
                QCOMPARE(actual, expect);
            }
        }
    }

    if (!output3_0File.isEmpty()) {
        const QByteArray outputData = converter.createVCards(list, VCardConverter::v3_0);

        QFile outputFile(QFileInfo(mOutput3_0Dir, output3_0File).absoluteFilePath());
        QVERIFY(outputFile.open(QIODevice::ReadOnly));

        const QByteArray outputRefData = outputFile.readAll();
        QCOMPARE(outputData.size(), outputRefData.size());

        const QList<QByteArray> outputLines = outputData.split('\n');
        const QList<QByteArray> outputRefLines = outputRefData.split('\n');
        QCOMPARE(outputLines.count(), outputRefLines.count());

        for (int i = 0; i < outputLines.count(); ++i) {
            const QByteArray actual = outputLines[i];
            const QByteArray expect = outputRefLines[i];

            if (actual != expect) {
                qCritical() << "Mismatch in v3.0 output line" << (i + 1);

                qCritical() << "\nActual:" << actual << "\nExpect:" << expect;
                QCOMPARE(actual.count(), expect.count());
                QCOMPARE(actual, expect);
            }
        }
    }
#if 0
    if (!output4_0File.isEmpty()) {
        const QByteArray outputData = converter.createVCards(list, VCardConverter::v4_0);

        QFile outputFile(QFileInfo(mOutput4_0Dir, output4_0File).absoluteFilePath());
        QVERIFY(outputFile.open(QIODevice::ReadOnly));

        const QByteArray outputRefData = outputFile.readAll();
        //QCOMPARE( outputData.size(), outputRefData.size() );

        const QList<QByteArray> outputLines = outputData.split('\n');
        const QList<QByteArray> outputRefLines = outputRefData.split('\n');
        //QCOMPARE(outputLines.count(), outputRefLines.count());

        for (int i = 0; i < outputLines.count(); ++i) {
            const QByteArray actual = outputLines[i];
            const QByteArray expect = outputRefLines[i];

            if (actual != expect) {
                qCritical() << "Mismatch in v4.0 output line" << (i + 1);

                qCritical() << "\nActual:" << actual << "\nExpect:" << expect;
                QCOMPARE(actual.count(), expect.count());
                QCOMPARE(actual, expect);
            }
        }
    }
#endif
}

QTEST_MAIN(RoundtripTest)

#include "testroundtrip.moc"
