/*
 * Copyright (C) 2018 Tianjin KYLIN Information Technology 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/>.
 *
**/
#include <QApplication>
#include <QTranslator>
#include <syslog.h>
#include <QDBusReply>
#include <QLocale>
#include <QDir>

#include <QCommandLineParser>
#include <QCommandLineOption>
#include <QDebug>
#include <QDesktopWidget>
#include <QDBusInterface>
#include <QEventLoop>
#include <signal.h>
#include <unistd.h>
#include <QProcess>
#include <ukui-log4qt.h>
#include <QtSingleApplication>

#include "utils.h"
#include "commonfunc.h"
#include "lockdialogmodel.h"
#include "lockdialogperformer.h"
#include "fullbackgroundwidget.h"
#include "screensaverwndadaptor.h"
#include "pluginsloader.h"
#include "msysdbus.h"

FullBackgroundWidget *window = nullptr;

int main(int argc, char *argv[])
{
    if(argc < 2)
        return 0;
    syslog(LOG_INFO, "[ukui-screensaver-dialog] startup!!");
    initUkuiLog4qt("ukui-screensaver-dialog");
    // 重启或关机时不被session关掉
    qunsetenv("SESSION_MANAGER");
    if (!isGreeterMode()) {
        // 试用模式不起锁屏
        checkIslivecd();
    }

    qputenv("QT_QPA_PLATFORMTHEME",QByteArray("ukui"));

#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 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
    // 屏蔽输入法
    qunsetenv("QT_IM_MODULE");

    QString id = QString("ukui-screensaver-dialog"+QLatin1String(getenv("DISPLAY")));
    QtSingleApplication app(id, argc, argv);
    if (app.isRunning()) {
        QString strArguments = QApplication::arguments().join(",");
        app.sendMessage(strArguments);
        qInfo()<<"ukui screensaver dialog is running!";
        return EXIT_SUCCESS;
    }
    setCursorCenter();
    // 加载插件实例
    PluginsLoader *pluginsLoader = &PluginsLoader::instance();
    pluginsLoader->start(QThread::HighestPriority);
    pluginsLoader->wait();

    QApplication::setSetuidAllowed(true);

    LockDialogModel *lockDialogModel = new LockDialogModel();
    LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel);

    QObject::connect(lockDialogModel, &LockDialogModel::requestUnlockSession,  [=]() {
        if (window) {
            window->onCloseScreensaver();
        } else {
            exit(0);
        }
    });
    if (!lockDialogModel->sessionActive()) {
        QEventLoop *loopTemp = new QEventLoop(&app);
        QObject::connect(lockDialogModel, &LockDialogModel::sessionActiveChanged, [loopTemp](bool isActive) {
            qDebug()<<"sessionActiveChanged:"<<isActive;
            if (isActive && loopTemp->isRunning()) {
                loopTemp->quit();
            }
        });
        QObject::connect(lockDialogModel, &LockDialogModel::requestLockSession, [loopTemp]() {
            qDebug()<<"session requestLock!";
            if (loopTemp->isRunning()) {
                loopTemp->quit();
            }
        });
        loopTemp->exec();
    }

    LockDialogModel::CommandLineArgs cmdArgs;
    if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) {
        return 0;
    }
    QObject::connect(&app, SIGNAL(messageReceived(const QString&)), lockDialogModel, SLOT(onRunningMessage(const QString&)));

    qInfo()<<"Start "<<app.arguments();

    //加载翻译文件
    QString locale = QLocale::system().name();
    QTranslator translator;
    QString qmFile = QString(WORKING_DIRECTORY"/i18n_qm/%1.qm").arg(locale);
    translator.load(qmFile);
    app.installTranslator(&translator);
    qDebug() << "load translation file " << qmFile;

    window = new FullBackgroundWidget(lockDialogModel);

    // 注册DBus
    ScreenSaverWndAdaptor adaptorWnd(window);
    QDBusConnection service = QDBusConnection::sessionBus();
    QString sessionDbus = SSWND_DBUS_SERVICE;
    if(!service.registerService(SSWND_DBUS_SERVICE)) {
        QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");;
        sessionDbus = QString("%1%2").arg(QString(SSWND_DBUS_SERVICE)).arg(displayNum);
        if(!service.registerService(sessionDbus)) {
            qDebug() << service.lastError().message();
            return 1;
        }
    }
    if(!service.registerObject(SSWND_DBUS_PATH, SSWND_DBUS_SERVICE, &adaptorWnd,
                               QDBusConnection::ExportAllSlots |
                               QDBusConnection::ExportAllSignals)) {
        qDebug() << service.lastError().message();
        return 1;
    }
    qDebug() << service.baseService();

    if(cmdArgs.isBlank) {
        Q_EMIT lockDialogModel->showBlankScreensaver(cmdArgs.nBlankDelay, cmdArgs.isBlankHasLock);
    }

#ifndef USE_INTEL
    syslog(LOG_INFO, "[ukui-screensaver-dialog] window show!!");
    window->show();
    window->activateWindow();
    syslog(LOG_INFO, "[ukui-screensaver-dialog] window show done!!");
#endif

    MSysDbus *m_sysDbus = new MSysDbus(lockDialogModel,window);

    if (!QDBusConnection::systemBus().registerService("org.ukui.screensaver")) {
        qDebug()<<"registerService failed";
    }

    if(cmdArgs.isLock) {
        Q_EMIT lockDialogModel->showLock(false);
    }
    
    if(cmdArgs.isLockStartup) {
        Q_EMIT lockDialogModel->showLock(true);
    }

    if(cmdArgs.isSessionIdle) {
        Q_EMIT lockDialogModel->showSessionIdle();
    }
 
    if(cmdArgs.isLockScreensaver) {
        Q_EMIT lockDialogModel->showLockScreensaver();
    }

    if(cmdArgs.isScreenSaver) {
        Q_EMIT lockDialogModel->showScreensaver();
    }

    KillFocusOfKydroid();

    return app.exec();
}
