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

ChargingSchedule::ChargingSchedule() : TimeFrame()
{

}

ChargingSchedule::ChargingSchedule(const ThingId &evChargerId) :
    TimeFrame(),
    m_evChargerId{evChargerId}
{

}

ChargingSchedule::ChargingSchedule(const ThingId &evChargerId, const TimeFrame &timeFrame) :
    TimeFrame(timeFrame),
    m_evChargerId{evChargerId}
{

}

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

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

ChargingAction ChargingSchedule::action() const
{
    return m_action;
}

void ChargingSchedule::setAction(const ChargingAction &action)
{
    m_action = action;
}

void ChargingSchedule::clear()
{
    m_startDateTime = QDateTime();
    m_endDateTime = QDateTime();
    m_action = ChargingAction();
}

ChargingSchedules::ChargingSchedules()
{

}

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

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

ChargingSchedule ChargingSchedules::getChargingSchedule(const QDateTime &dateTime) const
{
    foreach (const ChargingSchedule &schedule, *this) {
        if (schedule.isActive(dateTime)) {
            return schedule;
        }
    }

    return ChargingSchedule();
}

uint ChargingSchedules::removeAllIssuer(ChargingAction::ChargingActionIssuer issuer)
{
    uint count = 0;
    foreach(const ChargingSchedule &schedule, *this) {
        if (schedule.action().issuer() == issuer) {
            this->removeAll(schedule);
            count++;
        }
    }
    return count;
}

ChargingSchedules ChargingSchedules::filterByIssuer(ChargingAction::ChargingActionIssuer issuer) const
{
    ChargingSchedules schedules;
    foreach(const ChargingSchedule &schedule, *this) {
        if (schedule.action().issuer() == issuer) {
            schedules.append(schedule);
        }
    }
    return schedules;
}

QDebug operator<<(QDebug debug, const ChargingSchedule &chargingSchedule)
{
    const QDebugStateSaver saver(debug);
    debug.nospace() << "ChargingSchedule(" << chargingSchedule.startDateTime().toString("dd.MM.yyyy hh:mm");
    debug.nospace() << " - "<<  chargingSchedule.endDateTime().toString("dd.MM.yyyy hh:mm");
    debug.nospace() << ", " << chargingSchedule.action().maxChargingCurrent() << "A";
    debug.nospace() << ", Power: " << (chargingSchedule.action().chargingEnabled() ? "ON" : "OFF");
    debug.nospace() << ", Issuer: ";
    switch (chargingSchedule.action().issuer()) {
    case ChargingAction::ChargingActionIssuerUnknown:
        debug.nospace() << "Unknown";
        break;
    case ChargingAction::ChargingActionIssuerSurplusCharging:
        debug.nospace() << "Surplus";
        break;
    case ChargingAction::ChargingActionIssuerSpotMarketCharging:
        debug.nospace() << "Spot market";
        break;
    case ChargingAction::ChargingActionIssuerTimeRequirement:
        debug.nospace() << "Time requirement";
        break;
    case ChargingAction::ChargingActionIssuerOverloadProtection:
        debug.nospace() << "Overload protection";
        break;
    }

    debug.nospace()  << ")";
    return debug;
}

QDebug operator<<(QDebug debug, const ChargingSchedules &chargingSchedules)
{
    const QDebugStateSaver saver(debug);
    debug.nospace() << "ChargingSchedule(" << chargingSchedules.count() << ")\n";
    for (int i = 0; i < chargingSchedules.count(); i++) {
        debug.nospace() << " - " << i << " -> " << chargingSchedules.at(i) << "\n";
    }
    return debug;
}
