#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 Returns the history of average input power
         *        in a representation used by D-Bus.
         *
         * @return DBusRecordList - A list of averages with
         *         a timestamp for each entry.
         */
        DBusRecordList getAverageRecords();

        /**
         * @brief Returns the history of maximum input power
         *        in a representation used by D-Bus.
         *
         * @return DBusRecordList - A list of maximums with
         *         a timestamp for each entry.
         */
        DBusRecordList getMaximumRecords();

        /**
         * @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;
};

}
}
}
