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

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

#include "brightnessnode.h"

BrightnessNode::BrightnessNode(int percent, QObject *parent) : QObject(parent)
{
    qDebug() << "init brightness node info";

    m_hasEffectiveNode = false;

    m_maxbrightness = 0;

    QString brightnessNode = UpmCustomHardwareConfig::self()->getBrightnessNode();

    qDebug() << "get brightness node:" << brightnessNode;
    if (brightnessNode.isNull()) {
        qDebug() << "brightness node is null";
        m_effectiveNodePath = QString();
        initBrightnessNodeInfo();
    } else {
        m_effectiveNodePath = BRIGHTNESS_NODE_PATH + brightnessNode;
        QDir brightnessDir(m_effectiveNodePath);
        if (brightnessDir.exists()) {
            qDebug() << "brightness dir :" << m_effectiveNodePath;
            m_maxbrightness = getBrightnessNodeFileContent(m_effectiveNodePath, "/max_brightness").toInt();
            m_hasEffectiveNode = true;
        } else {
            qDebug() << "brightness dir no exists";
            m_effectiveNodePath = QString();
            initBrightnessNodeInfo();
        }
    }

    m_effectiveMaxbrightness = m_maxbrightness;

    qDebug() << "node path :" << m_effectiveNodePath;

    setBrightnessPercent(percent);
}

BrightnessNode::~BrightnessNode() {}

void BrightnessNode::initBrightnessNodeInfo()
{
    QDir brightnessNodeDir(BRIGHTNESS_NODE_PATH);

    m_nodeDirs = brightnessNodeDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    int i = 0;
    QStringList allNodesType;
    for (i = 0; i < m_nodeDirs.size(); ++i) {
        allNodesType << getBrightnessNodeFileContent(BRIGHTNESS_NODE_PATH + m_nodeDirs.at(i), "/type");
    }

    QStringList nodeTypes = {"firmware", "platform", "raw"};
    for (i = 0; i < nodeTypes.size(); ++i) {
        if (true == getEffectiveBrightnessNode(allNodesType, nodeTypes.at(i))) {
            m_hasEffectiveNode = true;
            m_maxbrightness = getBrightnessNodeFileContent(m_effectiveNodePath, "/max_brightness").toInt();
            break;
        }
    }
}

bool BrightnessNode::getEffectiveBrightnessNode(const QStringList &nodesType, const QString &type)
{
    int nodesNum = 0;
    int nodeIndex = 0;

    for (int i = 0; i < nodesType.size(); ++i) {
        if (type == nodesType.at(i)) {
            nodesNum++;
            nodeIndex = i;
        }
    }

    if (1 == nodesNum) {
        m_effectiveNodePath = BRIGHTNESS_NODE_PATH + m_nodeDirs.at(nodeIndex);
        return true;
    }
    return false;
}

QString BrightnessNode::getBrightnessNodeFileContent(const QString &strNodePath, const QString &strNodeFile)
{
    QFile nodeFile(strNodePath + strNodeFile);
    if (!nodeFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qDebug() << "open file error :" << strNodePath + strNodeFile;
        return "";
    }

    QString fileContent = nodeFile.readLine();
    nodeFile.close();

    return fileContent.remove('\n');
}

bool BrightnessNode::canSetBrightness()
{
    return m_hasEffectiveNode;
}

int BrightnessNode::getCurrentBrightness()
{
    return getBrightnessNodeFileContent(m_effectiveNodePath, "/brightness").toInt();
}

void BrightnessNode::setCurrentBrightness(int brightness)
{
    if (false == m_hasEffectiveNode) {
        return ;
    }

    QFile brightnessFile(m_effectiveNodePath + "/brightness");
    if (!brightnessFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
        return ;
    }
    QTextStream in(&brightnessFile);
    in << brightness << endl;
    brightnessFile.close();
}

void BrightnessNode::setBrightnessPercent(int percent)
{
    if (m_brightnessPercent == percent) {
        return;
    }

    if (percent < RESERVE_BRIGHTNESS_PERCENT) {
        setCurrentBrightness(m_effectiveMaxbrightness * 0.02);
        m_brightnessPercent = percent;
        qDebug() << "BrightnessNode percent < 2:" << percent;
    } else {
        if (percent > 100) {
            setCurrentBrightness(m_effectiveMaxbrightness);
            m_brightnessPercent = 100;
            qDebug() << "BrightnessNode percent > 100:" << percent;
        } else {
            setCurrentBrightness(m_effectiveMaxbrightness * percent * 0.01);
            m_brightnessPercent = percent;
            qDebug() << "BrightnessNode  0 < percent < 100:" << percent;
        }
    }
}

int BrightnessNode::getBrightnessPercent()
{
    return m_brightnessPercent;
}

int BrightnessNode::getMaxBrightness()
{
    return m_maxbrightness;
}

void BrightnessNode::setReduceMaxBrightness(bool value)
{
    if (true == value) {
        m_effectiveMaxbrightness = m_maxbrightness * 0.7;
    } else {
        m_effectiveMaxbrightness = m_maxbrightness;
    }

    setBrightnessPercent(m_brightnessPercent);
}
