/*
 * 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>
 * Author: Aline Gondim Santos   <aline.gondimsantos@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 "mediahandleradapter.h"
#include "conversationsadapter.h"
#include "deviceitemlistmodel.h"
#include "pluginitemlistmodel.h"
#include "mediahandleritemlistmodel.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(MediaHandlerItemListModel, 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(MediaHandlerAdapter, 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;
}
