/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2017 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.
 *
 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
 */

#ifndef NDN_ENCODING_BLOCK_HPP
#define NDN_ENCODING_BLOCK_HPP

#include "../common.hpp"

#include "buffer.hpp"
#include "tlv.hpp"
#include "encoding-buffer-fwd.hpp"

namespace boost {
namespace asio {
class const_buffer;
} // namespace asio
} // namespace boost

namespace ndn {

/** @brief Class representing a wire element of NDN-TLV packet format
 */
class Block
{
public:
  using element_container      = std::vector<Block>;
  using element_iterator       = element_container::iterator;
  using element_const_iterator = element_container::const_iterator;

  class Error : public tlv::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : tlv::Error(what)
    {
    }
  };

public: // constructor, creation, assignment
  /** @brief Create an empty Block
   */
  Block();

  /** @brief Parse Block from an EncodingBuffer
   *  @param buffer an EncodingBuffer containing one TLV element
   *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
   */
  explicit
  Block(const EncodingBuffer& buffer);

  /** @brief Parse Block from a wire Buffer
   *  @param buffer a Buffer containing one TLV element
   *  @note This constructor takes shared ownership of @p buffer.
   *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
   */
  explicit
  Block(const ConstBufferPtr& buffer);

  /** @brief Parse Block within boundaries of a wire Buffer
   *  @param buffer a Buffer containing an TLV element at [@p begin,@p end)
   *  @param begin begin position of the TLV element within @p buffer
   *  @param end end position of the TLV element within @p buffer
   *  @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
   *  @throw std::invalid_argument @p buffer is empty, or [@p begin,@p end) range are not within @p buffer
   *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
   *  @note This overload automatically detects TLV-TYPE and position of TLV-VALUE.
   */
  Block(ConstBufferPtr buffer, Buffer::const_iterator begin, Buffer::const_iterator end,
        bool verifyLength = true);

  /** @brief Parse Block within boundaries of an existing Block, reusing underlying wire Buffer
   *  @param block a Block whose buffer contains an TLV element at [@p begin,@p end)
   *  @param begin begin position of the TLV element within @p block
   *  @param end end position of the TLV element within @p block
   *  @param verifyLength if true, check TLV-LENGTH equals size of TLV-VALUE
   *  @throw std::invalid_argument [@p begin,@p end) range are not within @p block
   *  @throw tlv::Error Type-Length parsing fails, or TLV-LENGTH does not match size of TLV-VALUE
   */
  Block(const Block& block, Buffer::const_iterator begin, Buffer::const_iterator end,
        bool verifyLength = true);

  /** @brief Create a Block from a wire Buffer without parsing
   *  @param buffer a Buffer containing an TLV element at [@p begin,@p end)
   *  @param type TLV-TYPE
   *  @param begin begin position of the TLV element within @p buffer
   *  @param end end position of the TLV element within @p buffer
   *  @param valueBegin begin position of TLV-VALUE within @p buffer
   *  @param valueEnd end position of TLV-VALUE within @p buffer
   */
  Block(ConstBufferPtr buffer, uint32_t type,
        Buffer::const_iterator begin, Buffer::const_iterator end,
        Buffer::const_iterator valueBegin, Buffer::const_iterator valueEnd);

  /** @brief Parse Block from a raw buffer
   *  @param buf pointer to the first octet of an TLV element
   *  @param bufSize size of the raw buffer; may be more than size of the TLV element
   *  @throw tlv::Error Type-Length parsing fails, or size of TLV-VALUE exceeds @p bufSize
   *  @note This overload copies the TLV element into an internal wire buffer.
   */
  Block(const uint8_t* buf, size_t bufSize);

  /** @brief Parse Block from a raw buffer
   *  @deprecated use Block(const uint8_t*, size_t)
   */
  Block(const void* buf, size_t bufSize);

  /** @brief Create an empty Block with specified TLV-TYPE
   *  @param type TLV-TYPE
   */
  explicit
  Block(uint32_t type);

  /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
   *  @param type TLV-TYPE
   *  @param value a Buffer containing the TLV-VALUE
   */
  Block(uint32_t type, ConstBufferPtr value);

  /** @brief Create a Block with specified TLV-TYPE and TLV-VALUE
   *  @param type TLV-TYPE
   *  @param value a Block to be nested as TLV-VALUE
   */
  Block(uint32_t type, const Block& value);

  /** @brief Parse Block from an input stream
   */
  static Block
  fromStream(std::istream& is);

  /** @brief Try to parse Block from a wire buffer
   *  @param buffer a Buffer containing an TLV element at offset @p offset
   *  @param offset begin position of the TLV element within @p buffer
   *  @note This function does not throw exceptions upon decoding failure.
   *  @return true and the Block if parsing succeeds; otherwise false
   */
  static std::tuple<bool, Block>
  fromBuffer(ConstBufferPtr buffer, size_t offset);

  /** @brief Try to parse Block from a raw buffer
   *  @param buf pointer to the first octet of an TLV element
   *  @param bufSize size of the raw buffer; may be more than size of the TLV element
   *  @note This function does not throw exceptions upon decoding failure.
   *  @note This overload copies the TLV element into an internal wire buffer.
   *  @return true and the Block if parsing succeeds; otherwise false
   */
  static std::tuple<bool, Block>
  fromBuffer(const uint8_t* buf, size_t bufSize);

public: // wire format
  /** @brief Check if the Block is empty
   *
   *  A Block is "empty" only if it is default-constructed. A Block with zero-length TLV-VALUE is
   *  not considered empty.
   */
  bool
  empty() const
  {
    return m_type == std::numeric_limits<uint32_t>::max();
  }

  /** @brief Check if the Block has fully encoded wire
   *
   *  A Block has fully encoded wire if the underlying buffer exists and contains full
   *  Type-Length-Value instead of just TLV-VALUE field.
   */
  bool
  hasWire() const;

  /** @brief Reset wire buffer of the element
   *  @post empty() == true
   */
  void
  reset();

  /** @brief Reset wire buffer but keep TLV-TYPE and sub elements (if any)
   *  @post hasWire() == false
   *  @post hasValue() == false
   */
  void
  resetWire();

  /** @brief Get begin iterator of encoded wire
   *  @pre hasWire() == true
   */
  Buffer::const_iterator
  begin() const;

  /** @brief Get end iterator of encoded wire
   *  @pre hasWire() == true
   */
  Buffer::const_iterator
  end() const;

  /** @brief Get pointer to encoded wire
   *  @pre hasWire() == true
   */
  const uint8_t*
  wire() const;

  /** @brief Get size of encoded wire, including Type-Length-Value
   *  @pre empty() == false
   */
  size_t
  size() const;

  /** @brief Get underlying buffer
   */
  shared_ptr<const Buffer>
  getBuffer() const
  {
    return m_buffer;
  }

public: // type and value
  /** @brief Get TLV-TYPE
   */
  uint32_t
  type() const
  {
    return m_type;
  }

  /** @brief Get begin iterator of TLV-VALUE
   *
   *  This property reflects whether the underlying buffer contains TLV-VALUE. If this is false,
   *  TLV-VALUE has zero-length. If this is true, TLV-VALUE may be zero-length.
   */
  bool
  hasValue() const
  {
    return m_buffer != nullptr;
  }

  /** @brief Get begin iterator of TLV-VALUE
   *  @pre hasValue() == true
   */
  Buffer::const_iterator
  value_begin() const
  {
    return m_valueBegin;
  }

  /** @brief Get end iterator of TLV-VALUE
   *  @pre hasValue() == true
   */
  Buffer::const_iterator
  value_end() const
  {
    return m_valueEnd;
  }

  /** @brief Get pointer to TLV-VALUE
   */
  const uint8_t*
  value() const;

  /** @brief Get size of TLV-VALUE aka TLV-LENGTH
   */
  size_t
  value_size() const;

  Block
  blockFromValue() const;

public: // sub elements
  /** @brief Parse TLV-VALUE into sub elements
   *  @post elements() reflects sub elements found in TLV-VALUE
   *  @throw tlv::Error TLV-VALUE is not a sequence of TLV elements
   *  @note This method does not perform recursive parsing.
   *  @note This method has no effect if elements() is already populated.
   *  @note This method is not really const, but it does not modify any data.
   */
  void
  parse() const;

  /** @brief Encode sub elements into TLV-VALUE
   *  @post TLV-VALUE contains sub elements from elements()
   */
  void
  encode();

  /** @brief Get the first sub element of specified TLV-TYPE
   *  @pre parse() has been executed
   *  @throw Error sub element of @p type does not exist
   */
  const Block&
  get(uint32_t type) const;

  /** @brief Find the first sub element of specified TLV-TYPE
   *  @pre parse() has been executed
   *  @return iterator in elements() to the found sub element, otherwise elements_end()
   */
  element_const_iterator
  find(uint32_t type) const;

  /** @brief Remove all sub elements of specified TLV-TYPE
   *  @pre parse() has been executed
   *  @post find(type) == elements_end()
   */
  void
  remove(uint32_t type);

  /** @brief Erase a sub element
   */
  element_iterator
  erase(element_const_iterator position);

  /** @brief Erase a range of sub elements
   */
  element_iterator
  erase(element_const_iterator first, element_const_iterator last);

  /** @brief Append a sub element
   */
  void
  push_back(const Block& element);

  /** @brief Insert a sub element
   *  @param pos position of new sub element
   *  @param element new sub element
   *  @return iterator in elements() to the new sub element
   */
  element_iterator
  insert(element_const_iterator pos, const Block& element);

  /** @brief Get container of sub elements
   *  @pre parse() has been executed
   */
  const element_container&
  elements() const
  {
    return m_elements;
  }

  /** @brief Equivalent to elements().begin()
   */
  element_const_iterator
  elements_begin() const
  {
    return m_elements.begin();
  }

  /** @brief Equivalent to elements().end()
   */
  element_const_iterator
  elements_end() const
  {
    return m_elements.end();
  }

  /** @brief Equivalent to elements().size()
   */
  size_t
  elements_size() const
  {
    return m_elements.size();
  }

public: // misc
  /** @brief Implicit conversion to const_buffer
   */
  operator boost::asio::const_buffer() const;

protected:
  /** @brief underlying buffer storing TLV-VALUE and possibly TLV-TYPE and TLV-LENGTH fields
   *
   *  If m_buffer is nullptr, this is an empty Block with TLV-TYPE given in m_type.
   *  Otherwise,
   *  - [m_valueBegin, m_valueEnd) point to TLV-VALUE within m_buffer.
   *  - If m_begin != m_end, [m_begin,m_end) point to Type-Length-Value of this Block within m_buffer.
   *    Otherwise, m_buffer does not contain TLV-TYPE and TLV-LENGTH fields.
   */
  shared_ptr<const Buffer> m_buffer;
  Buffer::const_iterator m_begin; ///< @sa m_buffer
  Buffer::const_iterator m_end; ///< @sa m_buffer

  Buffer::const_iterator m_valueBegin; ///< @sa m_buffer
  Buffer::const_iterator m_valueEnd; ///< @sa m_buffer

  uint32_t m_type; ///< TLV-TYPE

  /** @brief total size including Type-Length-Value
   *
   *  This field is valid only if empty() is false.
   */
  uint32_t m_size;

  /** @brief sub elements
   *
   *  This field is valid only if parse() has been executed.
   */
  mutable element_container m_elements;
};

/** @brief Compare whether two Blocks have same TLV-TYPE, TLV-LENGTH, and TLV-VALUE
 */
bool
operator==(const Block& lhs, const Block& rhs);

inline bool
operator!=(const Block& lhs, const Block& rhs)
{
  return !(lhs == rhs);
}

} // namespace ndn

#endif // NDN_ENCODING_BLOCK_HPP
