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

UpmSystemIdle::UpmSystemIdle(QObject *parent) : QObject(parent)
{
    QStringList valueRange = {QString::number(300), QString::number(600),
                              QString::number(900), QString::number(1800),
                              QString::number(3600), QString::number(7200),
                              QString::number(10800), QString::number(-1)};
    m_turnoffDisplayAc = UpmCheckConfig::checkConfig(
                GSETTINGS_KEY_SLEEP_DISPLAY_AC,
                DEFAULE_SLEEP_DISPLAY_TIME, QVariant::Int,
                valueRange, false).toInt();
    m_turnoffDisplayBattery = UpmCheckConfig::checkConfig(
                GSETTINGS_KEY_SLEEP_DISPLAY_BATTERY,
                DEFAULE_SLEEP_DISPLAY_TIME, QVariant::Int,
                valueRange, false).toInt();
    m_systemSuspendAc = UpmCheckConfig::checkConfig(
                GSETTINGS_KEY_SLEEP_COMPUTER_AC,
                DEFAULE_SLEEP_COMPUTER_TIME, QVariant::Int,
                valueRange, false).toInt();
    m_systemSuspendBattery = UpmCheckConfig::checkConfig(
                GSETTINGS_KEY_SLEEP_COMPUTER_BATTERY,
                DEFAULE_SLEEP_COMPUTER_TIME, QVariant::Int,
                valueRange, false).toInt();

    connect(UpmGsettings::self(), &UpmGsettings::sleepDisplayAcChanged,
            this, [=](QVariant value) {
        m_turnoffDisplayAc = value.toInt();
        UpmControlDBus::self()->setUpmSystemConfig(GSETTINGS_KEY_SLEEP_DISPLAY_AC,
                                                   QString::number(m_turnoffDisplayAc));
    });
    connect(UpmGsettings::self(), &UpmGsettings::sleepDisplayBatteryChanged,
            this, [=](QVariant value) {
        m_turnoffDisplayBattery = value.toInt();
        UpmControlDBus::self()->setUpmSystemConfig(GSETTINGS_KEY_SLEEP_DISPLAY_BATTERY,
                                                   QString::number(m_turnoffDisplayBattery));
    });
    connect(UpmGsettings::self(), &UpmGsettings::sleepComputerAcChanged,
            this, [=](QVariant value) {
        m_systemSuspendAc = value.toInt();
        UpmControlDBus::self()->setUpmSystemConfig(GSETTINGS_KEY_SLEEP_COMPUTER_AC,
                                                   QString::number(m_systemSuspendAc));
    });
    connect(UpmGsettings::self(), &UpmGsettings::sleepComputerBatteryChanged,
            this, [=](QVariant value) {
        m_systemSuspendBattery = value.toInt();
        UpmControlDBus::self()->setUpmSystemConfig(GSETTINGS_KEY_SLEEP_COMPUTER_BATTERY,
                                                   QString::number(m_systemSuspendBattery));
    });

    connect(UpmCommonDBus::self(), &UpmCommonDBus::systemSleepStatus,
            this, &UpmSystemIdle::stopTimer);

    connect(UpmCommonDBus::self(), &UpmCommonDBus::systemIdleStatus,
            this, &UpmSystemIdle::dealSystemIdleStatus);

    m_turnOffDisplayTimer = new QTimer(this);
    connect(m_turnOffDisplayTimer, &QTimer::timeout,
            this, &UpmSystemIdle::dealTurnOffDisplay);
    m_systemSuspendTimer = new QTimer(this);
    connect(m_systemSuspendTimer, &QTimer::timeout,
            this, &UpmSystemIdle::dealSystemSuspend);
    m_reduceBrightnessTimer = new QTimer(this);
    connect(m_reduceBrightnessTimer, &QTimer::timeout,
            this, &UpmSystemIdle::dealReduceBrightness);
}

void UpmSystemIdle::dealSystemIdleStatus(bool systemIdle)
{
    int turnOffDisplayTime = getTurnOffDisplayTime();
    int systemSuspendTime = getSystemSuspendTime();
    int reduceBrightness = -1;
    QVariant value;

    qDebug() << "system enter idle:" << systemIdle;
    if (true == systemIdle) {
        if (turnOffDisplayTime > 0) {
            m_turnOffDisplayTimer->start(turnOffDisplayTime * 1000);
        } else {
            qDebug() << "turn off display timer not started!";
        }
        if (systemSuspendTime > 0) {
            m_systemSuspendTimer->start(systemSuspendTime * 1000);
        } else {
            qDebug() << "system suspend timer not started!";
        }

        if (turnOffDisplayTime > 0) {
            reduceBrightness = turnOffDisplayTime - 10;
            m_reduceBrightnessTimer->start(reduceBrightness * 1000);
            qDebug() << "reduce brightness time:" << reduceBrightness;
        }

        if (true == UpmUpowerDBus::self()->getAcOnlineState()) {
            if (true == UpmGsettings::self()->getGsettingsConfig(
                        GSETTINGS_KEY_POWER_POLICY_AC, value)) {
                if (power_policy_balance == value.toInt()) {
                    UpmControlDBus::self()->controlPowerManagement(
                                UPM_DBUS_METHOD_SET_GPU_POLICY,
                                power_policy_powersave);
                }
            }
        } else {
            if (true == UpmGsettings::self()->getGsettingsConfig(
                        GSETTINGS_KEY_POWER_POLICY_BATTERY, value)) {
                if (power_policy_balance == value.toInt()) {
                    UpmControlDBus::self()->controlPowerManagement(
                                UPM_DBUS_METHOD_SET_GPU_POLICY,
                                power_policy_powersave);
                }
            }
        }
    } else {
        stopTimer();
        emit brightnessControlSignal(INCREASE_BRIGHTNESS);
        if (true == UpmUpowerDBus::self()->getAcOnlineState()) {
            if (true == UpmGsettings::self()->getGsettingsConfig(
                        GSETTINGS_KEY_POWER_POLICY_AC, value)) {
                if (power_policy_balance == value.toInt()) {
                    UpmControlDBus::self()->controlPowerManagement(
                                UPM_DBUS_METHOD_SET_GPU_POLICY,
                                power_policy_balance);
                }
            }
        } else {
            if (true == UpmGsettings::self()->getGsettingsConfig(
                        GSETTINGS_KEY_POWER_POLICY_BATTERY, value)) {
                if (power_policy_balance == value.toInt()) {
                    UpmControlDBus::self()->controlPowerManagement(
                                UPM_DBUS_METHOD_SET_GPU_POLICY,
                                power_policy_balance);
                }
            }
        }
    }
}

int UpmSystemIdle::getTurnOffDisplayTime()
{
    int turnOffDisplayTime = 0;

    if (true == UpmUpowerDBus::self()->getAcOnlineState()) {
        turnOffDisplayTime = m_turnoffDisplayAc - m_enterIdleTime;
    } else {
        turnOffDisplayTime = m_turnoffDisplayBattery - m_enterIdleTime;
    }
    return turnOffDisplayTime;
}

int UpmSystemIdle::getSystemSuspendTime()
{
    int systemSuspendTime = 0;

    if (true == UpmUpowerDBus::self()->getAcOnlineState()) {
        systemSuspendTime = m_systemSuspendAc - m_enterIdleTime;
    } else {
        systemSuspendTime = m_systemSuspendBattery - m_enterIdleTime;
    }
    return systemSuspendTime;
}

void UpmSystemIdle::dealTurnOffDisplay()
{
    UpmControlDBus::self()->delayLockScreen("idle");
    UpmControlDBus::self()->controlDisplay("off");
    UpmControlDBus::self()->turnOffDisplaySignal();
    m_turnOffDisplayTimer->stop();
}

void UpmSystemIdle::dealSystemSuspend()
{
    UpmControlDBus::self()->controlPowerManagement("Suspend", 0, false);
    m_systemSuspendTimer->stop();
}

void UpmSystemIdle::dealReduceBrightness()
{
    emit brightnessControlSignal(REDUCE_BRIGHTNESS);
    m_reduceBrightnessTimer->stop();
}

void UpmSystemIdle::stopTimer()
{
    qDebug() << "stop timer";
    if (m_turnOffDisplayTimer->isActive()) {
        m_turnOffDisplayTimer->stop();
    }
    if (m_systemSuspendTimer->isActive()) {
        m_systemSuspendTimer->stop();
    }
    if (m_reduceBrightnessTimer->isActive()) {
        m_reduceBrightnessTimer->stop();
    }
}
