// SPDX-FileCopyrightText: 2023 g10 code GmbH
// SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later

#include <MimeTreeParserWidgets/MessageViewerDialog>
#include <QCoreApplication>
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QObject>
#include <QSignalSpy>
#include <QStandardPaths>
#include <QTest>
#include <QToolBar>

#include "../draft/draftmanager.h"
#include "../editor/composerwindow.h"
#include "../editor/recipientseditor.h"
#include "../webserver.h"
#include "../websocketclient.h"

#include <KLocalizedString>
#include <QWebSocket>
#include <QWebSocketServer>

using namespace Qt::Literals::StringLiterals;

class EmailControllerTest : public QObject
{
    Q_OBJECT

private Q_SLOTS:
    void initTestCase()
    {
        DraftManager::self(true);
        QCoreApplication::setApplicationName(u"gpgol-server"_s);

        KLocalizedString::setApplicationDomain(QByteArrayLiteral("gpgol"));

        m_webServer = new WebServer;
        m_webServer->run();

        auto webSocketServer = new QWebSocketServer(QStringLiteral("SSL Server"), QWebSocketServer::NonSecureMode);

        if (webSocketServer->listen(QHostAddress::Any, 5657)) { }
    }

    void testInfoEmailAction()
    {
        QFile file(QStringLiteral(DATA_DIR) + u"/encrypted.mbox"_s);
        QVERIFY(file.open(QIODeviceBase::ReadOnly));

        QNetworkRequest request(QUrl(u"http://127.0.0.1:%1/info"_s.arg(m_webServer->port())));
        auto reply = m_qnam.post(request, file.readAll());
        QSignalSpy spy(reply, &QNetworkReply::finished);
        spy.wait();

        qWarning() << reply->errorString();
        QCOMPARE(reply->error(), QNetworkReply::NoError);

        const auto doc = QJsonDocument::fromJson(reply->readAll());
        QVERIFY(!doc.isNull() && doc.isObject());

        const auto object = doc.object();
        QVERIFY(object["drafts"_L1].toArray().isEmpty());
        QVERIFY(object["encrypted"_L1].toBool());
        QVERIFY(!object["signed"_L1].toBool());
    }

    void testViewEmailAction()
    {
        QFile file(QStringLiteral(DATA_DIR) + u"/plaintext.mbox"_s);
        QVERIFY(file.open(QIODeviceBase::ReadOnly));

        QNetworkRequest request(QUrl(u"http://127.0.0.1:%1/view"_s.arg(m_webServer->port())));
        auto reply = m_qnam.post(request, file.readAll());
        QSignalSpy spy(reply, &QNetworkReply::finished);
        spy.wait();

        QCOMPARE(reply->error(), QNetworkReply::NoError);

        const auto widgets = qApp->topLevelWidgets();
        QVERIFY(!widgets.isEmpty());

        MimeTreeParser::Widgets::MessageViewerDialog *dialog = nullptr;
        for (auto widget : widgets) {
            if (!widget->isHidden()) {
                if (const auto messageViewer = qobject_cast<MimeTreeParser::Widgets::MessageViewerDialog *>(widget)) {
                    dialog = messageViewer;
                    break;
                }
            }
        }

        QVERIFY(dialog);

        WebsocketClient::self(QUrl(u"ws://127.0.0.1"_s), 5656);

        const auto toolBar = dialog->toolBar();
        QVERIFY(toolBar->isVisible());

        const auto actions = toolBar->actions();
        QCOMPARE(actions.count(), 3);
        qWarning() << actions;

        QCOMPARE(actions[1]->icon().name(), u"mail-reply-sender-symbolic"_s);
        actions[1]->trigger();

        const auto widgets2 = qApp->topLevelWidgets();
        QVERIFY(!widgets2.isEmpty());

        ComposerWindow *composer = nullptr;
        for (auto widget : widgets2) {
            if (!widget->isHidden()) {
                if (const auto composerWindow = qobject_cast<ComposerWindow *>(widget)) {
                    composer = composerWindow;
                    break;
                }
            }
        }
        QVERIFY(composer);

        QSignalSpy spyInit(composer, &ComposerWindow::initialized);
        spyInit.wait();

        QCOMPARE(composer->subject(), u"RE: A random subject with alternative contenttype"_s);

        const auto recipients = composer->recipientsEditor()->recipients();
        QCOMPARE(recipients.count(), 2);
        QCOMPARE(recipients[0]->email(), u"konqi@example.org"_s);
        QCOMPARE(recipients[0]->name(), u"Konqi"_s);

        QCOMPARE(recipients[1]->email(), u"konqi@kde.org"_s);
        QVERIFY(recipients[1]->name().isEmpty());
    }

    void cleanupTestCase()
    {
        m_webServer->deleteLater();
    }

private:
    WebServer *m_webServer = nullptr;
    QNetworkAccessManager m_qnam;
};

QTEST_MAIN(EmailControllerTest)
#include "emailcontrollertest.moc"
