/* -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
 * -*- coding: utf-8 -*-
 *
 * Copyright (C) 2023 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 of the License, or
 * 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 "global-signal.h"

#include <QDebug>



GlobalSignal::GlobalSignal(QObject *parent)
{
    qRegisterMetaType<SessionStruct>("SessionStruct");
    qRegisterMetaType<SessionStructList>("SessionStructList");
    qRegisterMetaType<QList<QString>>("QList<QString>");

    qDBusRegisterMetaType<QList<QString>>();
    qDBusRegisterMetaType<SessionStruct>();
    qDBusRegisterMetaType<SessionStructList>();


    qRegisterMetaType<UKUILite>("UKUILite");
    qDBusRegisterMetaType<UKUILite>();
    connectUserLogin1Signal();

    QStringList disableOptions = getShutDownDisableOptionFromGlobalManager();
    QSet<QString> setOptions = QSet<QString>(disableOptions.begin(), disableOptions.end());
    QSet<QString> allOptions = QSet<QString>(m_allOptions.begin(), m_allOptions.end());
    QStringList intersection = setOptions.intersect(allOptions).values();

    m_pGMsettings = new QGSettings(GSETTINGS_GLOBALMANAGER_SCHEMA);
    m_pGMsettings->set(DISABLE_POWEROFF_OPTIONS ,(QVariant)intersection);
    m_pGMsettings->set(HIDE_POWEROFF_UI,getHidePowerUiFromGlobalManager());

    connect(m_pGMsettings, SIGNAL(changed(QString)), this, SLOT(doGMsettinsChange(QString)), Qt::DirectConnection);
}

GlobalSignal::~GlobalSignal()
{
    if (m_pGMsettings != nullptr) {
        delete m_pGMsettings;
        m_pGMsettings = nullptr;
    }

    if (m_plogin2 != nullptr) {
        delete m_plogin2;
        m_plogin2 = nullptr;
    }
}

void GlobalSignal::sendUserActiveSignal(QString interface, QVariantMap qvarMap, QStringList strList)
{
    if (interface == "org.freedesktop.login1.Session") {
        QMap<QString,QVariant> mapKey = qvariant_cast<QMap<QString,QVariant>>(qvarMap);
        if (mapKey.contains("Active")) {
            bool isActive = qvariant_cast<bool>(mapKey["Active"]);
            QDBusMessage notifySignal =
                    QDBusMessage::createSignal(DBUS_GC_SIGNAL_PATH, DBUS_GC_SIGNAL_INTERFACE, DBUS_GC_SIGNAL_SIGNAL_Active);

            notifySignal.setArguments({QVariant::fromValue(isActive)});
            QDBusConnection::sessionBus().send(notifySignal);
            USD_LOG(LOG_DEBUG,"send active:%d",isActive);
        }
    }
}

bool GlobalSignal::isPresenceLightSensor()
{
    QGSettings gsettings(AUTO_BRIGHTNESS_SCHEMA);
    SYS_LOG_SHOW_PARAM1(gsettings.get(HAD_SENSOR_KEY).toBool());
    return gsettings.get(HAD_SENSOR_KEY).toBool();
}

QStringList GlobalSignal::getShutdownDisableOptions()
{
    /**
     * gsettings set org.ukui.SettingsDaemon.plugins.globalManager disable-shutdown-option  ['"switchuser"','"hibernate"','"suspend"','"lockscreen"','"logout"','"restart"','"shutdown"']
     * 全部屏蔽
     */

    QList<QString> disableOption = getShutDownDisableOptionInGsettings();

    QSet<QString> setOptions = QSet<QString>(disableOption.begin(), disableOption.end());
    QSet<QString> allOptions = QSet<QString>(m_allOptions.begin(), m_allOptions.end());

    bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool();

    if (ret) {
        return m_allOptions;
    }

    return allOptions.intersect(setOptions).values();
}

bool GlobalSignal::isHidePoweroffUi()
{
    bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool();

    if (!ret) {
        QList<QString> disableOption = getShutDownDisableOptionInGsettings();

        QSet<QString> setOptions = QSet<QString>(disableOption.begin(), disableOption.end());
        QSet<QString> allOptions = QSet<QString>(m_allOptions.begin(), m_allOptions.end());

        QList<QString> intersection = allOptions.intersect(setOptions).values();
        USD_LOG_SHOW_PARAM1(intersection.count());
        if (intersection.count()>=m_allOptions.count()) {
            return true;
        }
    }
    return m_pGMsettings->get(HIDE_POWEROFF_UI).toBool();
}

UKUILite GlobalSignal::getUKUILiteLevel()
{
    UKUILite lite;
    lite.function = m_pGMsettings->get(UKUI_LITE_FUNCTION).toString();
    lite.animation = m_pGMsettings->get(UKUI_LITE_ANIMATION).toString();
    USD_LOG_SHOW_PARAMS(lite.function.toLatin1().data());
    USD_LOG_SHOW_PARAMS(lite.animation.toLatin1().data());
    return lite;
}

QString GlobalSignal::getUKUILiteFunction()
{
    return m_pGMsettings->get(UKUI_LITE_FUNCTION).toString();
}

QString GlobalSignal::getUKUILiteAnimation()
{
    return m_pGMsettings->get(UKUI_LITE_ANIMATION).toString();
}

void GlobalSignal::doGMsettinsChange(QString key)
{
    if (key == DISABLE_POWEROFF_OPTIONS) {
        QStringList disableOption = getShutDownDisableOptionInGsettings();

        QSet<QString> setOptions = QSet<QString>(disableOption.begin(), disableOption.end());
        QSet<QString> allOptions = QSet<QString>(m_allOptions.begin(), m_allOptions.end());

        QStringList intersection = allOptions.intersect(setOptions).values();

        QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \
                              "/globalconfig", \
                              "com.settings.daemon.interface", \
                              QDBusConnection::systemBus());
        QList<QVariant> arguments;
        arguments << QVariant(QString::fromLatin1(MODULE_NAME)) << QVariant(QString::fromLatin1(DISABLE_POWEROFF_OPTIONS)) << QVariant::fromValue(QDBusVariant(intersection));
        QDBusPendingCall reply  = globalManager.asyncCallWithArgumentList("setGlobalConf", arguments);
        if (reply.isError()) {
            USD_LOG(LOG_DEBUG,"error! %s %s",reply.reply().errorMessage().toLatin1().data());
        }
    } else if (key == HIDE_POWEROFF_UI){
        bool ret = m_pGMsettings->get(HIDE_POWEROFF_UI).toBool();
        QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \
                                     "/globalconfig", \
                                     "com.settings.daemon.interface", \
                                     QDBusConnection::systemBus());
        QList<QVariant> arguments;
        arguments << QVariant(QString::fromLatin1(MODULE_NAME)) << QVariant(QString::fromLatin1(HIDE_POWEROFF_UI)) << QVariant::fromValue(QDBusVariant(ret));
        QDBusPendingCall reply  = globalManager.asyncCallWithArgumentList("setGlobalConf", arguments);
        if (reply.isError()) {
            USD_LOG(LOG_DEBUG,"error! %s %s",reply.reply().errorMessage().toLatin1().data());
        }
    } else if (key == UKUI_LITE_FUNCTION || key == UKUI_LITE_ANIMATION) {
        UKUILite lite;
        lite.function = m_pGMsettings->get(UKUI_LITE_FUNCTION).toString();
        lite.animation =  m_pGMsettings->get(UKUI_LITE_ANIMATION).toString();
        Q_EMIT UKUILiteChanged(lite);
    }
}

void GlobalSignal::connectUserActiveSignal()
{
    m_plogin1 = new  DBusLogin1Interface("org.freedesktop.login1",
                              "/org/freedesktop/login1/user/self",
                              "org.freedesktop.login1.User",
                              QDBusConnection::systemBus());
    SessionStructList lqvar =  qvariant_cast<SessionStructList>(m_plogin1->property("Sessions"));
}

void GlobalSignal::connectUserActiveSignalWithPath(QString path)
{
    USD_LOG(LOG_DEBUG,"connect:%s..",path.toLatin1().data());
    m_ploginWithPath = new  QDBusInterface("org.freedesktop.login1",
                                           path,
                                           "org.freedesktop.DBus.Properties",
                                           QDBusConnection::systemBus());
   connect(m_ploginWithPath, SIGNAL(PropertiesChanged(QString,QVariantMap,QStringList)), this, SLOT(sendUserActiveSignal(QString,QVariantMap,QStringList)));
}

void GlobalSignal::connectUserLogin1Signal()
{
    m_plogin2 = new  QDBusInterface("org.freedesktop.login1",
                                    "/org/freedesktop/login1/user/self",
                                    "org.freedesktop.DBus.Properties",
                                    QDBusConnection::systemBus());


    QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.login1",
                                                          "/org/freedesktop/login1/user/self"
                                                          ,"org.freedesktop.DBus.Properties",
                                                          "Get");

     QDBusMessage reply1 = m_plogin2->call("Get", "org.freedesktop.login1.User", "Sessions");

     QVariant v = reply1.arguments().first();
     QDBusArgument arg = v.value<QDBusVariant>().variant().value<QDBusArgument>();

     SessionStructList members;
     arg.beginArray();
     while(!arg.atEnd()) {
         SessionStruct m;
         arg >> m;
         members << m;
         USD_LOG(LOG_DEBUG,"ready connect %s..",m.userPath.path().toLatin1().data());
         connectUserActiveSignalWithPath(m.userPath.path());
         break;
     }
     arg.endArray();
}

QVariant GlobalSignal::getGlobalConfig(QString schema, QString key)
{
    QDBusInterface globalManager("com.settings.daemon.qt.systemdbus", \
                          "/globalconfig", \
                          "com.settings.daemon.interface", \
                          QDBusConnection::systemBus());

    QDBusReply<QVariant> reply = globalManager.call("getGlobalConf", schema, key);

    if (reply.isValid()) {
        return reply.value();
    } else {
        USD_LOG(LOG_ERR,"globalManager dbus interface failed .");
    }
    return QVariant(0);
}

QList<QString> GlobalSignal::getShutDownDisableOptionInGsettings()
{
    QList<QString> disableOption = m_pGMsettings->get(DISABLE_POWEROFF_OPTIONS).toStringList();
    for (int var = 0; var < disableOption.count(); ++var) {
        disableOption[var] = disableOption[var].toLower();
    }
    QSet<QString> setOptions = QSet<QString>(disableOption.begin(), disableOption.end());
    QSet<QString> allOptions = QSet<QString>(m_allOptions.begin(), m_allOptions.end());

    QList<QString> intersection = allOptions.intersect(setOptions).values();
    USD_LOG_SHOW_PARAM1(intersection.count());
    return intersection;
}

QStringList GlobalSignal::getShutDownDisableOptionFromGlobalManager()
{
    QStringList values = getGlobalConfig(MODULE_NAME, DISABLE_POWEROFF_OPTIONS).toStringList();
    return values;
}

bool GlobalSignal::getHidePowerUiFromGlobalManager()
{
    return getGlobalConfig(MODULE_NAME, HIDE_POWEROFF_UI).toBool();
}
