// SPDX-License-Identifier: GPL-3.0-or-later

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (C) 2013 - 2024, nymea GmbH
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
*
* This file is part of nymea-energy-plugin-nymea.
*
* nymea-energy-plugin-nymea.s 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.
*
* nymea-energy-plugin-nymea.s 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 nymea-energy-plugin-nymea. If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "flexibleload.h"

QString loadTypeToString(LoadType type)
{
    switch (type) {
    case LoadType::Inflexible: return QStringLiteral("Inflexible");
    case LoadType::Shiftable:  return QStringLiteral("Shiftable");
    case LoadType::Modulable:  return QStringLiteral("Modulable");
    case LoadType::Storage:    return QStringLiteral("Storage");
    }
    return QStringLiteral("Inflexible");
}

LoadType loadTypeFromString(const QString &str)
{
    if (str == QLatin1String("Shiftable"))  return LoadType::Shiftable;
    if (str == QLatin1String("Modulable"))  return LoadType::Modulable;
    if (str == QLatin1String("Storage"))    return LoadType::Storage;
    return LoadType::Inflexible;
}

QString loadSourceToString(LoadSource source)
{
    switch (source) {
    case LoadSource::SmartCharging: return QStringLiteral("SmartCharging");
    case LoadSource::HeatPump:      return QStringLiteral("HeatPump");
    case LoadSource::DHW:           return QStringLiteral("DHW");
    case LoadSource::Battery:       return QStringLiteral("Battery");
    case LoadSource::FeedIn:        return QStringLiteral("FeedIn");
    case LoadSource::External:      return QStringLiteral("External");
    }
    return QStringLiteral("External");
}

LoadSource loadSourceFromString(const QString &str)
{
    if (str == QLatin1String("SmartCharging")) return LoadSource::SmartCharging;
    if (str == QLatin1String("HeatPump"))      return LoadSource::HeatPump;
    if (str == QLatin1String("DHW"))           return LoadSource::DHW;
    if (str == QLatin1String("Battery"))       return LoadSource::Battery;
    if (str == QLatin1String("FeedIn"))        return LoadSource::FeedIn;
    return LoadSource::External;
}

QVariantMap FlexibleLoad::toJson() const
{
    QVariantMap map;
    map.insert("thingId",        thingId.toString());
    map.insert("displayName",    displayName);
    map.insert("type",           loadTypeToString(type));
    map.insert("source",         loadSourceToString(source));
    map.insert("minPowerW",      minPowerW);
    map.insert("maxPowerW",      maxPowerW);
    map.insert("currentPowerW",  currentPowerW);
    if (deadline.isValid())
        map.insert("deadline",   deadline.toUTC().toString(Qt::ISODateWithMs));
    map.insert("targetValue",    targetValue);
    map.insert("currentValue",   currentValue);
    map.insert("priority",       priority);
    map.insert("manualOverride", manualOverride);
    if (!overrideReason.isEmpty())
        map.insert("overrideReason", overrideReason);
    return map;
}

FlexibleLoad FlexibleLoad::fromJson(const QVariantMap &map)
{
    FlexibleLoad load;
    load.thingId       = ThingId(map.value("thingId").toString());
    load.displayName   = map.value("displayName").toString();
    load.type          = loadTypeFromString(map.value("type").toString());
    load.source        = loadSourceFromString(map.value("source").toString());
    load.minPowerW     = map.value("minPowerW").toDouble();
    load.maxPowerW     = map.value("maxPowerW").toDouble();
    load.currentPowerW = map.value("currentPowerW").toDouble();
    if (map.contains("deadline"))
        load.deadline  = QDateTime::fromString(map.value("deadline").toString(), Qt::ISODateWithMs).toUTC();
    load.targetValue   = map.value("targetValue").toDouble();
    load.currentValue  = map.value("currentValue").toDouble();
    load.priority      = map.value("priority").toDouble();
    load.manualOverride= map.value("manualOverride").toBool();
    load.overrideReason= map.value("overrideReason").toString();
    return load;
}

QDebug operator<<(QDebug debug, const FlexibleLoad &load)
{
    const QDebugStateSaver saver(debug);
    debug.nospace() << "FlexibleLoad("
                    << load.displayName
                    << ", " << loadTypeToString(load.type)
                    << ", " << loadSourceToString(load.source)
                    << ", " << load.currentPowerW << "W"
                    << ", priority=" << load.priority
                    << ")";
    return debug;
}
