/* -*- 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 totalFromBack 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
