#pragma once

#include <arpa/inet.h>
#include <byteswap.h>

#include <cassert>
#include <cstring>
#include <memory>
#include <string>
#include <vector>

namespace openpower
{
namespace pels
{

namespace detail
{
/**
 * @brief A host-to-network implementation for uint64_t
 *
 * @param[in] value - the value to convert to
 * @return uint64_t - the byteswapped value
 */
inline uint64_t htonll(uint64_t value)
{
    return bswap_64(value);
}

/**
 * @brief A network-to-host implementation for uint64_t
 *
 * @param[in] value - the value to convert to
 * @return uint64_t - the byteswapped value
 */
inline uint64_t ntohll(uint64_t value)
{
    return bswap_64(value);
}
} // namespace detail

/**
 * @class Stream
 *
 * This class is used for getting data types into and out of a vector<uint8_t>
 * that contains data in network byte (big endian) ordering.
 */
class Stream
{
  public:
    Stream() = delete;
    ~Stream() = default;
    Stream(const Stream&) = default;
    Stream& operator=(const Stream&) = default;
    Stream(Stream&&) = default;
    Stream& operator=(Stream&&) = default;

    /**
     * @brief Constructor
     *
     * @param[in] data - the vector of data
     */
    explicit Stream(std::vector<uint8_t>& data) : _data(data), _offset(0)
    {
    }

    /**
     * @brief Constructor
     *
     * @param[in] data - the vector of data
     * @param[in] offset - the starting offset
     */
    Stream(std::vector<uint8_t>& data, std::size_t offset) :
        _data(data), _offset(offset)
    {
        if (_offset >= _data.size())
        {
            throw std::out_of_range("Offset out of range");
        }
    }

    /**
     * @brief Extraction operator for a uint8_t
     *
     * @param[out] value - filled in with the value
     * @return Stream&
     */
    Stream& operator>>(uint8_t& value)
    {
        read(&value, 1);
        return *this;
    }

    /**
     * @brief Extraction operator for a char
     *
     * @param[out] value -filled in with the value
     * @return Stream&
     */
    Stream& operator>>(char& value)
    {
        read(&value, 1);
        return *this;
    }

    /**
     * @brief Extraction operator for a uint16_t
     *
     * @param[out] value -filled in with the value
     * @return Stream&
     */
    Stream& operator>>(uint16_t& value)
    {
        read(&value, 2);
        value = htons(value);
        return *this;
    }

    /**
     * @brief Extraction operator for a uint32_t
     *
     * @param[out] value -filled in with the value
     * @return Stream&
     */
    Stream& operator>>(uint32_t& value)
    {
        read(&value, 4);
        value = htonl(value);
        return *this;
    }

    /**
     * @brief Extraction operator for a uint64_t
     *
     * @param[out] value -filled in with the value
     * @return Stream&
     */
    Stream& operator>>(uint64_t& value)
    {
        read(&value, 8);
        value = detail::htonll(value);
        return *this;
    }

    /**
     * @brief Insert operator for a uint8_t
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(uint8_t& value)
    {
        write(&value, 1);
        return *this;
    }

    /**
     * @brief Insert operator for a char
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(char& value)
    {
        write(&value, 1);
        return *this;
    }

    /**
     * @brief Insert operator for a uint16_t
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(uint16_t& value)
    {
        uint16_t data = ntohs(value);
        write(&data, 2);
        return *this;
    }

    /**
     * @brief Insert operator for a uint32_t
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(uint32_t& value)
    {
        uint32_t data = ntohl(value);
        write(&data, 4);
        return *this;
    }

    /**
     * @brief Insert operator for a uint64_t
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(uint64_t& value)
    {
        uint64_t data = detail::ntohll(value);
        write(&data, 8);
        return *this;
    }

    /**
     * @brief Sets the offset of the stream
     *
     * @param[in] newOffset - the new offset
     */
    void offset(std::size_t newOffset)
    {
        if (newOffset >= _data.size())
        {
            throw std::out_of_range("new offset out of range");
        }

        _offset = newOffset;
    }

    /**
     * @brief Returns the current offset of the stream
     *
     * @return size_t - the offset
     */
    std::size_t offset() const
    {
        return _offset;
    }

    /**
     * @brief Returns the remaining bytes left between the current offset
     *        and the data size.
     *
     * @return size_t - the remaining size
     */
    std::size_t remaining() const
    {
        assert(_data.size() >= _offset);
        return _data.size() - _offset;
    }

    /**
     * @brief Reads a specified number of bytes out of a stream
     *
     * @param[out] out - filled in with the data
     * @param[in] size - the size to read
     */
    void read(void* out, std::size_t size)
    {
        rangeCheck(size);
        memcpy(out, &_data[_offset], size);
        _offset += size;
    }

    /**
     * @brief Writes a specified number of bytes into the stream
     *
     * @param[in] in - the data to write
     * @param[in] size - the size to write
     */
    void write(void* in, std::size_t size)
    {
        size_t newSize = _offset + size;
        if (newSize > _data.size())
        {
            _data.resize(newSize, 0);
        }
        memcpy(&_data[_offset], in, size);
        _offset += size;
    }

  private:
    /**
     * @brief Throws an exception if the size passed in plus the current
     *        offset is bigger than the current data size.
     * @param[in] size - the size to check
     */
    void rangeCheck(std::size_t size)
    {
        if (_offset + size > _data.size())
        {
            std::string msg{"Attempted stream overflow: offset "};
            msg += std::to_string(_offset) + " buffer size " +
                   std::to_string(_data.size()) + " op size " +
                   std::to_string(size);
            throw std::out_of_range(msg.c_str());
        }
    }

    /**
     * @brief The data that the stream accesses.
     */
    std::vector<uint8_t>& _data;

    /**
     * @brief The current offset of the stream.
     */
    std::size_t _offset;
};

} // namespace pels
} // namespace openpower
