/*
 * Copyright 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 (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 <https://www.gnu.org/licenses/>.
 */

#include "whitelistmanager.h"
#include <QStandardPaths>
#include <QDir>
#include <QFile>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonDocument>
#include <QDebug>
#include "utils/misc.h"

WhiteListManager::WhiteListManager(QObject *parent)
    : QObject(parent)
    , m_jsonFile(QStandardPaths::writableLocation(QStandardPaths::HomeLocation) +
               "/.config/kylin-app-manager/whitelists")
    , m_whitelistFileWatcher(new QFileSystemWatcher(this))
{
    initConnections();
    initJsonFile();
}

bool WhiteListManager::addToWhiteList(const QString &desktopFile, const QString &option)
{
    if (!m_jsonObj.contains(option)) {
        qWarning() << "unkwon option: " << option << m_jsonObj.keys();
        return false;
    }
    QJsonArray arr = m_jsonObj[option].toArray();
    if (arr.contains(desktopFile)) {
        return true;
    }
    arr.append(desktopFile);

    m_jsonObj[option] = arr;
    if (!utils::Misc::writeJsonToFile(m_jsonObj, m_jsonFile)) {
        qWarning() << __FUNCTION__ << "writeJsonToFile has failed!";
        return false;
    }
    Q_EMIT addedToWhitelist(desktopFile);
    return true;
}

bool WhiteListManager::removeFromWhiteList(const QString &desktopFile, const QString &option)
{
    qDebug() << __FUNCTION__ << m_jsonObj[option];
    if (!m_jsonObj.contains(option)) {
        qWarning() << "unkwon option: " << option << m_jsonObj.keys();
        return false;
    }
    QJsonArray arr = m_jsonObj[option].toArray();
    if (!arr.contains(desktopFile)) {
        return true;
    }

    for (int i=0; i<arr.size(); ++i) {
        if (arr[i] == desktopFile) {
            arr.removeAt(i);
            break;
        }
    }
    m_jsonObj[option] = arr;
    if (!utils::Misc::writeJsonToFile(m_jsonObj, m_jsonFile)) {
        qWarning() << __FUNCTION__ << "writeJsonToFile has failed!";
        return false;
    }
    return true;
}

bool WhiteListManager::isExists(const QString &desktopFile, const QString &option)
{  
    if (m_jsonObj[option].toArray().contains(desktopFile)) {
        return true;
    }
    return false;
}

QStringList WhiteListManager::whiteListsOfApp(const QString &desktopFile)
{
    QStringList options;
    for (auto &option : m_jsonObj.keys()) {
        if (m_jsonObj[option].toArray().contains(desktopFile)) {
            options.append(option);
        }
    }
    return options;
}

QStringList WhiteListManager::appWhiteList(const QString &option)
{
    if (!m_jsonObj.contains(option)) {
        qWarning() << "unkwon option: " << option << m_jsonObj.keys();
        return QStringList();
    }
    QStringList appLists;
    QJsonArray arr = m_jsonObj[option].toArray();
    for (int i=0; i<arr.size(); ++i) {
         appLists << arr[i].toString();
    }
    return appLists;
}

void WhiteListManager::initJsonFile()
{
    QString filePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.config/kylin-app-manager/";
    QString jsonFileName = filePath + "/whitelists";
    if (QFile::exists(jsonFileName)) {
        m_jsonObj = utils::Misc::readJsonFromFile(jsonFileName);
        return;
    }

    if (!utils::Misc::ensurePathExists(filePath) ||
            !utils::Misc::ensureFileExists(jsonFileName)) {
        return;
    }

    m_jsonObj["Notification"] = QJsonArray();
    m_jsonObj["PowerSaving"] = QJsonArray();

    // 初始化whitelist列表，添加默认的应用，维护whitelist列表
    QJsonArray appManagerArray;
    QJsonArray appUninstallArray;

    for (int i=0; i<appManagerList.size(); ++i) {
        appManagerArray.append(appManagerList[i]);
    }
    m_jsonObj["AppManager"] = appManagerArray;

    for (int i=0; i<appUninstallList.size(); ++i) {
        appUninstallArray.append(appUninstallList[i]);
    }
    m_jsonObj["AppUninstall"] = appUninstallArray;

    if (!utils::Misc::writeJsonToFile(m_jsonObj, m_jsonFile)) {
        qWarning() << __FUNCTION__ << "writeJsonToFile is failed!";
    }
}

void WhiteListManager::initConnections()
{
    m_whitelistFileWatcher->addPath(m_jsonFile);
    connect(m_whitelistFileWatcher, &QFileSystemWatcher::fileChanged,
            this, &WhiteListManager::updateWhitelistJsonInfo);
}

void WhiteListManager::updateWhitelistJsonInfo(const QString &path)
{
    QFile dir(path);
    if (!dir.exists()) {
        qWarning() << __FUNCTION__ << path << " is not exists";
        return;
    }
    m_jsonObj = utils::Misc::readJsonFromFile(m_jsonFile);
}
