/*
* Copyright (C) 2021, KylinSoft Co., Ltd.
*
* 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, 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/&gt;.
*
*/
#include "singleapplication.h"
#include <QApplication>
#include <QByteArray>
#include <QDir>
#include <QLibraryInfo>
#include <QLocale>
#include <QProcess>
#include <QTranslator>
#include <X11/Xlib.h> // ought to put this file last
#include <QCommandLineParser>
#include <QIODevice>
#include <QStandardPaths>
#include <QMessageBox>
#include <QObject>
#include <QDir>
#include <QFileInfo>
#include <fstream>
#include <stdio.h>
#include <log.hpp>
#include <kysdk/applications/singleapplication.h>
#include "windowmanage.hpp"
#include "include/common.h"
#include "globalsignal.h"
#include "mainwidget.h"
#include "scandialog.h"
#include "global.h"

#define TRANS_PATH  "/usr/share/kylin-scanner/translations"

//using namespace Global;


static void createDir(QString dirPath)
{
    qDebug() << "path: "<< dirPath;
    QDir configDir(dirPath);
    if (! configDir.exists()) {
        configDir.mkpath(dirPath);
    }
}

static void createScannerDir()
{
    createDir(g_config_signal->m_configPath);
    createDir(g_config_signal->m_scannerPath);
    createDir(g_config_signal->m_scannerPnmImagePath);
    createDir(g_config_signal->m_scannerImagePath);
    createDir(g_config_signal->m_scannerTempPath);
}


static QString getCurrentUserName()
{
    QString cmd(BashType);
    QStringList arglists;

    arglists << "-c";
    arglists << "whoami";

    QProcess *process = new QProcess();
    process->start(cmd, arglists);
    process->waitForFinished();
    QString userNow = QString::fromLocal8Bit(process->readAllStandardOutput().trimmed());

    KyInfo() << "Exist user: " << userNow;

    return userNow;
}

static void doWrite(QString userNow, int pidNow)
{
    QFile file(UserExistFile);
    if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
        KyInfo() << "open this file error!";
        return;
    }

    // Easy to other user to modify `scanner/user.id` file
    file.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner
                        | QFileDevice::ReadUser | QFileDevice::WriteUser
                        | QFileDevice::ReadGroup | QFileDevice::WriteGroup
                        | QFileDevice::ReadOther | QFileDevice::WriteOther);

    QString message = userNow + "," + QString::number(pidNow);
    KyInfo() << "doWrite: message= " << message;

    QTextStream text_stream(&file);
    text_stream << message << "\r\n";
    file.flush();
    file.close();
}

int getScreenWidth()
{
    Display *disp = XOpenDisplay(NULL);
    Screen *scrn = DefaultScreenOfDisplay(disp);
    if (NULL == scrn)
        return 0;

    int width = scrn->width;

    if (NULL != disp)
        XCloseDisplay(disp);

    return width;
}

static QString execCmd(QString cmd)
{
    KyInfo() << "cmd = " << cmd;
    QProcess process;
    process.start(QString(cmd));
    process.waitForFinished();
    QByteArray result = process.readAllStandardOutput();
    result = result.left(result.length()-1);
    KyInfo() << "arch = " << result;
    return result;
}
static QString getSystemArchitecture()
{
    QString archResult = execCmd("arch");
    return archResult;
}

static QString getAppVersion()
{
    QString versionResult = execCmd(QString("dpkg-parsechangelog -l %1 --show-field Version").arg(ChangelogFilePath));
    return versionResult;
}

int main(int argc, char *argv[])
{
    /* 使用sdk管理日志 */
    qInstallMessageHandler(kabase::Log::logOutput);

    QString scannerFileName;
    if (argc > 1) {
        scannerFileName = argv[1];
    }

    int exitCode = 0;

#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 0))
    QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
    QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif

    kdk::QtSingleApplication app(argc, argv);

    createScannerDir();
    getSystemArchitecture();
    QLocale loc = QLocale::system().name();
    app.setApplicationVersion(getAppVersion());
    app.setWindowIcon(QIcon::fromTheme("kylin-scanner"));

    if (app.isRunning()) {
        qDebug() << "is running";
        app.sendMessage(scannerFileName);
        return 0;
    }

    // Fetch tokens from the environment, if present
    // --openfile="/home/yushuoqi/ocr.png"
    const QByteArray kylinScannerImageDebug = qgetenv("KYLIN_SCANNER_IMAGE_DEBUG");
    //0606本地扫描调试/*
    if (!kylinScannerImageDebug.isEmpty()) {
//    if (kylinScannerImageDebug.isEmpty()) {
        g_config_signal->m_kylinScannerImageDebug = true;
    }

    QCommandLineParser parser;
    parser.setApplicationDescription("An interface-friendly scanner with OCR, Smart rectify and OneClickBeauty.");
    parser.addHelpOption();
    parser.addVersionOption();

    // An option with a value
    QCommandLineOption openFileOption(QStringList() << "f" << "openfile",
                                      QCoreApplication::translate("main", "Open file <filename>"),
                                      QCoreApplication::translate("main", "Filename"));

    // A boolean option with multiple names (-d, --hide)
    QCommandLineOption hideOption(QStringList() << "d" << "hide",
                                  QCoreApplication::translate("main", "Hide scan settings widget"));
    if (g_config_signal->m_kylinScannerImageDebug) {
        parser.addOption(openFileOption);
        parser.addOption(hideOption);
    }

    parser.process(app);

    if (g_config_signal->m_kylinScannerImageDebug) {
        g_config_signal->m_openFileName = parser.value(openFileOption);
        //0606本地扫描调试
        g_config_signal->m_openFileName = "/home/zyz/ocr.jpg";
        bool hide = parser.isSet(hideOption);
        g_config_signal->m_hideScanSettingsWidget = hide;

        KyInfo() << "args = " << parser.positionalArguments()
                 << "hide = " << hide
                 << "openFile = " << g_config_signal->m_openFileName;
    }
    //加载翻译文件
    QString trans_path;
    if (QDir(TRANS_PATH).exists()) {
        trans_path = TRANS_PATH;
    }
    else {
        trans_path = qApp->applicationDirPath();
    }
    QTranslator app_trans;
    QTranslator qt_trans;
    QTranslator trans_SDK;
    QString locale = QLocale::system().name();
    QString qt_trans_path;
    qt_trans_path = QLibraryInfo::location(QLibraryInfo::TranslationsPath);// /usr/share/qt5/translations

    if(!app_trans.load("kylin-scanner_" + locale + ".qm", trans_path))
        qDebug() << "Load translation file："<< "kylin-scanner_" + locale + ".qm from" << trans_path << "failed!";
    else
        app.installTranslator(&app_trans);

    if(!qt_trans.load("qt_" + locale + ".qm", qt_trans_path))
        qDebug() << "Load translation file："<< "qt_" + locale + ".qm from" << qt_trans_path << "failed!";
    else
        app.installTranslator(&qt_trans);


    QString translatorFileName = QLatin1String("qt_");
    translatorFileName += QLocale::system().name();
    QTranslator *translator = new QTranslator();
    if (translator->load(translatorFileName, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
    {
        app.installTranslator(translator);
    }
    else
    {
        qDebug() << "加载中文失败";
    }

    if(!trans_SDK.load(":/translations/gui_" + locale + ".qm")){
        qDebug() << "Load translations file" <<QLocale() << "failed!";
    }else{
        QApplication::installTranslator(&trans_SDK);
    }


    app.setApplicationName(QApplication::tr("Scanner"));
    if (! app.isRunning()) {
        QString userNow = getCurrentUserName();
        int pidNow = app.applicationPid();

        doWrite(userNow, pidNow);

        MainWidget *w = new MainWidget;
        /* 最小化拉起 */
        app.setActivationWindow(w);

        /* wayland最小化拉起 */
        quint32 mainWidgetWindowId = w->getWindowId();
        qDebug() << "mainWidgetWindowId: " << mainWidgetWindowId;
        if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) {
            QObject::connect(&app, &kdk::QtSingleApplication::messageReceived, [=](){
                printf("mainWidgetWindowId: %d",mainWidgetWindowId);
                qDebug() << "mainWidgetWindowId: " << mainWidgetWindowId;
                ::kabase::WindowManage::activateWindow(mainWidgetWindowId);
            });
        }

        /* 移除标题栏 */
        kabase::WindowManage::removeHeader(w);

        /* 解决置顶失效 */
        kabase::WindowManage::keepWindowAbove(w->windowId);

        w->show();

        /* 居中显示 */
        kabase::WindowManage::setMiddleOfScreen(w);


        return app.exec();
    }
}
