/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2015 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#ifndef NDN_ENCODING_ENCODER_HPP
#define NDN_ENCODING_ENCODER_HPP

#include "../common.hpp"
#include "block.hpp"

namespace ndn {
namespace encoding {

/**
 * @brief Helper class to perform TLV encoding
 * Interface of this class (mostly) matches interface of Estimator class
 * @sa Estimator
 */
class Encoder
{
public: // common interface between Encoder and Estimator
  /**
   * @brief Create instance of the encoder with the specified reserved sizes
   * @param totalReserve    initial buffer size to reserve
   * @param reserveFromBack number of bytes to reserve for append* operations
   */
  explicit
  Encoder(size_t totalReserve = 8800, size_t reserveFromBack = 400);

  Encoder(const Encoder&) = delete;

  Encoder&
  operator=(const Encoder&) = delete;

  /**
   * @brief Prepend a byte
   */
  size_t
  prependByte(uint8_t value);

  /**
   * @brief Append a byte
   */
  size_t
  appendByte(uint8_t value);

  /**
   * @brief Prepend a byte array @p array of length @p length
   */
  size_t
  prependByteArray(const uint8_t* array, size_t length);

  /**
   * @brief Append a byte array @p array of length @p length
   */
  size_t
  appendByteArray(const uint8_t* array, size_t length);

  /**
   * @brief Prepend range of bytes from the range [@p first, @p last)
   */
  template<class Iterator>
  size_t
  prependRange(Iterator first, Iterator last);

  /**
   * @brief Append range of bytes from the range [@p first, @p last)
   */
  template<class Iterator>
  size_t
  appendRange(Iterator first, Iterator last);

  /**
   * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
   * @sa http://named-data.net/doc/ndn-tlv/
   */
  size_t
  prependVarNumber(uint64_t varNumber);

  /**
   * @brief Prepend VarNumber @p varNumber of NDN TLV encoding
   * @sa http://named-data.net/doc/ndn-tlv/
   */
  size_t
  appendVarNumber(uint64_t varNumber);

  /**
   * @brief Prepend non-negative integer @p integer of NDN TLV encoding
   * @sa http://named-data.net/doc/ndn-tlv/
   */
  size_t
  prependNonNegativeInteger(uint64_t integer);

  /**
   * @brief Append non-negative integer @p integer of NDN TLV encoding
   * @sa http://named-data.net/doc/ndn-tlv/
   */
  size_t
  appendNonNegativeInteger(uint64_t integer);

  /**
   * @brief Prepend TLV block of type @p type and value from buffer @p array of size @p arraySize
   */
  size_t
  prependByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);

  /**
   * @brief Append TLV block of type @p type and value from buffer @p array of size @p arraySize
   */
  size_t
  appendByteArrayBlock(uint32_t type, const uint8_t* array, size_t arraySize);

  /**
   * @brief Prepend TLV block @p block
   */
  size_t
  prependBlock(const Block& block);

  /**
   * @brief Append TLV block @p block
   */
  size_t
  appendBlock(const Block& block);

public: // unique interface to the Encoder
  typedef Buffer::value_type value_type;
  typedef Buffer::iterator iterator;
  typedef Buffer::const_iterator const_iterator;

  /**
   * @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
  Encoder(const Block& block);

  /**
   * @brief Reserve @p size bytes for the underlying buffer
   * @param addInFront if true, then @p size bytes will be available in front (i.e., subsequent call
   *        to prepend* will not need to allocate memory).  If false, then reservation will be done
   *        at the end of the buffer (i.d., for subsequent append* calls)
   * @note Reserve size is exact, unlike reserveFront and reserveBack methods
   * @sa reserveFront, reserveBack
   */
  void
  reserve(size_t size, bool addInFront);

  /**
   * @brief Reserve at least @p size bytes at the back of the underlying buffer
   * @note the actual reserve size can be (and in most cases is) larger than specified reservation
   *       length
   */
  void
  reserveBack(size_t size);

  /**
   * @brief Reserve at least @p isze bytes at the beginning of the underlying buffer
   * @note the actual reserve size can be (and in most cases is) larger than specified reservation
   *       length
   */
  void
  reserveFront(size_t size);

  /**
   * @brief Get size of the underlying buffer
   */
  size_t
  capacity() const;

  /**
   * @brief Get underlying buffer
   */
  shared_ptr<Buffer>
  getBuffer();

public: // accessors

  /**
   * @brief Get an iterator pointing to the first byte of the encoded buffer
   */
  iterator
  begin();

  /**
   * @brief Get an iterator pointing to the past-the-end byte of the encoded buffer
   */
  iterator
  end();

  /**
   * @brief Get an iterator pointing to the first byte of the encoded buffer
   */
  const_iterator
  begin() const;

  const_iterator
  end() const;

  /**
   * @brief Get a pointer to the first byte of the encoded buffer
   */
  uint8_t*
  buf();

  /**
   * @brief Get a pointer to the first byte of the encoded buffer
   */
  const uint8_t*
  buf() const;

  /**
   * @brief Get size of the encoded buffer
   */
  size_t
  size() const;

  /**
   * @brief Create Block from the underlying buffer
   *
   * @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
   */
  Block
  block(bool verifyLength = true) const;

private:
  shared_ptr<Buffer> m_buffer;

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


inline size_t
Encoder::size() const
{
  return m_end - m_begin;
}

inline shared_ptr<Buffer>
Encoder::getBuffer()
{
  return m_buffer;
}

inline size_t
Encoder::capacity() const
{
  return m_buffer->size();
}

inline Buffer::iterator
Encoder::begin()
{
  return m_begin;
}

inline Buffer::iterator
Encoder::end()
{
  return m_end;
}

inline Buffer::const_iterator
Encoder::begin() const
{
  return m_begin;
}

inline Buffer::const_iterator
Encoder::end() const
{
  return m_end;
}

inline uint8_t*
Encoder::buf()
{
  return &(*m_begin);
}

inline const uint8_t*
Encoder::buf() const
{
  return &(*m_begin);
}

template<class Iterator>
inline size_t
Encoder::prependRange(Iterator first, Iterator last)
{
  size_t length = std::distance(first, last);
  reserveFront(length);

  m_begin -= length;
  std::copy(first, last, m_begin);
  return length;
}


template<class Iterator>
inline size_t
Encoder::appendRange(Iterator first, Iterator last)
{
  size_t length = std::distance(first, last);
  reserveBack(length);

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


} // namespace encoding
} // namespace ndn

#endif // NDN_ENCODING_ENCODER_HPP
