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

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

Q_GLOBAL_STATIC(UpmCustomHardwareConfig, s_upmCustomHardwareConfig)

UpmCustomHardwareConfig::UpmCustomHardwareConfig(QObject *parent) : QObject(parent)
{
    getHardwareInfo();
    getCpuType();

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

    m_globalConfig->beginGroup(UPM_GROUP_THIS_PRODUCT);
    //是否是首次运行
    if (1 == m_globalConfig->value(UPM_KEY_FIRST_RUN).toInt()) {
        //是否有扩展配置，对应品牌
        if (true == getExtendConfigFile(m_extendConfigPath)) {
            //有扩展配置，将配置文件路径写入全局配置文件
            m_globalConfig->setValue(UPM_KEY_EXTEND_CONFIG_PATH, m_extendConfigPath);

            m_extendConfig = new QSettings(m_extendConfigPath, QSettings::IniFormat, this);
            m_extendConfig->beginGroup("product");

            //配置文件中group[product]为产品标识，标识与硬件信息对应做为group，标识下的key为配置内容
            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;
                        m_globalConfig->setValue(UPM_KEY_DEVICE_IDENTIFICATION, m_productGroup);
                    }
                    break;
                }
            }
            m_extendConfig->endGroup();
        }
        m_globalConfig->setValue(UPM_KEY_FIRST_RUN, 0);
    } else {
        //不是首次运行，直接从全局配置中读取配置文件及产品标识
        m_extendConfigPath = m_globalConfig->value(UPM_KEY_EXTEND_CONFIG_PATH).toString();
        m_productGroup = m_globalConfig->value(UPM_KEY_DEVICE_IDENTIFICATION).toString();
        if (false == m_extendConfigPath.isEmpty()) {
            qDebug() << "extend config path:" << m_extendConfigPath;
            m_extendConfig = new QSettings(m_extendConfigPath, QSettings::IniFormat, this);
        }
    }

    m_globalConfig->endGroup();
    m_globalConfig->sync();
}

UpmCustomHardwareConfig::~UpmCustomHardwareConfig() {}

UpmCustomHardwareConfig *UpmCustomHardwareConfig::self()
{
    return s_upmCustomHardwareConfig;
}

bool UpmCustomHardwareConfig::isPanguM900()
{
    if (true == m_cpuType.contains("PANGU M900", Qt::CaseInsensitive)) {
        return true;
    }
    return false;
}

bool UpmCustomHardwareConfig::isHygonCpu()
{
    if (true == m_cpuType.contains("Hygon", Qt::CaseInsensitive)) {
        return true;
    }
    return false;
}

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

    return true;
}

QString UpmCustomHardwareConfig::getBrightnessNode()
{
    if (nullptr != m_extendConfig) {
        QVariant value;
        if (true == readConfig(m_extendConfig, m_productGroup,
                               UPM_KEY_EXTEND_BRIGHTNESS_NODE, value)) {
            return value.toString();
        }
    }

    QStringList cpuAndNodes = {"ZHAOXIN:acpi_video0",
                               "loongson:loongson-gpu",
                               "Phytium:ec_bl"};

    Q_FOREACH (const QString &str, cpuAndNodes) {
        QStringList cpuAndNode = str.split(":");
        if (m_cpuType.contains(cpuAndNode[0], Qt::CaseInsensitive)) {
            return cpuAndNode[1];
        }
    }

    return QString();
}

bool UpmCustomHardwareConfig::firstRunDonotSuspend()
{
    if (nullptr != m_extendConfig) {
        QVariant value;
        if (true == readConfig(m_extendConfig,
                               UPM_GROUP_EXTEND_BRAND_GENERIC_CONFIG,
                               UPM_KEY_FIRST_RUN_DONOT_SUSPEND, value)) {
            if (1 == value.toInt()) {
                return true;
            }
        }
    }
    return false;
}

bool UpmCustomHardwareConfig::getExtendConfig(const QString &configKey, QString &config)
{
    QVariant value;
    if (true == readConfig(m_extendConfig, m_productGroup, configKey, value)) {
        config = value.toString();
        return true;
    }
    return false;
}

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

void UpmCustomHardwareConfig::getCpuType()
{
    if (false == readAll(UPM_CPU_INFO_FILE, m_cpuType)) {
        qDebug() << "get cpu info failed";
    }
}

bool UpmCustomHardwareConfig::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 UpmCustomHardwareConfig::getExtendConfigFile(QString &configFilePath)
{
    QDir extendConfigDir(UPM_EXTEND_HARDWARE_CONFIG_PATH);

    if (true == extendConfigDir.exists()) {
        QStringList extendConfigs = extendConfigDir.entryList(QDir::Files | QDir::NoDotAndDotDot);
        qDebug() << "dirs :" << extendConfigDir;
        Q_FOREACH (const QString &extendConfig, extendConfigs) {
            qDebug() << "extend config:" << extendConfig;
            QStringList fileName = extendConfig.split(".");
            qDebug() << "fileName:" << fileName;
            if (m_hardwareInfo.contains(fileName[0], Qt::CaseInsensitive)) {
                configFilePath = QString(UPM_EXTEND_HARDWARE_CONFIG_PATH) + extendConfig;
                qDebug() << "configFilePath:" << configFilePath;
                return true;
            }
        }
    }
    qDebug() << "get extend config file failed";
    return false;
}

bool UpmCustomHardwareConfig::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;
}
