#pragma once
#include <string>
#include <unordered_map>
#include <vector>

//#include <iostream> // debug

namespace DSMR
{
    enum class LineTag
    {
        Unknown = -1,
        DSMRversion,
        DateTimeStamp,
        SerialNo,
        TotalPowerConsumedTariff1,
        TotalPowerConsumedTariff2,
        TotalReturnedPowerTariff1,
        TotalReturnedPowerTariff2,
        CurrentTarif,
        CurrentPowerConsumption,
        CurrentPowerReturn,
        PowerFailureCount,
        PowerFailureLongCount,
        PowerFailureEventLog,
        VoltageL1SagCount,
        VoltageL2SagCount,
        VoltageL3SagCount,
        VoltageL1SwellCount,
        VoltageL2SwellCount,
        VoltageL3SwellCount,
        TextMessageMaxChar,
        InstantL1VoltageResolution,
        InstantL2VoltageResolution,
        InstantL3VoltageResolution,
        InstantL1CurrentResolution,
        InstantL2CurrentResolution,
        InstantL3CurrentResolution,
        InstantL1ActivePowerResolution,
        InstantL2ActivePowerResolution,
        InstantL3ActivePowerResolution,
        InstantL1ActivePowerResolutionA,
        InstantL2ActivePowerResolutionA,
        InstantL3ActivePowerResolutionA,
        DeviceType,
        GasDeviceIdentifier,
        GasTotalConsumptionLog
    };

    // DSMR output parser for Landis Gyr E350, we only extract things that interest us.
    class Data {
    private:
        static const std::unordered_map<std::string, LineTag> & GetMap();

        static void RemoveUnit(std::string & value);

        // Single argument lines only
        static std::pair<std::string, std::string> GetKeyValuePair(const std::string & line);

    public:
        double currentPowerUsageKw = 0.0, currentPowerReturnKw = 0.0;
        double totalPowerConsumptionDayKwh = 0.0, totalPowerConsumptionNightKwh = 0.0;
        double totalPowerReturnedDayKwh = 0.0, totalPowerReturnedNightKwh = 0.0;
        bool usingDayTarif = true;
        std::string gasTimestamp = "";
        double gasConsumptionCubicMeters = 0.0; // m^3

        void ParseLine(const std::string & line);
        void ParseLines(const std::vector<std::string> & lines);

        std::string GetFormattedString(char const separator) const;
    };
}
