/*
* 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 <QDebug>

#include "login1_dbus.h"
#include "src/globalsignal.h"

static const QString LOGIND_DEST = "org.freedesktop.login1";
static const QString LOGIND_PATH = "/org/freedesktop/login1";
static const QString LOGIND_IFACE = "org.freedesktop.login1.Manager";
static const QString login1SessionInterface = QStringLiteral("org.freedesktop.login1.Session");

static const QString SCREENSAVER_DEST = "org.ukui.ScreenSaver";
static const QString SCREENSAVER_IFACE = "org.ukui.ScreenSaver";

static const QString LOGOUT_DEST = "org.gnome.SessionManager";
static const QString LOGOUT_IFACE = "org.gnome.SessionManager";



static const QString INHIBIT_WHO = "Kylin Camera";
static const QString INHIBIT_WHY = "Stop Recording when system is shutdown or sleep";
static const QString INHIBIT_MODE = "block";



login1dbusManager::login1dbusManager() :
    m_inhibitShutdownFD(QDBusUnixFileDescriptor()),
    m_inhibitSleepFD(QDBusUnixFileDescriptor())
{
    auto sysBus = QDBusConnection::systemBus();
    sysBus.connect(LOGIND_DEST, LOGIND_PATH,LOGIND_IFACE,
                    QString("PrepareForShutdown"), this, SLOT(login1PrepareForShutdown(bool)));
    sysBus.connect(LOGIND_DEST, LOGIND_PATH,LOGIND_IFACE,
                    QString("PrepareForSleep"), this, SLOT(login1PrepareForSleep(bool)));

    //切换用户信号操作
    QDBusInterface loginInterface(LOGIND_DEST,LOGIND_PATH,LOGIND_IFACE,QDBusConnection::systemBus());
    QDBusReply<QDBusObjectPath> sessionPath = loginInterface.call("GetSessionByPID",(quint32)QCoreApplication::applicationPid());
    QString session = sessionPath.value().path();
    QDBusConnection::systemBus().connect(LOGIND_DEST,session,login1SessionInterface,QStringLiteral("Lock"),this,SLOT(changeUserLock()));
    QDBusConnection::systemBus().connect(LOGIND_DEST,session,login1SessionInterface,QStringLiteral("Unlock"),this,SLOT(changeUserUnLock()));

    auto sesBus = QDBusConnection::sessionBus();
    sesBus.connect(SCREENSAVER_DEST,QString("/"),QString(SCREENSAVER_IFACE),
                   QString("lock"),this,SLOT(screenSaverLocked()));
    sesBus.connect(SCREENSAVER_DEST,QString("/"),QString(SCREENSAVER_IFACE),
                   QString("unlock"),this,SLOT(screenSaverUnlocked()));
    auto sesLogoutBus = QDBusConnection::sessionBus();
    sesLogoutBus.connect(LOGOUT_DEST,QString("/org/gnome/SessionManager"),QString(LOGOUT_IFACE),
                   QString("StartLogout"),this,SLOT(logoutSig()));

}

login1dbusManager::~login1dbusManager()
{

}
//Call this method when start record ...
bool login1dbusManager::inhibit(INHIBIT_TYPE type)
{
    qDebug() << "inhibit";
    QString what;
    if(type == INHIBIT_SLEEP){
        what = "sleep";
    }else if(type == INHIBIT_SHUTDOWN){
        what = "shutdown";
    }else{
        return false;
    }
    QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1",
                                                          "/org/freedesktop/login1",
                                                          "org.freedesktop.login1.Manager",
                                                          QStringLiteral("Inhibit"));
    message.setArguments(QVariantList({what,
                                       "Kylin Scanner",
                                       INHIBIT_WHY,
                                       QStringLiteral("delay")}));
    QDBusPendingReply<QDBusUnixFileDescriptor> reply = QDBusConnection::systemBus().call(message);
    qDebug() << "xx" << reply.value().isValid();
    if(type == INHIBIT_SLEEP){
        reply.value().swap(m_inhibitSleepFD);
    }else if(type == INHIBIT_SHUTDOWN){
        reply.value().swap(m_inhibitShutdownFD);
    }else{
        return false;
    }

    return reply.value().isValid();
}

//Call this method when stop recording ...
void login1dbusManager::unInhibit()
{
    qDebug() << "uninhibit";
    if(m_inhibitSleepFD.isValid() == true)
    {
        m_inhibitSleepFD = QDBusUnixFileDescriptor();
    }
    if(m_inhibitShutdownFD.isValid() == true)
    {
        m_inhibitShutdownFD = QDBusUnixFileDescriptor();
    }
}
void login1dbusManager::login1PrepareForSleep(bool in)
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__<<
          " "<< in;
    if(in){
        if(isLockFlag){
            qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
            return;
        }
        isLockFlag = true;
        emit g_user_signal->saneCancelSignal();
    }else{
        if(!isLockFlag){
            qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
            return;
        }
        isLockFlag = false;
        emit g_user_signal->saneRestartSignal();
    }
}
void login1dbusManager::login1PrepareForShutdown(bool in)
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__<<
          " "<< in;
    if(in){
        if(isLockFlag){
            qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
            return;
        }
        isLockFlag = true;
        emit g_user_signal->saneCancelSignal();
    }else{
        if(!isLockFlag){
            qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
            return;
        }
        isLockFlag = false;
        emit g_user_signal->saneRestartSignal();
    }
}
void login1dbusManager::logoutSig()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__;
    if(isLockFlag){
        qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
        return;
    }
    isLockFlag = true;
    emit g_user_signal->saneCancelSignal();
}
void login1dbusManager::screenSaverLocked()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__;
    if(isLockFlag){
        qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
        return;
    }
    isLockFlag = true;
    emit g_user_signal->saneCancelSignal();
}
void login1dbusManager::screenSaverUnlocked()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__;
    if(!isLockFlag){
        qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
        return;
    }
    isLockFlag = false;
    emit g_user_signal->saneRestartSignal();
}
void login1dbusManager::changeUserLock()
{
    qDebug()<<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__;
    if(isLockFlag){
        qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
        return;
    }
    isLockFlag = true;
    emit g_user_signal->saneCancelSignal();
}
void login1dbusManager::changeUserUnLock()
{
    qDebug() <<__FILE__<<":"<<__LINE__<<","<<__FUNCTION__;
    if(!isLockFlag){
        qDebug() << __FILE__<<":"<<__LINE__<<","<<__FUNCTION__ << "do nothing , and return!" << "isLockFlag:"<< isLockFlag;
        return;
    }
    isLockFlag = false;
    emit g_user_signal->saneRestartSignal();
}
