#include <QtTest/QtTest>

#include "Outline.h"
#include "PDFDoc.h"
#include "PDFDocFactory.h"

class TestInternalOutline : public QObject
{
    Q_OBJECT
public:
    explicit TestInternalOutline(QObject *parent = nullptr) : QObject(parent) { }
private slots:
    void testCreateOutline();
    void testSetOutline();
    void testInsertChild();
    void testRemoveChild();
    void testSetTitleAndSetPageDest();
};

void TestInternalOutline::testCreateOutline()
{
    QTemporaryFile tempFile;
    QVERIFY(tempFile.open());
    tempFile.close();

    const std::string tempFileName = tempFile.fileName().toStdString();
    const GooString gooTempFileName { tempFileName };

    std::unique_ptr<PDFDoc> doc = PDFDocFactory().createPDFDoc(GooString(TESTDATADIR "/unittestcases/truetype.pdf"));
    QVERIFY(doc.get());

    // ensure the file has no existing outline
    Outline *outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    auto *outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);

    // create an empty outline and save the file
    outline->setOutline({});
    outlineItems = outline->getItems();
    // no items will result in a nullptr rather than a 0 length list
    QVERIFY(outlineItems == nullptr);
    doc->saveAs(gooTempFileName);

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName);
    QVERIFY(doc.get());

    // ensure the re-opened file has an outline with no items
    outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);
}

static std::string getTitle(const OutlineItem *item)
{
    const Unicode *u = item->getTitle();
    std::string s;
    for (int i = 0; i < item->getTitleLength(); i++) {
        s.append(1, (char)u[i]);
    }
    return s;
}

void TestInternalOutline::testSetOutline()
{
    QTemporaryFile tempFile;
    QVERIFY(tempFile.open());
    tempFile.close();

    const std::string tempFileName = tempFile.fileName().toStdString();
    const GooString gooTempFileName { tempFileName };

    std::unique_ptr<PDFDoc> doc = PDFDocFactory().createPDFDoc(GooString(TESTDATADIR "/unittestcases/truetype.pdf"));
    QVERIFY(doc.get());

    // ensure the file has no existing outline
    Outline *outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    auto *outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);

    // create an outline and save the file
    outline->setOutline(
            { { "1", 1, { { "1.1", 1, {} }, { "1.2", 2, {} }, { "1.3", 3, { { "1.3.1", 1, {} }, { "1.3.2", 2, {} }, { "1.3.3", 3, {} }, { "1.3.4", 4, {} } } }, { "1.4", 4, {} } } }, { "2", 2, {} }, { "3", 3, {} }, { "4", 4, {} } });
    outlineItems = outline->getItems();
    QVERIFY(outlineItems != nullptr);
    doc->saveAs(gooTempFileName);
    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName);
    QVERIFY(doc.get());

    // ensure the re-opened file has an outline
    outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    outlineItems = outline->getItems();

    QVERIFY(outlineItems != nullptr);
    QVERIFY(outlineItems->size() == 4);

    OutlineItem *item = outlineItems->at(0);
    QVERIFY(item != nullptr);

    // c_str() is used so QCOMPARE prints string correctly on disagree
    QCOMPARE(getTitle(item).c_str(), "1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "3");
    item = outlineItems->at(3);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "4");

    outlineItems = outlineItems->at(0)->getKids();
    QVERIFY(outlineItems != nullptr);
    item = outlineItems->at(0);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3");
    item = outlineItems->at(3);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.4");

    outlineItems = outlineItems->at(2)->getKids();
    QVERIFY(outlineItems != nullptr);

    item = outlineItems->at(0);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.3");
    item = outlineItems->at(3);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.4");
}

void TestInternalOutline::testInsertChild()
{
    QTemporaryFile tempFile;
    QVERIFY(tempFile.open());
    tempFile.close();
    QTemporaryFile tempFile2;
    QVERIFY(tempFile2.open());
    tempFile2.close();

    const std::string tempFileName = tempFile.fileName().toStdString();
    const GooString gooTempFileName { tempFileName };
    const std::string tempFileName2 = tempFile2.fileName().toStdString();
    const GooString gooTempFileName2 { tempFileName2 };

    std::unique_ptr<PDFDoc> doc = PDFDocFactory().createPDFDoc(GooString(TESTDATADIR "/unittestcases/truetype.pdf"));
    QVERIFY(doc.get());

    // ensure the file has no existing outline
    Outline *outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    auto *outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);

    // create an outline and save the file
    outline->setOutline({});
    doc->saveAs(gooTempFileName);
    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName);
    QVERIFY(doc.get());

    // ensure the re-opened file has an outline with no items
    outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    // nullptr for 0-length
    QVERIFY(outline->getItems() == nullptr);

    // insert first one to empty
    outline->insertChild("2", 1, 0);
    // insert at the end
    outline->insertChild("3", 1, 1);
    // insert at the start
    outline->insertChild("1", 1, 0);

    // add an item to "2"
    outlineItems = outline->getItems();
    QVERIFY(outlineItems != nullptr);
    QVERIFY(outlineItems->at(1));
    outlineItems->at(1)->insertChild("2.1", 2, 0);
    outlineItems->at(1)->insertChild("2.2", 2, 1);
    outlineItems->at(1)->insertChild("2.4", 2, 2);

    outlineItems->at(1)->insertChild("2.3", 2, 2);

    // save the file
    doc->saveAs(gooTempFileName2);
    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName2);
    QVERIFY(doc.get());

    // ensure the re-opened file has an outline
    outline = doc->getOutline();
    QVERIFY(outline != nullptr);

    outlineItems = outline->getItems();

    QVERIFY(outlineItems != nullptr);
    QVERIFY(outlineItems->size() == 3);

    OutlineItem *item = outlineItems->at(0);
    QVERIFY(item != nullptr);

    // c_str() is used so QCOMPARE prints string correctly on disagree
    QCOMPARE(getTitle(item).c_str(), "1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "3");

    outlineItems = outlineItems->at(1)->getKids();
    item = outlineItems->at(0);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2.1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2.2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2.3");
    item = outlineItems->at(3);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2.4");
}

void TestInternalOutline::testRemoveChild()
{
    QTemporaryFile tempFile;
    QVERIFY(tempFile.open());
    tempFile.close();

    QTemporaryFile tempFile2;
    QVERIFY(tempFile2.open());
    tempFile2.close();

    const std::string tempFileName = tempFile.fileName().toStdString();
    const GooString gooTempFileName { tempFileName };
    const std::string tempFileName2 = tempFile2.fileName().toStdString();
    const GooString gooTempFileName2 { tempFileName2 };

    std::unique_ptr<PDFDoc> doc = PDFDocFactory().createPDFDoc(GooString(TESTDATADIR "/unittestcases/truetype.pdf"));
    QVERIFY(doc.get());

    // ensure the file has no existing outline
    Outline *outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    auto *outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);

    // create an outline and save the file
    outline->setOutline({ { "1", 1, { { "1.1", 1, {} }, { "1.2", 2, {} }, { "1.3", 3, { { "1.3.1", 1, {} }, { "1.3.2", 2, {} }, { "1.3.3", 3, {} }, { "1.3.4", 4, {} } } }, { "1.4", 4, {} } } },
                          { "2", 2, { { "2.1", 1, {} } } },
                          { "3", 3, { { "3.1", 1, {} }, { "3.2", 2, { { "3.2.1", 1, {} } } } } },
                          { "4", 4, {} } });
    outlineItems = outline->getItems();
    QVERIFY(outlineItems != nullptr);
    doc->saveAs(gooTempFileName);
    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName);
    QVERIFY(doc.get());

    outline = doc->getOutline();
    QVERIFY(outline != nullptr);

    // remove "3"
    outline->removeChild(2);
    // remove "1.3.1"
    outline->getItems()->at(0)->getKids()->at(2)->removeChild(0);
    // remove "1.3.4"
    outline->getItems()->at(0)->getKids()->at(2)->removeChild(2);
    // remove "2.1"
    outline->getItems()->at(1)->removeChild(0);

    // save the file
    doc->saveAs(gooTempFileName2);
    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName2);
    QVERIFY(doc.get());

    // ensure the re-opened file has an outline
    outline = doc->getOutline();
    QVERIFY(outline != nullptr);

    outlineItems = outline->getItems();

    QVERIFY(outlineItems != nullptr);
    QVERIFY(outlineItems->size() == 3);

    OutlineItem *item = outlineItems->at(0);
    QVERIFY(item != nullptr);

    // c_str() is used so QCOMPARE prints string correctly on disagree
    QCOMPARE(getTitle(item).c_str(), "1");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "2");
    item = outlineItems->at(2);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "4");

    outlineItems = outlineItems->at(0)->getKids();
    outlineItems = outlineItems->at(2)->getKids();
    item = outlineItems->at(0);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.2");
    item = outlineItems->at(1);
    QVERIFY(item != nullptr);
    QCOMPARE(getTitle(item).c_str(), "1.3.3");

    // verify "2.1" is removed, lst length 0 is returned as a nullptr
    QVERIFY(outline->getItems()->at(1)->getKids() == nullptr);
}

void TestInternalOutline::testSetTitleAndSetPageDest()
{
    QTemporaryFile tempFile;
    QVERIFY(tempFile.open());
    tempFile.close();

    QTemporaryFile tempFile2;
    QVERIFY(tempFile2.open());
    tempFile2.close();

    const std::string tempFileName = tempFile.fileName().toStdString();
    const GooString gooTempFileName { tempFileName };
    const std::string tempFileName2 = tempFile2.fileName().toStdString();
    const GooString gooTempFileName2 { tempFileName2 };

    std::unique_ptr<PDFDoc> doc = PDFDocFactory().createPDFDoc(GooString(TESTDATADIR "/unittestcases/truetype.pdf"));
    QVERIFY(doc.get());

    // ensure the file has no existing outline
    Outline *outline = doc->getOutline();
    QVERIFY(outline != nullptr);
    auto *outlineItems = outline->getItems();
    QVERIFY(outlineItems == nullptr);

    // create an outline and save the file
    outline->setOutline({ { "1", 1, { { "1.1", 1, {} }, { "1.2", 2, {} }, { "1.3", 3, { { "1.3.1", 1, {} }, { "1.3.2", 2, {} }, { "1.3.3", 3, {} }, { "1.3.4", 4, {} } } }, { "1.4", 4, {} } } },
                          { "2", 2, { { "2.1", 1, {} } } },
                          { "3", 3, { { "3.1", 1, {} }, { "3.2", 2, { { "3.2.1", 1, {} } } } } },
                          { "4", 4, {} } });
    outlineItems = outline->getItems();
    QVERIFY(outlineItems != nullptr);
    doc->saveAs(gooTempFileName);

    outline = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName);
    QVERIFY(doc.get());

    outline = doc->getOutline();
    QVERIFY(outline != nullptr);

    // change "1.3.1"
    OutlineItem *item = outline->getItems()->at(0)->getKids()->at(2)->getKids()->at(0);
    QCOMPARE(getTitle(item).c_str(), "1.3.1");

    item->setTitle("Changed to a different title");

    item = outline->getItems()->at(2);
    {
        const LinkAction *action = item->getAction();
        QVERIFY(action->getKind() == actionGoTo);
        const LinkGoTo *gotoAction = dynamic_cast<const LinkGoTo *>(action);
        const LinkDest *dest = gotoAction->getDest();
        QVERIFY(dest->isPageRef() == false);
        QCOMPARE(dest->getPageNum(), 3);

        item->setPageDest(1);
    }

    // save the file
    doc->saveAs(gooTempFileName2);
    outline = nullptr;
    item = nullptr;

    /******************************************************/

    doc = PDFDocFactory().createPDFDoc(gooTempFileName2);
    QVERIFY(doc.get());

    outline = doc->getOutline();
    QVERIFY(outline != nullptr);

    item = outline->getItems()->at(0)->getKids()->at(2)->getKids()->at(0);
    QCOMPARE(getTitle(item).c_str(), "Changed to a different title");
    {
        item = outline->getItems()->at(2);
        const LinkAction *action = item->getAction();
        QVERIFY(action->getKind() == actionGoTo);
        const LinkGoTo *gotoAction = dynamic_cast<const LinkGoTo *>(action);
        const LinkDest *dest = gotoAction->getDest();
        QVERIFY(dest->isPageRef() == false);
        QCOMPARE(dest->getPageNum(), 1);
    }
}

QTEST_GUILESS_MAIN(TestInternalOutline)
#include "check_internal_outline.moc"
