/*
 *   This file is part of Dianara
 *   Copyright 2012-2019  JanKusanagi JRR <jancoding@gmx.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 2 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, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .
 */

#include <QApplication>
#include <QTranslator>
#include <QLibraryInfo> // Include needed in some cases
#include <iostream>

#ifdef HAVE_SONNET_SPELLCHECKER
 #if __has_include(<KF5/sonnet_version.h>)
 #include <KF5/sonnet_version.h>
 #endif
#endif

#ifdef HAVE_KCHARSELECT
 #if __has_include(<KF5/kwidgetsaddons_version.h>)
 #include <KF5/kwidgetsaddons_version.h>
 #endif
#endif


#include "mainwindow.h"



void customMessageHandler(QtMsgType type,
                          const QMessageLogContext &context,
                          const QString &msg)
{
    Q_UNUSED(type)
    Q_UNUSED(context)
    Q_UNUSED(msg)

    // Do nothing

    return;
}



int main(int argc, char *argv[])
{
    QApplication dianaraApp(argc, argv);
    dianaraApp.setApplicationName(QStringLiteral("Dianara"));
    dianaraApp.setApplicationVersion(QStringLiteral("1.4.3"));
    dianaraApp.setOrganizationName(QStringLiteral("JanCoding"));
    dianaraApp.setOrganizationDomain(QStringLiteral("jancoding.wordpress.com"));
    // This is mainly needed for window managers under Wayland
    dianaraApp.setDesktopFileName(QStringLiteral("org.nongnu.dianara.desktop"));

    std::cout << QString("Dianara v%1 - JanKusanagi 2012-2019\n"
                         "https://jancoding.wordpress.com/dianara\n\n")
                 .arg(dianaraApp.applicationVersion())
                 .toStdString();

    std::cout << QString("- Built with Qt v%1").arg(QT_VERSION_STR)
                                               .toStdString();

/*
 * REPRODUCIBLEBUILD is defined via .pro file when SOURCE_DATE_EPOCH is
 * defined in the build environment. This is used to avoid hardcoding
 * timestamps and this way make the builds reproducible.
 *
 */
#ifndef REPRODUCIBLEBUILD
    std::cout << QString(" on %1, %2")
                 .arg(__DATE__)
                 .arg(__TIME__).toStdString();
#endif
    std::cout << "\n";

    std::cout << QString("- Running with Qt v%1\n").arg(qVersion())
                                                   .toStdString();
    std::cout << QString("- Qt Platform plugin in use: %1\n\n")
                 .arg(qApp->platformName()).toStdString();
    std::cout.flush();

#ifdef HAVE_SONNET_SPELLCHECKER
    std::cout << "* Built with Sonnet spell checking support";
 #ifdef SONNET_VERSION_STRING
    std::cout << ": v" << SONNET_VERSION_STRING << "\n";
 #else
    std::cout << ".\n";
 #endif
#endif

#ifdef HAVE_KCHARSELECT
    std::cout << "* Built with KCharSelect symbol selection support";
 #ifdef KWIDGETSADDONS_VERSION_STRING
   std::cout << ": v" << KWIDGETSADDONS_VERSION_STRING << "\n";
 #else
   std::cout << ".\n";
 #endif
#endif

    std::cout << "\n";


    // To make the mswin version of Dianara distributable as a standalone package
#ifdef Q_OS_WIN
    dianaraApp.addLibraryPath("./plugins/");
#endif


    QStringList cmdLine = qApp->arguments();
    cmdLine.removeFirst(); // Remove the program executable name/path

    bool debugMode = false;
    bool nextParameterIsConfig = false;
    bool ignoreSslErrors = false;
    bool nohttps = false;

    // Parse command line parameters
    if (!cmdLine.isEmpty())
    {
        foreach (const QString argument, cmdLine)
        {
            // Help
            if (argument.startsWith("--help", Qt::CaseInsensitive)
             || argument.startsWith("-h", Qt::CaseInsensitive))
            {
                std::cout << "\nHelp:\n";
                std::cout << "    " << argv[0] << " [options]\n\n";
                std::cout << "Options:\n";
                std::cout << "    -c  --config [name]       Use a different "
                             "configuration file and data folder\n"
                             "                              (parameter is a "
                             "simple name, not a file path)\n";
                std::cout << "    -d  --debug               Show debug messages "
                             "in the terminal\n";
                std::cout << "        --linkcolor=[color]   Set color for "
                             "links, such as 'green' or '#00B500'\n"
                             "\n";
                std::cout << "        --nohttps             Use this if your "
                             "server does not support HTTPS\n";
                std::cout << "        --ignoresslerrors     Ignore SSL errors "
                             "(dangerous, use with care!)\n"
                             "\n";
                std::cout << "    -v  --version             Show version "
                             "information and exit\n";
                std::cout << "    -h  --help                Show this help and "
                             "exit\n";
                std::cout << "\n";

                return 0; // Exit to shell
            }


            // Version info
            if (argument.startsWith("--version", Qt::CaseInsensitive)
             || argument.startsWith("-v", Qt::CaseInsensitive))
            {
                // Version information already shown
                std::cout << "\n"
                             "You can get the latest stable version from "
                             "http://dianara.nongnu.org and\n"
                             "the latest development version from "
                             "https://gitlab.com/dianara/dianara-dev"
                             "\n\n";

                return 0;
            }


            // Use different config file, by setting a different applicationName
            if (argument.startsWith("--config", Qt::CaseInsensitive)
             || argument.startsWith("-c", Qt::CaseInsensitive))
            {
                nextParameterIsConfig = true;
                cmdLine.removeAll(argument);
            }
            else if (nextParameterIsConfig)
            {
                const QString configName = "Dianara_" + argument.toLower();
                dianaraApp.setApplicationName(configName);
                nextParameterIsConfig = false;

                std::cout << "Using alternate config file: "
                          << configName.toStdString() << "\n";
            }

            // Debug mode
            if (argument.startsWith("--debug", Qt::CaseInsensitive)
             || argument.startsWith("-d", Qt::CaseInsensitive))
            {
                debugMode = true;
                cmdLine.removeAll(argument);

                std::cout << "Debug messages enabled\n";
            }


            // Option to set link color (useful in GTK environments)
            if (argument.startsWith("--linkcolor=", Qt::CaseInsensitive))
            {
                const QString linkColorName = argument.split("=").last();
                const QColor linkColor = QColor(linkColorName);
                if (linkColor.isValid())
                {
                    QPalette newPalette = dianaraApp.palette();
                    newPalette.setColor(QPalette::Link, linkColor);
                    dianaraApp.setPalette(newPalette);

                    std::cout << "Forcing link color to: "
                              << linkColorName.toStdString() << "\n";
                }
                else
                {
                    std::cout << "Invalid link color specified!\n";
                }
            }


            // Option to use non-https servers
            if (argument.startsWith("--nohttps", Qt::CaseInsensitive))
            {
                nohttps = true;
                cmdLine.removeAll(argument);

                std::cout << "*** Using No-HTTPS mode\n";
            }


            // Option to ignore SSL errors
            if (argument.startsWith("--ignoresslerrors", Qt::CaseInsensitive))
            {
                ignoreSslErrors = true;
                cmdLine.removeAll(argument);

                std::cout << "\n"
                             "*************************************\n"
                             "*** WARNING: Ignoring SSL errors. ***\n"
                             "***          This is insecure!    ***\n"
                             "*************************************\n"
                             "\n";
            }

        } // End foreach
    }


    // Register custom message handler, to hide debug messages unless specified
    if (!debugMode)
    {
    #ifdef Q_OS_WIN
        FreeConsole();
    #endif

        std::cout << "To see debug messages while running, use --debug\n";
        qInstallMessageHandler(customMessageHandler);
    }


    // Load translation files
    // Get language from LANG environment variable or system's locale
    QString languageString = qgetenv("LANG");
    if (languageString.isEmpty())
    {
        languageString = QLocale::system().name();
    }

    QString languageFile;
    bool languageLoaded;


    QTranslator translatorQt;
    languageFile = QString("qt_%1").arg(languageString);
    std::cout << "\n"
              << "Using Qt translation "
              << QLibraryInfo::location(QLibraryInfo::TranslationsPath).toStdString()
              << "/" << languageFile.toStdString() << "... ";
    languageLoaded = translatorQt.load(languageFile,
                                       QLibraryInfo::location(QLibraryInfo::TranslationsPath));
    if (languageLoaded)
    {
        std::cout << "OK";
        dianaraApp.installTranslator(&translatorQt);
    }
    else
    {
        std::cout << "Unavailable";
    }


    QTranslator translatorDianara;
    languageFile = QString(":/translations/dianara_%1").arg(languageString);
    std::cout << "\n"
              << "Using program translation "
              << languageFile.toStdString() << "... ";

    languageLoaded = translatorDianara.load(languageFile);
    if (languageLoaded)
    {
        std::cout << "OK";
        dianaraApp.installTranslator(&translatorDianara);
    }
    else
    {
        std::cout << "Unavailable";
    }

    std::cout << "\n\n";
    std::cout.flush();


    MainWindow dianaraWindow;

    if (ignoreSslErrors)
    {
        dianaraWindow.enableIgnoringSslErrors();
    }

    if (nohttps)
    {
        dianaraWindow.enableNoHttpsMode();
    }

    dianaraWindow.toggleMainWindow(true);  // show(), firstTime=true


    return dianaraApp.exec();
}
