/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright 2013 - 2025, nymea GmbH
* Contact: contact@nymea.io
*
* This file is part of nymea.
* This project including source code and documentation is protected by
* copyright law, and remains the property of nymea GmbH. All rights, including
* reproduction, publication, editing and translation, are reserved. The use of
* this project is subject to the terms of a license agreement to be concluded
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
* under https://nymea.io/license
*
* GNU Lesser General Public License Usage
* Alternatively, this project may be redistributed and/or modified under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; version 3. This project 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this project. If not, see <https://www.gnu.org/licenses/>.
*
* For any further details and any questions please contact us under
* contact@nymea.io or see our FAQ/Licensing Information on
* https://nymea.io/license/faq
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include "chargingconfiguration.h"

ChargingConfiguration::ChargingConfiguration(const ThingId &evChargerId):
    m_evChargerId(evChargerId)
{

}

ThingId ChargingConfiguration::evChargerId() const
{
    return m_evChargerId;
}

void ChargingConfiguration::setEvChargerId(const ThingId &evChargerId)
{
    m_evChargerId = evChargerId;
}

ThingId ChargingConfiguration::assignedCarId() const
{
    return m_assignedCarId;
}

void ChargingConfiguration::setAssignedCarId(const ThingId &assignedCarId)
{
    m_assignedCarId = assignedCarId;
}

ChargingConfiguration::ChargingMode ChargingConfiguration::chargingMode() const
{
    return m_chargingMode;
}

void ChargingConfiguration::setChargingMode(ChargingMode chargingMode)
{
    m_chargingMode = chargingMode;
}

QDateTime ChargingConfiguration::endDateTime() const
{
    return m_endDateTime;
}

void ChargingConfiguration::setEndDateTime(const QDateTime &endDateTime)
{
    m_endDateTime = endDateTime;
}

QList<int> ChargingConfiguration::repeatDays() const
{
    return m_repeatDays;
}

void ChargingConfiguration::setRepeatDays(const QList<int> &repeatDays)
{
    m_repeatDays = repeatDays;
}

uint ChargingConfiguration::targetPercentage() const
{
    return m_targetPercentage;
}

void ChargingConfiguration::setTargetPercentage(uint targetPercentage)
{
    m_targetPercentage = targetPercentage;
}

uint ChargingConfiguration::dailySpotMarketPercentage() const
{
    return m_dailySpotMarketPercentage;
}

void ChargingConfiguration::setDailySpotMarketPercentage(uint dailySpotMarketPercentage)
{
    m_dailySpotMarketPercentage = dailySpotMarketPercentage;
}

bool ChargingConfiguration::lockOnUnplug() const
{
    return m_lockOnUnplug;
}

void ChargingConfiguration::setLockOnUnplug(bool lockOnUnplug)
{
    m_lockOnUnplug = lockOnUnplug;
}

bool ChargingConfiguration::stopOnTargetPercentage() const
{
    return m_stopOnTargetPercentage;
}

void ChargingConfiguration::setStopOnTargetPercentage(bool stopOnTargetPercentage)
{
    m_stopOnTargetPercentage = stopOnTargetPercentage;
}

QLocale ChargingConfiguration::locale() const
{
    return m_locale;
}

void ChargingConfiguration::setLocale(const QLocale &locale)
{
    m_locale = locale;
}

bool ChargingConfiguration::manualChargingEnabled() const
{
    return m_manualChargingEnabled;
}

void ChargingConfiguration::setManualChargingEnabled(bool manualChargingEnabled)
{
    m_manualChargingEnabled = manualChargingEnabled;
}

double ChargingConfiguration::manualMaxChargingCurrent() const
{
    return m_manualMaxChargingCurrent;
}

void ChargingConfiguration::setManualMaxChargingCurrent(double manualMaxChargingCurrent)
{
    m_manualMaxChargingCurrent = manualMaxChargingCurrent;
}

uint ChargingConfiguration::manualDesiredPhaseCount() const
{
    return m_manualDesiredPhaseCount;
}

void ChargingConfiguration::setManualDesiredPhaseCount(uint manualDesiredPhaseCount)
{
    m_manualDesiredPhaseCount = manualDesiredPhaseCount;
}

QDateTime ChargingConfiguration::nextEndTime(const QDateTime &currentDateTime) const
{
    if (!m_endDateTime.isValid())
        return m_endDateTime;


    if (m_repeatDays.isEmpty()) {
        if (m_endDateTime < currentDateTime) {
            return QDateTime();
        } else {
            return m_endDateTime;
        }
    }

    QDate currentDate = currentDateTime.date();
    while (true) {
        if (m_repeatDays.contains(currentDate.dayOfWeek())) {
            QDateTime nextCandidate(currentDate, m_endDateTime.time());
            if (nextCandidate >= currentDateTime) {
                return nextCandidate;
            }
        }
        currentDate = currentDate.addDays(1);
    }

    return QDateTime();
}

bool ChargingConfiguration::operator==(const ChargingConfiguration &other) const
{
    return m_evChargerId == other.evChargerId() &&
           m_assignedCarId == other.assignedCarId() &&
           m_chargingMode == other.chargingMode() &&
           m_endDateTime == other.endDateTime() &&
           m_repeatDays == other.repeatDays() &&
           m_targetPercentage == other.targetPercentage() &&
           m_dailySpotMarketPercentage == other.dailySpotMarketPercentage() &&
           m_lockOnUnplug == other.lockOnUnplug() &&
           m_stopOnTargetPercentage == other.stopOnTargetPercentage() &&
           m_locale == other.locale() &&
           m_manualChargingEnabled == other.manualChargingEnabled() &&
           m_manualMaxChargingCurrent == other.manualMaxChargingCurrent() &&
           m_manualDesiredPhaseCount == other.manualDesiredPhaseCount();
}

bool ChargingConfiguration::operator!=(const ChargingConfiguration &other) const
{
    return !(*this == other);
}

QDebug operator<<(QDebug debug, const ChargingConfiguration &chargingConfiguration)
{
    const QDebugStateSaver saver(debug);
    debug.nospace().noquote() << "ChargingConfiguration: Charger: " << chargingConfiguration.evChargerId().toString() << ", ";
    debug.nospace().noquote() << "Assigned car: " << chargingConfiguration.assignedCarId().toString() << ", ";
    debug.nospace().noquote() << "ECO settings: End time: " << chargingConfiguration.endDateTime() << " Repeated on: " << chargingConfiguration.repeatDays()
          << " Target percentage: " << chargingConfiguration.targetPercentage()
          << " Locale: " << chargingConfiguration.locale().name() << ", ";
    debug.nospace().noquote() << "Target percentage: " << chargingConfiguration.targetPercentage() << ", ";
    debug.nospace().noquote() << "Charge daily from spot market: " << chargingConfiguration.dailySpotMarketPercentage() << "%, ";
    debug.nospace().noquote() << "Lock on unplug: " << chargingConfiguration.lockOnUnplug() << "%, ";
    debug.nospace().noquote() << "Stop on target percentage: " << chargingConfiguration.stopOnTargetPercentage() << "%, ";
    debug.nospace().noquote() << "Normal mode restore settings: " << (chargingConfiguration.manualChargingEnabled() ? "ON " : "OFF ")
          << chargingConfiguration.manualMaxChargingCurrent() << "A "
          << chargingConfiguration.manualDesiredPhaseCount() << " phases";
    return debug;
}

ChargingConfigurations::ChargingConfigurations()
{

}

ChargingConfigurations::ChargingConfigurations(const QList<ChargingConfiguration> &other): QList<ChargingConfiguration>(other)
{

}

QVariant ChargingConfigurations::get(int index) const
{
    return QVariant::fromValue(at(index));
}

void ChargingConfigurations::put(const QVariant &variant)
{
    append(variant.value<ChargingConfiguration>());
}
