#pragma once

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

#include <cassert>
#include <cstring>
#include <memory>
#include <stdexcept>
#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
