/*
 * Copyright (C) 2010, 2011, Pino Toscano <pino@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include <QtTest/QtTest>

#include <poppler-qt5.h>
#include <poppler-private.h>

#include <GlobalParams.h>

Q_DECLARE_METATYPE(GooString*)
Q_DECLARE_METATYPE(Unicode*)

class TestStrings : public QObject
{
    Q_OBJECT

public:
    TestStrings(QObject *parent = nullptr) : QObject(parent) { }

private slots:
    void initTestCase();
    void cleanupTestCase();
    void check_unicodeToQString_data();
    void check_unicodeToQString();
    void check_UnicodeParsedString_data();
    void check_UnicodeParsedString();
    void check_QStringToUnicodeGooString_data();
    void check_QStringToUnicodeGooString();
    void check_QStringToGooString_data();
    void check_QStringToGooString();

private:
    GooString* newGooString(const char *s);
    GooString* newGooString(const char *s, int l);

    QVector<GooString *> m_gooStrings;
};

void TestStrings::initTestCase()
{
    qRegisterMetaType<GooString*>("GooString*");
    qRegisterMetaType<Unicode*>("Unicode*");

    globalParams = new GlobalParams();
}

void TestStrings::cleanupTestCase()
{
    qDeleteAll(m_gooStrings);

    delete globalParams;
}

void TestStrings::check_unicodeToQString_data()
{
    QTest::addColumn<Unicode*>("data");
    QTest::addColumn<int>("length");
    QTest::addColumn<QString>("result");

    {
    const int l = 1;
    Unicode *u = new Unicode[l];
    u[0] = int('a');
    QTest::newRow("a") << u << l << QStringLiteral("a");
    }
    {
    const int l = 1;
    Unicode *u = new Unicode[l];
    u[0] = 0x0161;
    QTest::newRow("\u0161") << u << l << QStringLiteral("\u0161");
    }
    {
    const int l = 2;
    Unicode *u = new Unicode[l];
    u[0] = int('a');
    u[1] = int('b');
    QTest::newRow("ab") << u << l << QStringLiteral("ab");
    }
    {
    const int l = 2;
    Unicode *u = new Unicode[l];
    u[0] = int('a');
    u[1] = 0x0161;
    QTest::newRow("a\u0161") << u << l << QStringLiteral("a\u0161");
    }
    {
    const int l = 2;
    Unicode *u = new Unicode[l];
    u[0] = 0x5c01;
    u[1] = 0x9762;
    QTest::newRow("\xe5\xb0\x81\xe9\x9d\xa2") << u << l << QStringLiteral("封面");
    }
    {
    const int l = 3;
    Unicode *u = new Unicode[l];
    u[0] = 0x5c01;
    u[1] = 0x9762;
    u[2] = 0x0;
    QTest::newRow("\xe5\xb0\x81\xe9\x9d\xa2 + 0") << u << l << QStringLiteral("封面");
    }
}

void TestStrings::check_unicodeToQString()
{
    QFETCH(Unicode*, data);
    QFETCH(int, length);
    QFETCH(QString, result);

    QCOMPARE(Poppler::unicodeToQString(data, length), result);

    delete [] data;
}

void TestStrings::check_UnicodeParsedString_data()
{
    QTest::addColumn<GooString*>("string");
    QTest::addColumn<QString>("result");

    // non-unicode strings
    QTest::newRow("<empty>") << newGooString("")
                             << QString();
    QTest::newRow("a") << newGooString("a")
                       << QStringLiteral("a");
    QTest::newRow("ab") << newGooString("ab")
                        << QStringLiteral("ab");
    QTest::newRow("~") << newGooString("~")
                       << QStringLiteral("~");
    QTest::newRow("test string") << newGooString("test string")
                                 << QStringLiteral("test string");

    // unicode strings
    QTest::newRow("<unicode marks>") << newGooString("\xFE\xFF")
                                     << QString();
    QTest::newRow("U a") << newGooString("\xFE\xFF\0a", 4)
                         << QStringLiteral("a");
    QTest::newRow("U ~") << newGooString("\xFE\xFF\0~", 4)
                         << QStringLiteral("~");
    QTest::newRow("U aa") << newGooString("\xFE\xFF\0a\0a", 6)
                           << QStringLiteral("aa");
    QTest::newRow("U \xC3\x9F") << newGooString("\xFE\xFF\0\xDF", 4)
                                << QStringLiteral("ß");
    QTest::newRow("U \xC3\x9F\x61") << newGooString("\xFE\xFF\0\xDF\0\x61", 6)
                                    << QStringLiteral("ßa");
    QTest::newRow("U \xC5\xA1") << newGooString("\xFE\xFF\x01\x61", 4)
                                << QStringLiteral("š");
    QTest::newRow("U \xC5\xA1\x61") << newGooString("\xFE\xFF\x01\x61\0\x61", 6)
                                << QStringLiteral("ša");
    QTest::newRow("test string") << newGooString("\xFE\xFF\0t\0e\0s\0t\0 \0s\0t\0r\0i\0n\0g", 24)
                                 << QStringLiteral("test string");
    QTest::newRow("UTF16-LE") << newGooString("\xFF\xFE\xDA\x00\x6E\x00\xEE\x00\x63\x00\xF6\x00\x64\x00\xE9\x00\x51\x75", 18)
                                 << QStringLiteral("Únîcödé畑");
}

void TestStrings::check_UnicodeParsedString()
{
    QFETCH(GooString*, string);
    QFETCH(QString, result);

    QCOMPARE(Poppler::UnicodeParsedString(string), result);
}

void TestStrings::check_QStringToUnicodeGooString_data()
{
    QTest::addColumn<QString>("string");
    QTest::addColumn<QByteArray>("result");


    QTest::newRow("<null>") << QString()
                            << QByteArray("");
    QTest::newRow("<empty>") << QString(QLatin1String(""))
                             << QByteArray("");
    QTest::newRow("a") << QStringLiteral("a")
                       << QByteArray("\0a", 2);
    QTest::newRow("ab") << QStringLiteral("ab")
                        << QByteArray("\0a\0b", 4);
    QTest::newRow("test string") << QStringLiteral("test string")
                                 << QByteArray("\0t\0e\0s\0t\0 \0s\0t\0r\0i\0n\0g", 22);
    QTest::newRow("\xC3\x9F") << QStringLiteral("ß")
                              << QByteArray("\0\xDF", 2);
    QTest::newRow("\xC3\x9F\x61") << QStringLiteral("ßa")
                                  << QByteArray("\0\xDF\0\x61", 4);
}

void TestStrings::check_QStringToUnicodeGooString()
{
    QFETCH(QString, string);
    QFETCH(QByteArray, result);

    GooString *goo = Poppler::QStringToUnicodeGooString(string);
    QVERIFY(goo->hasUnicodeMarker());
    QCOMPARE(goo->getLength(), string.length() * 2 + 2);
    QCOMPARE(result, QByteArray::fromRawData(goo->c_str() + 2, goo->getLength() - 2));

    delete goo;
}

void TestStrings::check_QStringToGooString_data()
{
    QTest::addColumn<QString>("string");
    QTest::addColumn<GooString*>("result");

    QTest::newRow("<null>") << QString()
                            << newGooString("");
    QTest::newRow("<empty>") << QString(QLatin1String(""))
                             << newGooString("");
    QTest::newRow("a") << QStringLiteral("a")
                       << newGooString("a");
    QTest::newRow("ab") << QStringLiteral("ab")
                        << newGooString("ab");
}

void TestStrings::check_QStringToGooString()
{
    QFETCH(QString, string);
    QFETCH(GooString*, result);

    GooString *goo = Poppler::QStringToGooString(string);
    QCOMPARE(goo->c_str(), result->c_str());

    delete goo;
}

GooString* TestStrings::newGooString(const char *s)
{
    GooString *goo = new GooString(s);
    m_gooStrings.append(goo);
    return goo;
}

GooString* TestStrings::newGooString(const char *s, int l)
{
    GooString *goo = new GooString(s, l);
    m_gooStrings.append(goo);
    return goo;
}

QTEST_GUILESS_MAIN(TestStrings)

#include "check_strings.moc"
