#include "Globals.h"
#include "DataTypeDef.h"

#include <QMutex>
#include <QTime>
#include <QDebug>
#include <QMutexLocker>

Globals* globalInstance = nullptr;
Globals *Globals::instance()
{
    static QMutex mutex;
    if (!globalInstance) {
        QMutexLocker locker(&mutex);
        if (!globalInstance) {
            globalInstance = new Globals();
        }
    }

    return globalInstance;
}

void Globals::setValue(const QString &key, const QVariant &value)
{
    QMutexLocker locker(&m_mutex);
    if (m_values.value(key) != value) {
        m_values.insert(key, value);
        // emit valueChanged(key, value);
        signalGeneration(key, value);
    }
}

QVariant Globals::getValue(const QString &key, const QVariant &defaultValue)
{
    QMutexLocker locker(&m_mutex);
    return m_values.value(key, defaultValue);
}

bool Globals::contains(const QString &key) const
{
    QMutexLocker locker(&m_mutex);
    return m_values.contains(key);
}

uint8_t Globals::getKeyIndex(const QString &key)
{
    auto values = m_keys.values();
    if (values.contains(key)) {
        return m_keys.key(key);
    }
    return 0;
}

Globals::Globals(QObject *parent)
    : QObject{parent}
{
    m_keys.insert(GLOBALS_GUN_BASIC_INFO_KEY_1,         Global::Keys::GUN_BASIC_INFO_1);
    m_keys.insert(GLOBALS_GUN_BASIC_INFO_KEY_2,         Global::Keys::GUN_BASIC_INFO_2);
    m_keys.insert(GLOBALS_CHARGING_INFO_KEY_1,          Global::Keys::CHARGING_INFO_1);
    m_keys.insert(GLOBALS_CHARGING_INFO_KEY_2,          Global::Keys::CHARGING_INFO_2);
    m_keys.insert(GLOBALS_GUN_ERROR_KEY_1,              Global::Keys::GUN_ERROR_1);
    m_keys.insert(GLOBALS_GUN_ERROR_KEY_2,              Global::Keys::GUN_ERROR_2);
    m_keys.insert(GLOBALS_GUN_STATE_KEY_1,              Global::Keys::GUN_STATE_1);
    m_keys.insert(GLOBALS_GUN_STATE_KEY_2,              Global::Keys::GUN_STATE_2);
    m_keys.insert(GLOBALS_GUN_TYPE_KEY_1,               Global::Keys::GUN_TYPE_1);
    m_keys.insert(GLOBALS_GUN_TYPE_KEY_2,               Global::Keys::GUN_TYPE_2);
    m_keys.insert(GLOBALS_AUTH_LIST_KEY,                Global::Keys::AUTH_LIST);
    m_keys.insert(GLOBALS_CCU_CFG_KEY,                  Global::Keys::CCU_CFG);
    m_keys.insert(GLOBALS_CHARGING_PROFILES_KEY,        Global::Keys::CHARGING_PROFILES);
    m_keys.insert(GLOBALS_CFG_KEY_KEY,                  Global::Keys::CFG_KEY);
    m_keys.insert(GLOBALS_OFFLINE_CHARGING_RECORDS_KEY, Global::Keys::OFFLINE_CHARGING_RECORDS);
    m_keys.insert(GLOBALS_TCU_CFG_KEY,                  Global::Keys::TCU_CFG);
    m_keys.insert(GLOBALS_PCU_CFG_KEY,                  Global::Keys::PCU_CFG);
    m_keys.insert(GLOBALS_PRICE_INFO_KEY,               Global::Keys::PRICEINFO);
    m_keys.insert(GLOBALS_VERSION_KEY,                  Global::Keys::VERSION);
}

void Globals::signalGeneration(const QString &key, const QVariant &value)
{
    switch (m_keys.key(key)) {
    case GLOBALS_GUN_BASIC_INFO_KEY_1:
    case GLOBALS_GUN_BASIC_INFO_KEY_2:
        emit chargeGunBasicValueChanged(value.value<BASIC_INFO>());
        break;
    case GLOBALS_CHARGING_INFO_KEY_1:
    case GLOBALS_CHARGING_INFO_KEY_2:
        emit chargeInfoValueChanged(value.value<CHARGING_INFO>());
        break;
    case GLOBALS_GUN_ERROR_KEY_1:
        emit gunErrorValueChanged_1(value.value<UINT32_QSTRING_MAP>());
        break;
    case GLOBALS_GUN_ERROR_KEY_2:
        emit gunErrorValueChanged_2(value.value<UINT32_QSTRING_MAP>());
        break;
    case GLOBALS_GUN_STATE_KEY_1:
        emit gunStateValueChanged_1(value.value<UINT32_QSTRING_MAP>());
        break;
    case GLOBALS_GUN_STATE_KEY_2:
        emit gunStateValueChanged_2(value.value<UINT32_QSTRING_MAP>());
        break;
    case GLOBALS_GUN_TYPE_KEY_1:
        emit gunTypeValueChanged_1(value.value<UINT8_QSTRING_MAP>());
        break;
    case GLOBALS_GUN_TYPE_KEY_2:
        emit gunTypeValueChanged_2(value.value<UINT8_QSTRING_MAP>());
        break;
    case GLOBALS_AUTH_LIST_KEY:
        emit authListValueChanged(value.value<AUTH_LIST>());
        break;
    case GLOBALS_CCU_CFG_KEY:
        emit ccuConfigValueChanged(value.value<CCU_CFG>());
        break;
    case GLOBALS_CHARGING_PROFILES_KEY:
        emit chargingProfilesValueChanged(value.value<CHARGING_PROFILES>());
        break;
    case GLOBALS_CFG_KEY_KEY:
        emit ocppConfigKeyValueChanged(value.value<CONFIG_KEY_INFO>());
        break;
    case GLOBALS_OFFLINE_CHARGING_RECORDS_KEY:
        emit chargingRecordsValueChanged(value.value<CHARGING_RECORDS_INFO>());
        break;
    case GLOBALS_TCU_CFG_KEY:
        emit tcuConfigValueChanged(value.value<TCU_CFG>());
        break;
    case GLOBALS_PCU_CFG_KEY:
        emit pcuConfigValueChanged(value.value<PCU_CFG>());
        break;
    case GLOBALS_PRICE_INFO_KEY:
        emit priceInfoValueChanged(value.value<PRICE_INFO>());
        break;
    case GLOBALS_VERSION_KEY:
        emit versionValueChanged(value.value<VERSION>());
        break;
    default:
        emit valueChanged(key, value);
        break;
    }
}
