/*
    SPDX-FileCopyrightText: 2011 Volker Krause <vkrause@kde.org>
    SPDX-FileCopyrightText: 2014 Daniel Vrátil <dvratil@redhat.com>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#ifndef AKTEST_H
#define AKTEST_H

#include "akapplication.h"
#include <private/instance_p.h>

#include <KCrash/KCrash>

#include <QTest>

#define AKTEST_MAIN(TestObject) \
    int main(int argc, char **argv) \
    { \
        qputenv("XDG_DATA_HOME", ".local-unit-test/share"); \
        qputenv("XDG_CONFIG_HOME", ".config-unit-test"); \
        AkCoreApplication app(argc, argv); \
        KCrash::setDrKonqiEnabled(false); \
        app.parseCommandLine(); \
        TestObject tc; \
        return QTest::qExec(&tc, argc, argv); \
    }

#define AKTEST_FAKESERVER_MAIN(TestObject) \
    int main(int argc, char **argv) \
    { \
        AkCoreApplication app(argc, argv); \
        KCrash::setDrKonqiEnabled(false); \
        app.addCommandLineOptions(QCommandLineOption( \
                                  QStringLiteral("no-cleanup"), QStringLiteral("Don't clean up the temporary runtime environment"))); \
        app.parseCommandLine(); \
	TestObject tc; \
        return QTest::qExec(&tc, argc, argv); \
    }

#define AKCOMPARE(actual, expected) \
    do {\
        if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
            return false;\
    } while (false)

#define AKVERIFY(statement) \
    do {\
        if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
            return false;\
    } while (false)

inline void akTestSetInstanceIdentifier(const QString &instanceId)
{
    Akonadi::Instance::setIdentifier(instanceId);
}

#include <private/protocol_p.h>

namespace QTest
{
template<>
char *toString(const Akonadi::Protocol::ItemChangeNotificationPtr &msg)
{
    return qstrdup(qPrintable(Akonadi::Protocol::debugString(msg)));
}
}

namespace AkTest
{
enum NtfField {
    NtfType                   = (1 << 0),
    NtfOperation              = (1 << 1),
    NtfSession                = (1 << 2),
    NtfEntities               = (1 << 3),
    NtfResource               = (1 << 5),
    NtfCollection             = (1 << 6),
    NtfDestResource           = (1 << 7),
    NtfDestCollection         = (1 << 8),
    NtfAddedFlags             = (1 << 9),
    NtfRemovedFlags           = (1 << 10),
    NtfAddedTags              = (1 << 11),
    NtfRemovedTags            = (1 << 12),

    NtfFlags                  = NtfAddedFlags | NtfRemovedTags,
    NtfTags                   = NtfAddedTags | NtfRemovedTags,
    NtfAll                    = NtfType | NtfOperation | NtfSession | NtfEntities |
                                NtfResource | NtfCollection | NtfDestResource |
                                NtfDestCollection | NtfFlags | NtfTags
};
typedef QFlags<NtfField> NtfFields;

bool compareNotifications(const Akonadi::Protocol::ItemChangeNotificationPtr &actual,
                          const Akonadi::Protocol::ItemChangeNotificationPtr &expected,
                          const NtfFields fields = NtfAll)
{
    if (fields & NtfOperation) {
        AKCOMPARE(actual->operation(), expected->operation());
    }
    if (fields & NtfSession) {
        AKCOMPARE(actual->sessionId(), expected->sessionId());
    }
    if (fields & NtfEntities) {
        AKCOMPARE(actual->items(), expected->items());
    }
    if (fields & NtfResource) {
        AKCOMPARE(actual->resource(), expected->resource());
    }
    if (fields & NtfCollection) {
        AKCOMPARE(actual->parentCollection(), expected->parentCollection());
    }
    if (fields & NtfDestResource) {
        AKCOMPARE(actual->destinationResource(), expected->destinationResource());
    }
    if (fields & NtfDestCollection) {
        AKCOMPARE(actual->parentDestCollection(), expected->parentDestCollection());
    }
    if (fields & NtfAddedFlags) {
        AKCOMPARE(actual->addedFlags(), expected->addedFlags());
    }
    if (fields & NtfRemovedFlags) {
        AKCOMPARE(actual->removedFlags(), expected->removedFlags());
    }
    if (fields & NtfAddedTags) {
        AKCOMPARE(actual->addedTags(), expected->addedTags());
    }
    if (fields & NtfRemovedTags) {
        AKCOMPARE(actual->removedTags(), expected->removedTags());
    }

    return true;
}
}

#endif
