#pragma once

#include <deque>
#include <tuple>
#include <vector>

namespace witherspoon
{
namespace power
{
namespace history
{

static constexpr auto recIDPos = 0;
static constexpr auto recTimePos = 1;
static constexpr auto recAvgPos = 2;
static constexpr auto recMaxPos = 3;
using Record = std::tuple<size_t, int64_t, int64_t, int64_t>;

/**
 * @class InvalidRecordException
 *
 * The exception that is thrown when a raw history record
 * cannot be parsed.
 */
class InvalidRecordException : public std::runtime_error
{
    public:

        InvalidRecordException() :
            std::runtime_error("Invalid history record")
        {
        }
};

/**
 * @class RecordManager
 *
 * This class manages the records for the input power history of
 * a power supply.
 *
 * The history is the average and maximum power values across 30s
 * intervals.  Every 30s, a new record will be available from the
 * PS.  This class takes that raw PS data and converts it into
 * something useable by D-Bus.  It ensures the readings are always
 * sorted newest to oldest, and prunes out the oldest entries when
 * necessary.  If there is a problem with the ordering IDs coming
 * from the PS, it will clear out the old records and start over.
 */
class RecordManager
{
    public:

        static constexpr auto RAW_RECORD_SIZE = 5;
        static constexpr auto RAW_RECORD_ID_OFFSET = 0;
        static constexpr auto FIRST_SEQUENCE_ID = 0;
        static constexpr auto LAST_SEQUENCE_ID = 0xFF;

        using DBusRecord = std::tuple<uint64_t, int64_t>;
        using DBusRecordList = std::vector<DBusRecord>;

        RecordManager() = delete;
        ~RecordManager() = default;
        RecordManager(const RecordManager&) = default;
        RecordManager& operator=(const RecordManager&) = default;
        RecordManager(RecordManager&&) = default;
        RecordManager& operator=(RecordManager&&) = default;

        /**
         * @brief Constructor
         *
         * @param[in] maxRec - the maximum number of history
         *                     records to keep at a time
         */
        RecordManager(size_t maxRec) :
                RecordManager(maxRec, LAST_SEQUENCE_ID)
        {
        }

        /**
         * @brief Constructor
         *
         * @param[in] maxRec - the maximum number of history
         *                     records to keep at a time
         * @param[in] lastSequenceID - the last sequence ID the power supply
         *                             will use before starting over
         */
        RecordManager(size_t maxRec, size_t lastSequenceID) :
                maxRecords(maxRec),
                lastSequenceID(lastSequenceID)
        {
        }

        /**
         * @brief Adds a new entry to the history
         *
         * Also checks to see if the old history should be
         * cleared, such as when there is an invalid record
         * sequence ID or if there was no data from the PS.
         *
         * @param[in] rawRecord - the record data straight
         *                    from the power supply
         *
         * @return bool - If there has been a change to the
         *                history records that needs to be
         *                reflected in D-Bus.
         */
        bool add(const std::vector<uint8_t>& rawRecord);

        /**
         * @brief Converts a Linear Format power number to an integer
         *
         * The PMBus spec describes a 2 byte Linear Format
         * number that is composed of an exponent and mantissa
         * in two's complement notation.
         *
         * Value = Mantissa * 2**Exponent
         *
         * @return int64_t the converted value
         */
        static int64_t linearToInteger(uint16_t data);

        /**
         * @brief Returns the number of records
         *
         * @return size_t - the number of records
         *
         */
        inline size_t getNumRecords() const
        {
            return records.size();
        }

        /**
         * @brief Deletes all records
         */
        inline void clear()
        {
            records.clear();
        }

    private:

        /**
         * @brief returns the sequence ID from a raw history record
         *
         * Throws InvalidRecordException if the data is the wrong length.
         *
         * @param[in] data - the raw record data as the PS returns it
         *
         * @return size_t - the ID from byte 0
         */
        size_t getRawRecordID(const std::vector<uint8_t>& data) const;

        /**
         * @brief Creates an instance of a Record from the raw PS data
         *
         * @param[in] data - the raw record data as the PS returns it
         *
         * @return Record - A filled in Record instance
         */
        Record createRecord(const std::vector<uint8_t>& data);

        /**
         * @brief The maximum number of entries to keep in the history.
         *
         * When a new record is added, the oldest one will be removed.
         */
        const size_t maxRecords;

        /**
         * @brief The last ID the power supply returns before rolling over
         *        back to the first ID of 0.
         */
        const size_t lastSequenceID;

        /**
         * @brief The list of timestamp/average/maximum records.
         *        Newer records are added to the front, and older ones
         *        removed from the back.
         */
        std::deque<Record> records;
};

}
}
}
