
#ifndef _WIN32
#include <unistd.h>
#else
#include <windows.h>
#define sleep Sleep
#endif
#include <time.h>

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

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include <QtGui/QImage>

class SillyThread : public QThread
{
public:
    SillyThread(Poppler::Document* document, QObject* parent = 0);

    void run();

private:
    Poppler::Document* m_document;
    QVector< Poppler::Page* > m_pages;

};

class CrazyThread : public QThread
{
public:
    CrazyThread(uint seed, Poppler::Document* document, QMutex* annotationMutex, QObject* parent = 0);

    void run();

private:
    uint m_seed;
    Poppler::Document* m_document;
    QMutex* m_annotationMutex;

};

static Poppler::Page* loadPage(Poppler::Document* document, int index)
{
    Poppler::Page* page = document->page(index);

    if(page == 0)
    {
        qDebug() << "!Document::page";
        
        exit(EXIT_FAILURE);
    }

    return page;
}

static Poppler::Page* loadRandomPage(Poppler::Document* document)
{
    return loadPage(document, qrand() % document->numPages());
}

SillyThread::SillyThread(Poppler::Document* document, QObject* parent) : QThread(parent),
    m_document(document),
    m_pages()
{
    m_pages.reserve(m_document->numPages());

    for(int index = 0; index < m_document->numPages(); ++index)
    {
        m_pages.append(loadPage(m_document, index));
    }
}


void SillyThread::run()
{
    forever
    {
        foreach(Poppler::Page* page, m_pages)
        {
            QImage image = page->renderToImage();

            if(image.isNull())
            {
                qDebug() << "!Page::renderToImage";
                
                ::exit(EXIT_FAILURE);
            }
        }
    }
}

CrazyThread::CrazyThread(uint seed, Poppler::Document* document, QMutex* annotationMutex, QObject* parent) : QThread(parent),
    m_seed(seed),
    m_document(document),
    m_annotationMutex(annotationMutex)
{
}

void CrazyThread::run()
{
    typedef QScopedPointer< Poppler::Page > PagePointer;

    qsrand(m_seed);

    forever
    {
        if(qrand() % 2 == 0)
        {
            qDebug() << "search...";

            PagePointer page(loadRandomPage(m_document));

            page->search("c", Poppler::Page::CaseInsensitive);
            page->search("r", Poppler::Page::CaseSensitive);
            page->search("a", Poppler::Page::CaseInsensitive);
            page->search("z", Poppler::Page::CaseSensitive);
            page->search("y", Poppler::Page::CaseInsensitive);
        }

        if(qrand() % 2 == 0)
        {
            qDebug() << "links...";

            PagePointer page(loadRandomPage(m_document));

            QList< Poppler::Link* > links = page->links();

            qDeleteAll(links);
        }

        if(qrand() % 2 == 0)
        {
            qDebug() << "form fields...";

            PagePointer page(loadRandomPage(m_document));

            QList< Poppler::FormField* > formFields = page->formFields();

            qDeleteAll(formFields);
        }

        if(qrand() % 2 == 0)
        {
            qDebug() << "thumbnail...";

            PagePointer page(loadRandomPage(m_document));

            page->thumbnail();
        }

        if(qrand() % 2 == 0)
        {
            qDebug() << "text...";

            PagePointer page(loadRandomPage(m_document));

            page->text(QRectF(QPointF(), page->pageSizeF()));
        }

        if(qrand() % 2 == 0)
        {
            QMutexLocker mutexLocker(m_annotationMutex);
            
            qDebug() << "add annotation...";

            PagePointer page(loadRandomPage(m_document));

            Poppler::Annotation* annotation = 0;

            switch(qrand() % 3)
            {
            default:
            case 0:
                annotation = new Poppler::TextAnnotation(qrand() % 2 == 0 ? Poppler::TextAnnotation::Linked : Poppler::TextAnnotation::InPlace);
                break;
            case 1:
                annotation = new Poppler::HighlightAnnotation();
                break;
            case 2:
                annotation = new Poppler::InkAnnotation();
                break;
            }

            annotation->setBoundary(QRectF(0.0, 0.0, 0.5, 0.5));
            annotation->setContents("crazy");

            page->addAnnotation(annotation);

            delete annotation;
        }

        if(qrand() % 2 == 0)
        {
            QMutexLocker mutexLocker(m_annotationMutex);
            
            for(int index = 0; index < m_document->numPages(); ++index)
            {
                PagePointer page(loadPage(m_document, index));

                QList< Poppler::Annotation* > annotations = page->annotations();

                if(!annotations.isEmpty())
                {
                    qDebug() << "modify annotation...";

                    annotations.at(qrand() % annotations.size())->setBoundary(QRectF(0.5, 0.5, 0.25, 0.25));
                    annotations.at(qrand() % annotations.size())->setAuthor("foo");
                    annotations.at(qrand() % annotations.size())->setContents("bar");
                    annotations.at(qrand() % annotations.size())->setCreationDate(QDateTime::currentDateTime());
                    annotations.at(qrand() % annotations.size())->setModificationDate(QDateTime::currentDateTime());
                }

                qDeleteAll(annotations);

                if(!annotations.isEmpty())
                {
                    break;
                }
            }
        }

        if(qrand() % 2 == 0)
        {
            QMutexLocker mutexLocker(m_annotationMutex);
            
            for(int index = 0; index < m_document->numPages(); ++index)
            {
                PagePointer page(loadPage(m_document, index));

                QList< Poppler::Annotation* > annotations = page->annotations();

                if(!annotations.isEmpty())
                {
                    qDebug() << "remove annotation...";

                    page->removeAnnotation(annotations.takeAt(qrand() % annotations.size()));
                }

                qDeleteAll(annotations);

                if(!annotations.isEmpty())
                {
                    break;
                }
            }
        }

        if(qrand() % 2 == 0)
        {
            qDebug() << "fonts...";

            m_document->fonts();
        }
    }
}

int main(int argc, char** argv)
{
    if(argc < 5)
    {
        qDebug() << "usage: stress-threads-qt duration sillyCount crazyCount file(s)";
        
        return EXIT_FAILURE;
    }

    const int duration = atoi(argv[1]);
    const int sillyCount = atoi(argv[2]);
    const int crazyCount = atoi(argv[3]);
    
    qsrand(time(0));

    for(int argi = 4; argi < argc; ++argi)
    {
        const QString file = QFile::decodeName(argv[argi]);
        Poppler::Document* document = Poppler::Document::load(file);

        if(document == 0)
        {
            qDebug() << "Could not load" << file;            
            continue;
        }
        
        if(document->isLocked())
        {
            qDebug() << file << "is locked";
            continue;
        }
        
        for(int i = 0; i < sillyCount; ++i)
        {
            (new SillyThread(document))->start();
        }
        
        QMutex* annotationMutex = new QMutex();

        for(int i = 0; i < crazyCount; ++i)
        {
            (new CrazyThread(qrand(), document, annotationMutex))->start();
        }
    }

    sleep(duration);

    return EXIT_SUCCESS;
}
