/*
    Copyright (C) 2017 Krzysztof Nowicki <krissn@op.pl>

    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.
*/

#ifndef ISOLATEDTESTBASE_H
#define ISOLATEDTESTBASE_H

#include <QObject>
#include <QString>

#include <Akonadi/KMime/SpecialMailCollections>

#include "fakeewsserver.h"

namespace Akonadi {
class AgentInstance;
}
class FakeEwsServerThread;
class OrgKdeAkonadiEwsSettingsInterface;
class OrgKdeAkonadiEwsWalletInterface;

class IsolatedTestBase : public QObject
{
    Q_OBJECT
public:
    class Folder
    {
    public:
        enum DistinguishedType {
            None,
            Root,
            Inbox,
            Outbox,
            Sent,
            Trash,
            Drafts,
            Templates,
            Calendar,
            Tasks,
            Contacts
        };

        QString id;
        QString name;
        DistinguishedType type;
        QString parentId;
    };

    typedef QVector<Folder> FolderList;

    explicit IsolatedTestBase(QObject *parent = nullptr);
    ~IsolatedTestBase() override;

    static QString loadResourceAsString(const QString &path);
protected:
    virtual void init();
    virtual void cleanup();

protected:
    QScopedPointer<FakeEwsServerThread> mFakeServerThread;
};

class TestAgentInstance : public QObject
{
    Q_OBJECT
public:
    TestAgentInstance(const QString &url);
    ~TestAgentInstance();

    const QString &identifier() const;

    bool setOnline(bool online, bool wait);
    bool isValid() const;
private:
    QScopedPointer<Akonadi::AgentInstance> mEwsInstance;
    QScopedPointer<OrgKdeAkonadiEwsSettingsInterface> mEwsSettingsInterface;
    QScopedPointer<OrgKdeAkonadiEwsWalletInterface> mEwsWalletInterface;
    QString mIdentifier;
};

class DialogEntryBase : public FakeEwsServer::DialogEntry
{
public:
    explicit DialogEntryBase(const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback())
    {
        replyCallback = callback;
        description = descr;
    }
};

class MsgRootInboxDialogEntry : public DialogEntryBase
{
public:
    explicit MsgRootInboxDialogEntry(const QString &rootId, const QString &inboxId, const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class SubscribedFoldersDialogEntry : public DialogEntryBase
{
public:
    explicit SubscribedFoldersDialogEntry(const IsolatedTestBase::FolderList &folders, const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class SpecialFoldersDialogEntry : public DialogEntryBase
{
public:
    explicit SpecialFoldersDialogEntry(const IsolatedTestBase::FolderList &folders, const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class GetTagsEmptyDialogEntry : public DialogEntryBase
{
public:
    explicit GetTagsEmptyDialogEntry(const QString &rootId, const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class SubscribeStreamingDialogEntry : public DialogEntryBase
{
public:
    explicit SubscribeStreamingDialogEntry(const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class SyncFolderHierInitialDialogEntry : public DialogEntryBase
{
public:
    explicit SyncFolderHierInitialDialogEntry(const IsolatedTestBase::FolderList &folders, const QString &syncState, const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class UnsubscribeDialogEntry : public DialogEntryBase
{
public:
    explicit UnsubscribeDialogEntry(const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

class ValidateFolderIdsDialogEntry : public DialogEntryBase
{
public:
    explicit ValidateFolderIdsDialogEntry(const QStringList &ids = QStringList(), const QString &descr = QString(), const ReplyCallback &callback = ReplyCallback());
};

#endif
