#pragma once

#include <cstdint>
#include <deque>
#include <stdexcept>
#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
     */
    explicit 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
