/*
 * 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, 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 "ukccsessionserver.h"

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>
#include <QDBusInterface>
#include <QDBusReply>

const QStringList openkylinFilterPathList = {"/Shortcut/Add", "/Shortcut/Customize Shortcut"};

ukccSessionServer::ukccSessionServer() {
   mFilePath = QDir::homePath() + "/.config/ukui/ukcc-screenPreCfg.json";
   monitoFileChanged();
}

QMap<QString, QVariant> ukccSessionServer::getJsonInfo(const QString &configFile) {
    QVariantMap moduleMap;

    QFile file(configFile);
    if (file.exists()) {
        file.open(QIODevice::ReadOnly);
        QByteArray readBy=file.readAll();
        QJsonParseError error;
        QJsonDocument readDoc=QJsonDocument::fromJson(readBy,&error);
        QJsonArray obj=readDoc.object().value("ukcc").toArray();

        for (int i = 0 ; i < obj.size(); i++) {
            QJsonObject faObj= obj[i].toObject();
            if (!faObj.contains("name")) {
                continue;
            }
            QString name = faObj["name"].toString();
            bool visible = true;
            if (faObj.contains("visible")) {
                visible = faObj["visible"].toBool();
            }
            moduleMap.insert(name, visible);
            QJsonArray childNodeAry =  faObj["childnode"].toArray();
            for (int j = 0; j < childNodeAry.size(); j++) {
                QJsonObject childObj= childNodeAry.at(j).toObject();
                if (!childObj.contains("name")) {
                    continue;
                }
                QString modeName = childObj["name"].toString();
                bool modeVisiable = true;
                if (childObj.contains("visible")) {
                    modeVisiable = childObj["visible"].toBool();
                }
                QString modeSet = modeName + "Settings";
                moduleMap.insert(modeName, modeVisiable);
                if (childObj.contains(modeSet)) {
                    moduleMap.insert(modeSet, childObj[modeSet].toString());
                }
            }
        }
    }
    return moduleMap;
}

QString ukccSessionServer::getScreenMode()
{
    return mScreenMode;
}

void ukccSessionServer::setScreenMode(QString screenMode)
{
    mScreenMode = screenMode;
    Q_EMIT screenChanged(mScreenMode);
}

void ukccSessionServer::setPreScreenCfg(QVariantList preScreenCfg)
{
    mPreScreenCfg = preScreenCfg;
}

QVariantList ukccSessionServer::getPreScreenCfg()
{
    if (!mPreScreenCfg.count()) {
        QFile file(mFilePath);
        if (file.exists()) {
            file.open(QIODevice::ReadOnly);
            QByteArray readBy=file.readAll();
            QJsonParseError error;
            QJsonDocument readDoc=QJsonDocument::fromJson(readBy,&error);
            QVariantList obj = readDoc.array().toVariantList();

            Q_FOREACH(QVariant variant, obj) {
                QMap<QString, QVariant> map = variant.toMap();
                ScreenConfig screenCfg;
                screenCfg.screenId = map["id"].toString();
                screenCfg.screenModeId = map["modeid"].toString();
                screenCfg.screenPosX = map["x"].toInt();
                screenCfg.screenPosY = map["y"].toInt();
                screenCfg.isPrimary = map["primary"].toBool();
                QVariant screenVar = QVariant::fromValue(screenCfg);
                mPreScreenCfg << screenVar;
            }
        }
    }
    return mPreScreenCfg;
}

void ukccSessionServer::exitService() {
    qApp->exit();
}

void ukccSessionServer::ReloadSecurityConfig()
{
    Q_EMIT configChanged();
}

QVariantMap ukccSessionServer::getModuleHideStatus() {
    QString name = qgetenv("USER");
    if (name.isEmpty()) {
        name = qgetenv("USERNAME");
    }
    QString filename = GetSecurityConfigPath();

    return getJsonInfo(filename);
}

QString ukccSessionServer::GetSecurityConfigPath() {
    QString name = qgetenv("USER");
    if (name.isEmpty()) {
        name = qgetenv("USERNAME");
    }
    QString systemFilename = "/usr/share/ukui-control-center/data/ukui-control-center-security-config.json";
    QFile file(systemFilename);
    if (file.exists()) {
        return systemFilename;
    }

    QString userFilename = QDir::homePath() + "/.config/ukui-control-center-security-config.json";
    QFile userFile(userFilename);
    if (userFile.exists()) {
        return userFilename;
    }

    QString moduleFileName = "/usr/share/ukui-control-center/data/ukui-control-center-config.json";
    return moduleFileName;
}

void ukccSessionServer::monitoFileChanged()
{
    QFileSystemWatcher *m_FileWatcher = new QFileSystemWatcher(this);
    m_FileWatcher->addPath(GetSecurityConfigPath());
    connect(m_FileWatcher, &QFileSystemWatcher::fileChanged, this, [=](){
        Q_EMIT configChanged();
    });
}

QVariantMap ukccSessionServer::getSearchItems()
{
    QDBusInterface* m_interface = new QDBusInterface("org.ukui.ukcc.search",
                                                     "/",
                                                     "org.ukui.ukcc.search.interface",
                                                     QDBusConnection::sessionBus(),
                                                     this);
    QJsonArray searchItems;
    QJsonObject rootobj;
    rootobj.insert("ukcc", searchItems);
    QJsonDocument document;
    document.setObject(rootobj);
    if (!m_interface->isValid()) {
        qDebug() << "ukcc search Interface Failed : " << QDBusConnection::sessionBus().lastError();
        return rootobj.toVariantMap();
    }
    QDBusReply<QVariantMap> reply = m_interface->call("getSearchItems");
    if (reply.isValid()) {
        return reply.value();
    } else {
        return rootobj.toVariantMap();
    }
}

