#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 Extraction operator for a std::vector<uint8_t>
     *
     * The vector's size is the amount extracted.
     *
     * @param[out] value - filled in with the value
     * @return Stream&
     */
    Stream& operator>>(std::vector<uint8_t>& value)
    {
        if (!value.empty())
        {
            read(value.data(), value.size());
        }
        return *this;
    }

    /**
     * @brief Extraction operator for a std::vector<char>
     *
     * The vector's size is the amount extracted.
     *
     * @param[out] value - filled in with the value
     * @return Stream&
     */
    Stream& operator>>(std::vector<char>& value)
    {
        if (!value.empty())
        {
            read(value.data(), value.size());
        }
        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 Insert operator for a std::vector<uint8_t>
     *
     * The full vector is written to the stream.
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(const std::vector<uint8_t>& value)
    {
        if (!value.empty())
        {
            write(value.data(), value.size());
        }
        return *this;
    }

    /**
     * @brief Insert operator for a std::vector<char>
     *
     * The full vector is written to the stream.
     *
     * @param[in] value - the value to write to the stream
     * @return Stream&
     */
    Stream& operator<<(const std::vector<char>& value)
    {
        if (!value.empty())
        {
            write(value.data(), value.size());
        }
        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(const 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
