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


ShortcutInterface::ShortcutInterface()
{
    qRegisterMetaType<QStringPair>("QStringPair");
    qDBusRegisterMetaType<QStringPair>();
    qRegisterMetaType<QStringPairList>("QStringPairList");
    qDBusRegisterMetaType<QStringPairList>();

    qRegisterMetaType<KeyEntry>("KeyEntry");
    qDBusRegisterMetaType<KeyEntry>();
    qRegisterMetaType<KeyEntryList>("KeyEntryList");
    qDBusRegisterMetaType<KeyEntryList>();

    getShortcutThread();
}

ShortcutInterface::~ShortcutInterface()
{

}

void ShortcutInterface::getShortcutThread()
{
    GetShortcutWorker *toGetShortcutThread = new GetShortcutWorker(this);
    systemEntries.clear();
    customEntries.clear();
    systemShortcutList.clear();
    customShortcutList.clear();
    connect(toGetShortcutThread, &GetShortcutWorker::generalShortcutGenerate, this,
            [=](QString schema, QString key, QString value){
        KeyEntry generalKeyEntry;
        generalKeyEntry.gsSchema = schema;
        generalKeyEntry.keyStr   = key;
        generalKeyEntry.valueStr = value;
        systemEntries.append(generalKeyEntry);
    });

    connect(toGetShortcutThread, &GetShortcutWorker::customShortcutGenerate, this,
            [=](QString path, QString name, QString binding, QString action){
        KeyEntry customKeyEntry;
        customKeyEntry.gsSchema = KEYBINDINGS_CUSTOM_SCHEMA;
        customKeyEntry.gsPath     = path;
        customKeyEntry.nameStr    = name;
        customKeyEntry.bindingStr = binding;
        customKeyEntry.actionStr  = action;
        customEntries.append(customKeyEntry);
    });

    connect(toGetShortcutThread, &GetShortcutWorker::workerComplete, this, [=]() {
        QMap<QString, QString> systemMap;
        QMap<QString, QString> desktopMap;
        // 最新快捷键数据
        for (int i = 0; i < systemEntries.count(); i++) {
            if (systemEntries[i].gsSchema == KEYBINDINGS_DESKTOP_SCHEMA) {
                desktopMap.insert(systemEntries[i].keyStr, systemEntries[i].valueStr);
            } else if (systemEntries[i].gsSchema == KEYBINDINGS_SYSTEM_SCHEMA) {
                systemMap.insert(systemEntries[i].keyStr, systemEntries[i].valueStr);
            }
        }

        desktopMap = MergerOfTheSamekind(desktopMap);
        QMap<QString, QMap<QString, QString>> generalMaps;
        if (desktopMap.count() != 0) {
            generalMaps.insert("Desktop", desktopMap);
        }

        QMap<QString, QMap<QString, QString>>::iterator it = generalMaps.begin();
        for (; it != generalMaps.end(); it++) {
            buildGeneralWidget(it.key(), it.value());
        }

        for (KeyEntry ckeyEntry : customEntries) {
            QStringPair sq;
            sq.name = ckeyEntry.nameStr;
            sq.key  = getShowShortcutString(ckeyEntry.bindingStr);
            customShortcutList.append(sq);
        }
    });

    connect(toGetShortcutThread, &GetShortcutWorker::finished, this, [=](){
        toGetShortcutThread->deleteLater();
    });
    toGetShortcutThread->start();
}

QList<KeyEntry> ShortcutInterface::getSystemShortcutEntry()
{
    return systemEntries;
}
QList<KeyEntry> ShortcutInterface::getCustomShortcutEntry()
{
    return customEntries;
}

QList<QStringPair> ShortcutInterface::getSystemShortcut()
{
    return systemShortcutList;
}

QList<QStringPair> ShortcutInterface::getCustomShortcut()
{
    return customShortcutList;
}

void ShortcutInterface::updateShortcut()
{
    getShortcutThread();
}

void ShortcutInterface::setSystemShortcut(const QString &key, const QString &value)
{
    QGSettings generalShort(KEYBINDINGS_DESKTOP_SCHEMA);
    generalShort.set(key, value);
}

QMap<QString, QString> ShortcutInterface:: MergerOfTheSamekind(QMap<QString, QString> desktopMap)
{
    QMap<QString, QString>::iterator it = desktopMap.begin();
    for (; it != desktopMap.end(); it++) {
        QString name = it.key().at(it.key().size() - 1);
        QString name_modification = it.key().left(it.key().length() - 1);
        if (name == '2') {
            desktopMap[name_modification] = desktopMap[name_modification]+" or "+it.value();
            desktopMap.erase(it);
            it = desktopMap.begin()+1;// 除之后要将指针指向后面一个
        }
    }
    return desktopMap;
}

void ShortcutInterface::buildGeneralWidget(QString schema, QMap<QString, QString> subShortcutsMap)
{
    GSettingsSchema *pSettings;
    QString domain;

    if (schema == "Desktop") {
        domain    = "ukui-settings-daemon";
        pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory(
                                                    "/usr/share/glib-2.0/schemas/",
                                                    g_settings_schema_source_get_default(),
                                                    FALSE, NULL),
                                                    KEYBINDINGS_DESKTOP_SCHEMA,
                                                    FALSE);

    } else if (schema == "System") {
        domain    = "gsettings-desktop-schemas";
        pSettings = g_settings_schema_source_lookup(g_settings_schema_source_new_from_directory(
                                                    "/usr/share/glib-2.0/schemas/",
                                                    g_settings_schema_source_get_default(),
                                                    FALSE, NULL),
                                                    KEYBINDINGS_SYSTEM_SCHEMA,
                                                    FALSE);
    } else {
        return;
    }
    QMap<QString, QString>::iterator it = subShortcutsMap.begin();
    for (int i = 0; it != subShortcutsMap.end(); it++,i++) {
        QByteArray ba = domain.toLatin1();
        QByteArray ba1 = it.key().toLatin1();

        GSettingsSchemaKey *keyObj = g_settings_schema_get_key(pSettings, ba1.data());
        char *i18nKey;
        i18nKey = const_cast<char *>(g_dgettext(ba.data(), g_settings_schema_key_get_summary(keyObj)));
        QStringPair shortcut;
        shortcut.name = QString(i18nKey);
        shortcut.key  = it.value();
        shortcut.mediakey = it.key();
        systemShortcutList.append(shortcut);
        g_settings_schema_key_unref(keyObj);
    }

    g_settings_schema_unref(pSettings);
    return;
}

QString ShortcutInterface::getShowShortcutString(QString src) {
    if (src.contains("Meta")) {
        src.replace("Meta", "Win");
    }
    if (src.contains("Start")) {
        src.replace("Start", "Win");
    }
    src.replace("<","");
    src.replace(">","   ");
    QStringList temp_list = src.split(" ");
    QString str;
    for(qint32 i = 0; i < temp_list.count(); i++) {
        str += temp_list.at(i)
                .left(1).toUpper() +
                temp_list.at(i)
                .mid(1, temp_list.at(i).length() - 1);
        str += " ";
    }
    str.replace("Or","or");
    return  str;
}
