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

#include "controllers/emailcontroller.h"

#include <KLocalizedString>
#include <Libkleo/KeyCache>
#include <QApplication>
#include <QHttpServer>
#include <QHttpServerResponse>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkReply>
#include <QPointer>
#include <QTimer>
#include <QUuid>

#include "config.h"
#include "firsttimedialog.h"
#include "gpgol_client_debug.h"
#include "qnam.h"
#include "utils/kuniqueservice.h"
#include "webserver.h"
#include "websocketclient.h"

using namespace Qt::Literals::StringLiterals;
using namespace std::chrono;

#ifdef Q_OS_WINDOWS
#include <windows.h>
#endif

#define STARTUP_TIMING qCDebug(GPGOL_CLIENT_LOG) << "Startup timing:" << startupTimer.elapsed() << "ms:"
#define STARTUP_TRACE qCDebug(GPGOL_CLIENT_LOG) << "Startup timing:" << startupTimer.elapsed() << "ms:" << SRCNAME << __func__ << __LINE__;

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setOrganizationDomain(QStringLiteral("kde.org"));
    app.setQuitOnLastWindowClosed(false);

    QElapsedTimer startupTimer;
    startupTimer.start();

    STARTUP_TIMING << "Application created";
    /* Create the unique service ASAP to prevent double starts if
     * the application is started twice very quickly. */
    KUniqueService service;
    STARTUP_TIMING << "Service created";

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

    QObject::connect(qnam, &QNetworkAccessManager::sslErrors, qnam, [](QNetworkReply *reply, const QList<QSslError> &) {
        reply->ignoreSslErrors();
    });

#ifdef Q_OS_WINDOWS
    if (AttachConsole(ATTACH_PARENT_PROCESS)) {
        freopen("CONOUT$", "w", stdout);
        freopen("CONOUT$", "w", stderr);
    }
#endif

    const auto clientId = QUuid::createUuid().toString(QUuid::WithoutBraces);

    STARTUP_TIMING << "Server start";
    WebServer server;
    server.run();
    if (!server.running()) {
        qWarning() << "Server failed to listen on a port.";
        return 1;
    }
    const auto port = server.port();
    STARTUP_TIMING << "Server running";

    STARTUP_TIMING << "KeyCache creation";
    WebsocketClient::self(QUrl(u"wss://localhost:5657/"_s), port, clientId);
    auto keyCache = Kleo::KeyCache::mutableInstance();
    keyCache->startKeyListing();

    if (Config::self()->showLauncher()) {
        QPointer<FirstTimeDialog> launcher = new FirstTimeDialog;
        QObject::connect(&WebsocketClient::self(), &WebsocketClient::stateChanged, launcher.get(), &FirstTimeDialog::slotStateChanged);
        launcher->show();
    }

    return app.exec();
}
