/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 *
 * @author Wentao Shang <http://irl.cs.ucla.edu/~wentao/>
 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
 */

#ifndef NDN_ENCODING_ENCODING_BUFFER_HPP
#define NDN_ENCODING_ENCODING_BUFFER_HPP

#include "../common.hpp"

#include "buffer.hpp"
#include "block.hpp"

namespace ndn {

namespace encoding {
static const bool Buffer = true;
static const bool Estimator = false;
} // encoding

template<bool isRealEncoderNotEstimator>
class EncodingImpl;

typedef EncodingImpl<encoding::Buffer> EncodingBuffer;
typedef EncodingImpl<encoding::Estimator> EncodingEstimator;

/**
 * @brief Class representing wire element of the NDN packet
 */
template<>
class EncodingImpl<encoding::Buffer>
{
public:
  /**
   * @brief Constructor to create a EncodingImpl with specified reserved sizes
   *
   * The caller should make sure that that reserveFromBack does not exceed totalReserve,
   * otherwise behavior is undefined.
   */
  EncodingImpl(size_t totalReserve = 8800,
               size_t reserveFromBack = 400)
    : m_buffer(new Buffer(totalReserve))
  {
    m_begin = m_end = m_buffer->end() - (reserveFromBack < totalReserve ? reserveFromBack : 0);
  }

  /**
   * @brief Create EncodingBlock from existing block
   *
   * This is a dangerous constructor and should be used with caution.
   * It will modify contents of the buffer that is used by block and may
   * impact data in other blocks.
   *
   * The primary purpose for this method is to be used to extend Block
   * after sign operation.
   */
  explicit
  EncodingImpl(const Block& block)
    : m_buffer(const_pointer_cast<Buffer>(block.m_buffer))
    , m_begin(m_buffer->begin() + (block.begin() - m_buffer->begin()))
    , m_end(m_buffer->begin()   + (block.end()   - m_buffer->begin()))
  {
  }

  inline size_t
  size() const;

  inline size_t
  capacity() const;

  inline uint8_t*
  buf();

  inline const uint8_t*
  buf() const;

  /**
   * @brief Create Block from the underlying EncodingBuffer
   *
   * @param verifyLength If this parameter set to true, Block's constructor
   *                     will be requested to verify consistency of the encoded
   *                     length in the Block, otherwise ignored
   */
  inline Block
  block(bool verifyLength = true) const;

  inline void
  resize(size_t size, bool addInFront);

  inline Buffer::iterator
  begin();

  inline Buffer::iterator
  end();

  inline Buffer::const_iterator
  begin() const;

  inline Buffer::const_iterator
  end() const;

  inline size_t
  prependByte(uint8_t value);

  inline size_t
  prependByteArray(const uint8_t* array, size_t length);

  inline size_t
  prependNonNegativeInteger(uint64_t varNumber);

  inline size_t
  prependVarNumber(uint64_t varNumber);

  inline size_t
  appendByte(uint8_t value);

  inline size_t
  appendByteArray(const uint8_t* array, size_t length);

  inline size_t
  appendNonNegativeInteger(uint64_t varNumber);

  inline size_t
  appendVarNumber(uint64_t varNumber);

  // inline void
  // removeByteFromFront();

  // inline void
  // removeByteFromEnd();

  // inline void
  // removeVarNumberFromFront(uint64_t varNumber);

  // inline void
  // removeVarNumberFromBack(uint64_t varNumber);

private:
  BufferPtr m_buffer;

  // invariant: m_begin always points to the position of last-written byte (if prepending data)
  Buffer::iterator m_begin;
  // invariant: m_end always points to the position of next unwritten byte (if appending data)
  Buffer::iterator m_end;

  friend class Block;
};


/**
 * @brief Class representing wire element of the NDN packet
 */
template<>
class EncodingImpl<encoding::Estimator>
{
public:
  EncodingImpl(size_t totalReserve = 8800,
               size_t reserveFromBack = 400)
  {
  }

  inline size_t
  prependByte(uint8_t value);

  inline size_t
  prependByteArray(const uint8_t* array, size_t length);

  inline size_t
  prependNonNegativeInteger(uint64_t varNumber);

  inline size_t
  prependVarNumber(uint64_t varNumber);

  inline size_t
  appendByte(uint8_t value);

  inline size_t
  appendByteArray(const uint8_t* array, size_t length);

  inline size_t
  appendNonNegativeInteger(uint64_t varNumber);

  inline size_t
  appendVarNumber(uint64_t varNumber);
};


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

inline size_t
EncodingImpl<encoding::Buffer>::size() const
{
  return m_end - m_begin;
}

inline size_t
EncodingImpl<encoding::Buffer>::capacity() const
{
  return m_buffer->size();
}

inline uint8_t*
EncodingImpl<encoding::Buffer>::buf()
{
  return &(*m_begin);
}

inline const uint8_t*
EncodingImpl<encoding::Buffer>::buf() const
{
  return &(*m_begin);
}

inline Block
EncodingImpl<encoding::Buffer>::block(bool verifyLength/* = true*/) const
{
  return Block(m_buffer,
               m_begin, m_end,
               verifyLength);
}

inline void
EncodingImpl<encoding::Buffer>::resize(size_t size, bool addInFront)
{
  if (addInFront)
    {
      size_t diff_end = m_buffer->end() - m_end;
      size_t diff_begin = m_buffer->end() - m_begin;

      Buffer* buf = new Buffer(size);
      std::copy_backward(m_buffer->begin(), m_buffer->end(), buf->end());

      m_buffer.reset(buf);

      m_end = m_buffer->end() - diff_end;
      m_begin = m_buffer->end() - diff_begin;
    }
  else
    {
      size_t diff_end = m_end - m_buffer->begin();
      size_t diff_begin = m_begin - m_buffer->begin();

      Buffer* buf = new Buffer(size);
      std::copy(m_buffer->begin(), m_buffer->end(), buf->begin());

      m_buffer.reset(buf);

      m_end = m_buffer->begin() + diff_end;
      m_begin = m_buffer->begin() + diff_begin;
    }
}

inline Buffer::iterator
EncodingImpl<encoding::Buffer>::begin()
{
  return m_begin;
}

inline Buffer::iterator
EncodingImpl<encoding::Buffer>::end()
{
  return m_end;
}

inline Buffer::const_iterator
EncodingImpl<encoding::Buffer>::begin() const
{
  return m_begin;
}

inline Buffer::const_iterator
EncodingImpl<encoding::Buffer>::end() const
{
  return m_end;
}


//////////////////////////////////////////////////////////
// Prepend to the back of the buffer. Resize if needed. //
//////////////////////////////////////////////////////////

inline size_t
EncodingImpl<encoding::Buffer>::prependByte(uint8_t value)
{
  if (m_begin == m_buffer->begin())
    resize(m_buffer->size() * 2, true);

  m_begin--;
  *m_begin = value;
  return 1;
}

inline size_t
EncodingImpl<encoding::Estimator>::prependByte(uint8_t value)
{
  return 1;
}

inline size_t
EncodingImpl<encoding::Buffer>::prependByteArray(const uint8_t* array, size_t length)
{
  if ((m_buffer->begin() + length) > m_begin)
    resize(m_buffer->size() * 2 + length, true);

  m_begin -= length;
  std::copy(array, array + length, m_begin);
  return length;
}

inline size_t
EncodingImpl<encoding::Estimator>::prependByteArray(const uint8_t* array, size_t length)
{
  return length;
}

inline size_t
EncodingImpl<encoding::Buffer>::prependNonNegativeInteger(uint64_t varNumber)
{
  if (varNumber <= std::numeric_limits<uint8_t>::max()) {
    return prependByte(static_cast<uint8_t>(varNumber));
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
  }
  else {
    uint64_t value = htobe64(varNumber);
    return prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
  }
}

inline size_t
EncodingImpl<encoding::Estimator>::prependNonNegativeInteger(uint64_t varNumber)
{
  if (varNumber <= std::numeric_limits<uint8_t>::max()) {
    return 1;
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    return 2;
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    return 4;
  }
  else {
    return 8;
  }
}

inline size_t
EncodingImpl<encoding::Buffer>::prependVarNumber(uint64_t varNumber)
{
  if (varNumber < 253) {
    prependByte(static_cast<uint8_t>(varNumber));
    return 1;
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
    prependByte(253);
    return 3;
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
    prependByte(254);
    return 5;
  }
  else {
    uint64_t value = htobe64(varNumber);
    prependByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
    prependByte(255);
    return 9;
  }
}

inline size_t
EncodingImpl<encoding::Estimator>::prependVarNumber(uint64_t varNumber)
{
  if (varNumber < 253) {
    return 1;
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    return 3;
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    return 5;
  }
  else {
    return 9;
  }
}

/////////////////////////////////////////////////////////
// Append to the back of the buffer. Resize if needed. //
/////////////////////////////////////////////////////////

inline size_t
EncodingImpl<encoding::Buffer>::appendByte(uint8_t value)
{
  if (m_end == m_buffer->end())
    resize(m_buffer->size() * 2, false);

  *m_end = value;
  m_end++;
  return 1;
}

inline size_t
EncodingImpl<encoding::Estimator>::appendByte(uint8_t value)
{
  return 1;
}

inline size_t
EncodingImpl<encoding::Buffer>::appendByteArray(const uint8_t* array, size_t length)
{
  if ((m_end + length) > m_buffer->end())
    resize(m_buffer->size() * 2 + length, false);

  std::copy(array, array + length, m_end);
  m_end += length;
  return length;
}

inline size_t
EncodingImpl<encoding::Estimator>::appendByteArray(const uint8_t* array, size_t length)
{
  return prependByteArray(array, length);
}

inline size_t
EncodingImpl<encoding::Buffer>::appendNonNegativeInteger(uint64_t varNumber)
{
  if (varNumber <= std::numeric_limits<uint8_t>::max()) {
    return appendByte(static_cast<uint8_t>(varNumber));
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
  }
  else {
    uint64_t value = htobe64(varNumber);
    return appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
  }
}

inline size_t
EncodingImpl<encoding::Estimator>::appendNonNegativeInteger(uint64_t varNumber)
{
  return prependNonNegativeInteger(varNumber);
}

inline size_t
EncodingImpl<encoding::Buffer>::appendVarNumber(uint64_t varNumber)
{
  if (varNumber < 253) {
    appendByte(static_cast<uint8_t>(varNumber));
    return 1;
  }
  else if (varNumber <= std::numeric_limits<uint16_t>::max()) {
    appendByte(253);
    uint16_t value = htobe16(static_cast<uint16_t>(varNumber));
    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 2);
    return 3;
  }
  else if (varNumber <= std::numeric_limits<uint32_t>::max()) {
    appendByte(254);
    uint32_t value = htobe32(static_cast<uint32_t>(varNumber));
    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 4);
    return 5;
  }
  else {
    appendByte(255);
    uint64_t value = htobe64(varNumber);
    appendByteArray(reinterpret_cast<const uint8_t*>(&value), 8);
    return 9;
  }
}

inline size_t
EncodingImpl<encoding::Estimator>::appendVarNumber(uint64_t varNumber)
{
  return prependVarNumber(varNumber);
}

/// helper methods

template<bool P>
inline size_t
prependNonNegativeIntegerBlock(EncodingImpl<P>& encoder, uint32_t type, uint64_t number)
{
  size_t valueLength = encoder.prependNonNegativeInteger(number);
  size_t totalLength = valueLength;
  totalLength += encoder.prependVarNumber(valueLength);
  totalLength += encoder.prependVarNumber(type);

  return totalLength;
}

template<bool P>
inline size_t
prependByteArrayBlock(EncodingImpl<P>& encoder, uint32_t type,
                      const uint8_t* array, size_t arraySize)
{
  size_t valueLength = encoder.prependByteArray(array, arraySize);
  size_t totalLength = valueLength;
  totalLength += encoder.prependVarNumber(valueLength);
  totalLength += encoder.prependVarNumber(type);

  return totalLength;
}

template<bool P>
inline size_t
prependBooleanBlock(EncodingImpl<P>& encoder, uint32_t type)
{
  size_t totalLength = encoder.prependVarNumber(0);
  totalLength += encoder.prependVarNumber(type);

  return totalLength;
}


template<bool P, class U>
inline size_t
prependNestedBlock(EncodingImpl<P>& encoder, uint32_t type, const U& nestedBlock)
{
  size_t valueLength = nestedBlock.wireEncode(encoder);
  size_t totalLength = valueLength;
  totalLength += encoder.prependVarNumber(valueLength);
  totalLength += encoder.prependVarNumber(type);

  return totalLength;
}

template<bool P>
inline size_t
prependBlock(EncodingImpl<P>& encoder, const Block& block)
{
  return encoder.prependByteArray(block.wire(), block.size());
}


} // ndn

#endif // NDN_ENCODING_ENCODING_BUFFER_HPP
