#pragma once

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

namespace phosphor
{
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 usable 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;
};

} // namespace history
} // namespace power
} // namespace phosphor
