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

#include "upm_customdefaultgsettings.h"
#include "upm_gsettings.h"

#include <QDebug>
#include <QDir>
#include <QFileInfo>

enum power_policy
{
    power_policy_performance = 0,
    power_policy_balance,
    power_policy_powersave,
    power_policy_unknown
};

UpmCustomDefaultGsettings::UpmCustomDefaultGsettings(QObject *parent) : QObject(parent)
{
    getHardwareInfo();

    m_globalConfig = new QSettings(UPM_GLOBAL_GSETTINGS_CONFIG_FILE, QSettings::IniFormat, this);

    QString extendConfigFilePath;
    if (true == getExtendConfigFile(extendConfigFilePath)) {
        m_extendConfig = new QSettings(extendConfigFilePath, QSettings::IniFormat, this);
        m_extendConfig->beginGroup("product");
        QStringList productList = m_extendConfig->allKeys();
        Q_FOREACH (const QString &product, productList) {
            if (m_hardwareInfo.contains(product, Qt::CaseInsensitive)) {
                if (1 == m_extendConfig->value(product).toInt()) {
                    m_productGroup = product;
                }
                break;
            }
        }
        m_extendConfig->endGroup();
    }
}

UpmCustomDefaultGsettings::~UpmCustomDefaultGsettings() {}

void UpmCustomDefaultGsettings::setUpmCustomDefaultGsettings()
{
    QGSettings powerGsettings(POWER_MANAGER_SETTINGS);
    if (true == powerGsettings.get(PREPROCESS_POWER_MODE)) {
        return;
    }

    powerGsettings.set(GSETTINGS_KEY_POWER_POLICY_AC, getCustomDefaultCpuPolicyAc());

    powerGsettings.set(GSETTINGS_KEY_POWER_POLICY_BATTERY, getCustomDefaultCpuPolicyBattery());

    powerGsettings.set(GSETTINGS_KEY_IDLE_BRIGHTNESS, getCustomDefaultIdleBrightness());

    powerGsettings.set(GSETTINGS_KEY_IDLE_POWER_POLICY_AUTO, getCustomDefaultIdlePowerPolicyAuto());

    powerGsettings.set(PREPROCESS_POWER_MODE, true);
}

void UpmCustomDefaultGsettings::getHardwareInfo()
{
    if (false == readAll(UPM_HARDWARE_INFO_FILE, m_hardwareInfo)) {
        qDebug() << "get hardware info failed";
    }
}

int UpmCustomDefaultGsettings::getCustomDefaultCpuPolicyAc()
{
    if (true == getGlobalCpuDefaultPolicy(UPM_GROUP_DEFAULT_POLICY_AC,
                                          UPM_KEY_BALANCE_MODE_BOARD_NAME)) {
        return power_policy_balance;
    }
    if (true == getGlobalCpuDefaultPolicy(UPM_GROUP_DEFAULT_POLICY_AC,
                                          UPM_KEY_POWERSAVE_MODE_BOARD_NAME)) {
        return power_policy_powersave;
    }

    if (nullptr != m_extendConfig) {
        QVariant value;
        int cpuPolicy = power_policy_performance;
        if (true == readConfig(m_extendConfig,
                               UPM_GROUP_EXTEND_BRAND_GENERIC_CONFIG,
                               GSETTINGS_KEY_POWER_POLICY_AC, value)) {
            cpuPolicy = value.toInt();
        }
        if (true == readConfig(m_extendConfig, m_productGroup,
                               GSETTINGS_KEY_POWER_POLICY_AC, value)) {
            cpuPolicy = value.toInt();
        }
        return cpuPolicy;
    }
    return power_policy_performance;
}

int UpmCustomDefaultGsettings::getCustomDefaultCpuPolicyBattery()
{
    if (true == getGlobalCpuDefaultPolicy(UPM_GROUP_DEFAULT_POLICY_BATTERY,
                                          UPM_KEY_BALANCE_MODE_BOARD_NAME)) {
        return power_policy_balance;
    }
    if (true == getGlobalCpuDefaultPolicy(UPM_GROUP_DEFAULT_POLICY_BATTERY,
                                          UPM_KEY_POWERSAVE_MODE_BOARD_NAME)) {
        return power_policy_powersave;
    }

    if (nullptr != m_extendConfig) {
        QVariant value;
        int cpuPolicy = power_policy_performance;
        if (true == readConfig(m_extendConfig,
                               UPM_GROUP_EXTEND_BRAND_GENERIC_CONFIG,
                               GSETTINGS_KEY_POWER_POLICY_BATTERY, value)) {
            cpuPolicy = value.toInt();
        }
        if (true == readConfig(m_extendConfig, m_productGroup,
                               GSETTINGS_KEY_POWER_POLICY_BATTERY, value)) {
            cpuPolicy = value.toInt();
        }
        return cpuPolicy;
    }
    return power_policy_performance;
}

int UpmCustomDefaultGsettings::getCustomDefaultIdleBrightness()
{
    if (nullptr != m_extendConfig) {
        QVariant value;
        if (true == readConfig(m_extendConfig, m_productGroup,
                               GSETTINGS_KEY_IDLE_BRIGHTNESS, value)) {
            return value.toInt();
        }
    }
    return 70;
}

bool UpmCustomDefaultGsettings::getCustomDefaultIdlePowerPolicyAuto()
{
    if (nullptr != m_extendConfig) {
        QVariant value;
        if (true == readConfig(m_extendConfig, m_productGroup,
                               GSETTINGS_KEY_IDLE_POWER_POLICY_AUTO, value)) {
            if (1 == value.toInt()) {
                return true;
            }
        }
    }
    return false;
}

bool UpmCustomDefaultGsettings::getGlobalCpuDefaultPolicy(const QString &group, const QString &key)
{
    QVariant value;
    if (true == readConfig(m_globalConfig, group, key, value)) {
        QStringList boards = value.toString().split(",");
        Q_FOREACH (const QString &board, boards) {
            if (m_hardwareInfo.contains(board, Qt::CaseInsensitive) && !board.isEmpty()) {
                return true;
            }
        }
    }
    return false;
}

bool UpmCustomDefaultGsettings::readConfig(
        QSettings *settings,
        const QString &group,
        const QString &key,
        QVariant &value)
{
    if (nullptr == settings) {
        return false;
    }
    settings->beginGroup(group);
    value = settings->value(key, UPM_NO_THIS_KEY);
    settings->endGroup();

    if (UPM_NO_THIS_KEY == value.toString()) {
        return false;
    }
    return true;
}

bool UpmCustomDefaultGsettings::getExtendConfigFile(QString &configFilePath)
{
    QDir extendConfigDir(UPM_EXTEND_GSETTINGS_CONFIG_PATH);

    if (true == extendConfigDir.exists()) {
        QStringList extendConfigs = extendConfigDir.entryList(QDir::Files | QDir::NoDotAndDotDot);
        Q_FOREACH (const QString &extendConfig, extendConfigs) {
            QStringList fileName = extendConfig.split(".");
            if (m_hardwareInfo.contains(fileName[0], Qt::CaseInsensitive)) {
                configFilePath = QString(UPM_EXTEND_GSETTINGS_CONFIG_PATH) + extendConfig;
                return true;
            }
        }
    }
    return false;
}

bool UpmCustomDefaultGsettings::readAll(const QString &filePath, QString &content)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "read file error :" << filePath;
        return false;
    }

    content = file.readAll();
    file.close();

    return true;
}
