/*
 * Copyright (C) 2015-2020 by Savoir-faire Linux
 * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
 * Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
 * Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "mainapplication.h"

#include "accountadapter.h"
#include "accountlistmodel.h"
#include "accountstomigratelistmodel.h"
#include "audiocodeclistmodel.h"
#include "audioinputdevicemodel.h"
#include "audiomanagerlistmodel.h"
#include "audiooutputdevicemodel.h"
#include "avadapter.h"
#include "bannedlistmodel.h"
#include "calladapter.h"
#include "clientwrapper.h"
#include "contactadapter.h"
#include "conversationsadapter.h"
#include "deviceitemlistmodel.h"
#include "pluginitemlistmodel.h"
#include "preferenceitemlistmodel.h"
#include "distantrenderer.h"
#include "globalinstances.h"
#include "globalsystemtray.h"
#include "messagesadapter.h"
#include "namedirectory.h"
#include "pixbufmanipulator.h"
#include "previewrenderer.h"
#include "qrimageprovider.h"
#include "settingsadaptor.h"
#include "tintedbuttonimageprovider.h"
#include "utils.h"
#include "version.h"
#include "videocodeclistmodel.h"
#include "videoformatfpsmodel.h"
#include "videoformatresolutionmodel.h"
#include "videoinputdevicemodel.h"

#include <QFontDatabase>
#include <QQmlContext>
#include <QtWebEngine>

#include <locale.h>

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

#if defined _MSC_VER && !COMPILE_ONLY
#include <gnutls/gnutls.h>
#endif

MainApplication::MainApplication(int &argc, char **argv)
    : QApplication(argc, argv)
    , engine_(new QQmlApplicationEngine())
{
    QObject::connect(this, &QApplication::aboutToQuit, [this] { exitApp(); });
}

void
MainApplication::applicationInitialization()
{
    /*
     * Some attributes are needed to be set before the creation of the application.
     */
    QApplication::setApplicationName("Ring");
    QApplication::setOrganizationDomain("jami.net");
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    QApplication::setQuitOnLastWindowClosed(false);
    QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
    QApplication::setHighDpiScaleFactorRoundingPolicy(
        Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor);
    /*
     * Initialize QtWebEngine.
     */
    QtWebEngine::initialize();
#endif
}

void
MainApplication::consoleDebug()
{
#ifdef Q_OS_WIN
    AllocConsole();
    SetConsoleCP(CP_UTF8);

    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);

    COORD coordInfo;
    coordInfo.X = 130;
    coordInfo.Y = 9000;

    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coordInfo);
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS);
#endif
}

void
MainApplication::vsConsoleDebug()
{
#ifdef _MSC_VER
    /*
     * Print debug to output window if using VS.
     */
    QObject::connect(&LRCInstance::behaviorController(),
                     &lrc::api::BehaviorController::debugMessageReceived,
                     [](const QString &message) {
                         OutputDebugStringA((message + "\n").toStdString().c_str());
                     });
#endif
}

void
MainApplication::fileDebug(QFile *debugFile)
{
    QObject::connect(&LRCInstance::behaviorController(),
                     &lrc::api::BehaviorController::debugMessageReceived,
                     [debugFile](const QString &message) {
                         if (debugFile->open(QIODevice::WriteOnly | QIODevice::Append)) {
                             auto msg = (message + "\n").toStdString().c_str();
                             debugFile->write(msg, qstrlen(msg));
                             debugFile->close();
                         }
                     });
}

void
MainApplication::exitApp()
{
    GlobalSystemTray::instance().hide();
#ifdef Q_OS_WIN
    FreeConsole();
#endif
}

char **
MainApplication::parseInputArgument(int &argc, char *argv[], char *argToParse)
{
    /*
     * Forcefully append argToParse.
     */
    int oldArgc = argc;
    argc = argc + 1 + 1;
    char **newArgv = new char *[argc];
    for (int i = 0; i < oldArgc; i++) {
        newArgv[i] = argv[i];
    }
    newArgv[oldArgc] = argToParse;
    newArgv[oldArgc + 1] = nullptr;
    return newArgv;
}

QString
MainApplication::getDebugFilePath()
{
    QDir logPath(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
    /*
     * Since logPath will be .../Ring, we use cdUp to remove it.
     */
    logPath.cdUp();
    return QString(logPath.absolutePath() + "/jami/jami.log");
}

void
MainApplication::loadTranslations()
{
    auto appDir = qApp->applicationDirPath() + "/";
    const auto locale_name = QLocale::system().name();
    const auto locale_lang = locale_name.split('_')[0];

    QTranslator *qtTranslator_lang = new QTranslator(this);
    QTranslator *qtTranslator_name = new QTranslator(this);
    if (locale_name != locale_lang) {
        if (qtTranslator_lang->load("qt_" + locale_lang,
                                    QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
            installTranslator(qtTranslator_lang);
    }
    qtTranslator_name->load("qt_" + locale_name,
                            QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    installTranslator(qtTranslator_name);

    QTranslator *lrcTranslator_lang = new QTranslator(this);
    QTranslator *lrcTranslator_name = new QTranslator(this);
    if (locale_name != locale_lang) {
        if (lrcTranslator_lang->load(appDir + "share/libringclient/translations/lrc_" + locale_lang))
            installTranslator(lrcTranslator_lang);
    }
    if (lrcTranslator_name->load(appDir + "share/libringclient/translations/lrc_" + locale_name))
        installTranslator(lrcTranslator_name);

    QTranslator *mainTranslator_lang = new QTranslator(this);
    QTranslator *mainTranslator_name = new QTranslator(this);
    if (locale_name != locale_lang) {
        if (mainTranslator_lang->load(appDir + "share/ring/translations/ring_client_windows_"
                                      + locale_lang))
            installTranslator(mainTranslator_lang);
    }
    if (mainTranslator_name->load(appDir + "share/ring/translations/ring_client_windows_"
                                  + locale_name))
        installTranslator(mainTranslator_name);
}

void
MainApplication::initLrc()
{
    /*
     * Init mainwindow and finish splash when mainwindow shows up.
     */
    std::atomic_bool isMigrating(false);
    LRCInstance::init(
        [this, &isMigrating] {
            /*
             * TODO: splash screen for account migration.
             */
            isMigrating = true;
            while (isMigrating) {
                this->processEvents();
            }
        },
        [this, &isMigrating] {
            while (!isMigrating) {
                std::this_thread::sleep_for(std::chrono::milliseconds(10));
            }
            isMigrating = false;
        });
    LRCInstance::subscribeToDebugReceived();
    LRCInstance::getAPI().holdConferences = false;
}

void
MainApplication::processInputArgument(bool &startMinimized)
{
    debugFile_ = std::make_unique<QFile>(getDebugFilePath());
    QString uri = "";

    for (auto string : QCoreApplication::arguments()) {
        if (string.startsWith("jami:")) {
            uri = string;
        } else {
            if (string == "-m" || string == "--minimized") {
                startMinimized = true;
            }
            auto dbgFile = string == "-f" || string == "--file";
            auto dbgConsole = string == "-c" || string == "--vsconsole";
            if (dbgFile || dbgConsole) {
                if (dbgFile) {
                    debugFile_->open(QIODevice::WriteOnly | QIODevice::Truncate);
                    debugFile_->close();
                    fileDebug(debugFile_.get());
                }
#ifdef _MSC_VER
                if (dbgConsole) {
                    vsConsoleDebug();
                }
#endif
            }
        }
    }
}

void
MainApplication::setApplicationFont()
{
    QFont font;
    font.setFamily("Segoe UI");
    setFont(font);
    QFontDatabase::addApplicationFont(":/images/FontAwesome.otf");
}

void
MainApplication::qmlInitialization()
{
    /*
     * Register accountListModel type.
     */
    QML_REGISTERTYPE(AccountListModel, 1, 0);
    QML_REGISTERTYPE(DeviceItemListModel, 1, 0);
    QML_REGISTERTYPE(PluginItemListModel, 1, 0);
    QML_REGISTERTYPE(PreferenceItemListModel, 1, 0);
    QML_REGISTERTYPE(BannedListModel, 1, 0);
    QML_REGISTERTYPE(VideoCodecListModel, 1, 0);
    QML_REGISTERTYPE(AudioCodecListModel, 1, 0);
    QML_REGISTERTYPE(AccountsToMigrateListModel, 1, 0);
    QML_REGISTERTYPE(AudioInputDeviceModel, 1, 0);
    QML_REGISTERTYPE(AudioOutputDeviceModel, 1, 0);
    QML_REGISTERTYPE(AudioManagerListModel, 1, 0);
    QML_REGISTERTYPE(VideoInputDeviceModel, 1, 0);
    QML_REGISTERTYPE(VideoFormatResolutionModel, 1, 0);
    QML_REGISTERTYPE(VideoFormatFpsModel, 1, 0);
    /*
     * Register QQuickItem type.
     */
    QML_REGISTERTYPE(PreviewRenderer, 1, 0);
    QML_REGISTERTYPE(VideoCallPreviewRenderer, 1, 0);
    QML_REGISTERTYPE(DistantRenderer, 1, 0);
    QML_REGISTERTYPE(PhotoboothPreviewRender, 1, 0)

    /*
     * Adapter - qmlRegisterSingletonType.
     * Note: in future, if lrc is fully compatible with qml (C++ struct
     *       is readable in qml), the adapters can be optimized away.
     */
    QML_REGISTERSINGLETONTYPE_URL(QStringLiteral("qrc:/src/constant/JamiTheme.qml"),
                                  JamiTheme,
                                  1,
                                  0);
    QML_REGISTERSINGLETONTYPE(CallAdapter, 1, 0);

    QML_REGISTERSINGLETONTYPE(MessagesAdapter, 1, 0);
    QML_REGISTERSINGLETONTYPE(ConversationsAdapter, 1, 0);
    QML_REGISTERSINGLETONTYPE(AvAdapter, 1, 0);
    QML_REGISTERSINGLETONTYPE(ContactAdapter, 1, 0);
    QML_REGISTERSINGLETONTYPE(ClientWrapper, 1, 0);

    //QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(AccountAdapter, 1, 0);
    //QML_REGISTERSINGLETONTYPE_WITH_INSTANCE(UtilsAdapter, 1, 0);
    QML_REGISTERUNCREATABLE(AccountAdapter, 1, 0);
    QML_REGISTERUNCREATABLE(UtilsAdapter, 1, 0);
    QML_REGISTERUNCREATABLE(SettingsAdaptor, 1, 0);
    QML_REGISTERUNCREATABLE(NameDirectory, 1, 0);
    QML_REGISTERUNCREATABLE(LRCInstance, 1, 0);

    /*
     * Lrc models - qmlRegisterUncreatableType & Q_DECLARE_METATYPE.
     * This to make lrc models recognizable in qml.
     */
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewAccountModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(BehaviorController, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(DataTransferModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(AVModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ContactModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(ConversationModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCallModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(PluginModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewDeviceModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(NewCodecModel, lrc::api, 1, 0);
    QML_REGISTERUNCREATABLE_IN_NAMESPACE(PeerDiscoveryModel, lrc::api, 1, 0);

    /*
     * Client models - qmlRegisterUncreatableType & Q_DECLARE_METATYPE.
     * This to make client models recognizable in qml.
     */
    QML_REGISTERUNCREATABLE(RenderManager, 1, 0);

    /*
     * Namespaces - qmlRegisterUncreatableMetaObject.
     */
    QML_REGISTERNAMESPACE(lrc::api::staticMetaObject, "Lrc", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::account::staticMetaObject, "Account", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::call::staticMetaObject, "Call", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::datatransfer::staticMetaObject, "Datatransfer", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::interaction::staticMetaObject, "Interaction", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::video::staticMetaObject, "Video", 1, 0);
    QML_REGISTERNAMESPACE(lrc::api::profile::staticMetaObject, "Profile", 1, 0);

    /*
     * Add image provider.
     */
    engine_->addImageProvider(QLatin1String("qrImage"), new QrImageProvider());
    engine_->addImageProvider(QLatin1String("tintedPixmap"), new TintedButtonImageProvider());

    engine_->load(QUrl(QStringLiteral("qrc:/src/MainApplicationWindow.qml")));
}

MainApplication::~MainApplication() {}

bool
MainApplication::applicationSetup()
{
#ifdef Q_OS_LINUX
    if (!getenv("QT_QPA_PLATFORMTHEME"))
        setenv("QT_QPA_PLATFORMTHEME", "gtk3", true);
#endif

    /*
     * Start debug console.
     */
    for (auto string : QCoreApplication::arguments()) {
        if (string == "-d" || string == "--debug") {
            consoleDebug();
        }
    }

    /*
     * Remove old version files.
     */
    Utils::removeOldVersions();

    /*
     * Load translations.
     */
    loadTranslations();

    /*
     * Set font.
     */
    setApplicationFont();

#if defined _MSC_VER && !COMPILE_ONLY
    gnutls_global_init();
#endif

    /*
     * Init pixmap manipulator.
     */
    GlobalInstances::setPixmapManipulator(std::make_unique<PixbufManipulator>());

    /*
     * Init lrc and its possible migration ui.
     */
    initLrc();

    /*
     * Process input argument.
     */
    bool startMinimized{false};
    processInputArgument(startMinimized);

    /*
     * Create jami.net settings in Registry if it is not presented.
     */
    QSettings settings("jami.net", "Jami");

    /*
     * Initialize qml components.
     */
    qmlInitialization();

    return true;
}
