#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
     */
    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
