/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Alexander Afanasyev <alexander.afanasyev@ucla.edu>
 */

#ifndef NDN_BLOCK_HPP
#define NDN_BLOCK_HPP

#include "../common.hpp"

#include "buffer.hpp"
#include "tlv.hpp"

namespace ndn {

template<bool> class EncodingImpl;
typedef EncodingImpl<true> EncodingBuffer;

/**
 * @brief Class representing wire element of the NDN packet
 */
class Block
{
public:
  typedef std::vector<Block>                 element_container;
  typedef element_container::iterator        element_iterator;
  typedef element_container::const_iterator  element_const_iterator;

  /// @brief Error that can be thrown from the block
  class Error : public Tlv::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : Tlv::Error(what)
    {
    }
  };

  /**
   * @brief Default constructor to create an empty Block
   */
  Block();

  /**
   * @brief Create block based on EncodingBuffer object
   */
  explicit
  Block(const EncodingBuffer& buffer);

  /**
   * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
   *
   * This constructor provides ability of implicit conversion from ConstBufferPtr to Block
   */
  Block(const ConstBufferPtr& buffer);

  /**
   * @brief Another helper to create block from a buffer, directly specifying boundaries
   *        of the block within the buffer
   *
   * This version will automatically detect type and position of the value within the block
   */
  Block(const ConstBufferPtr& buffer,
        const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
        bool verifyLength = true);

  /**
   * @brief A helper version of a constructor to create Block from the raw buffer (type and value-length parsing)
   */
  Block(const uint8_t* buffer, size_t maxlength);

  Block(const void* buffer, size_t maxlength);

  /*
   * @brief A helper version of a constructor to create Block from the stream.
   */
  explicit
  Block(std::istream& is);

  /**
   * @brief Create Block from the wire buffer (no parsing)
   *
   * This version of the constructor does not do any parsing
   */
  Block(const ConstBufferPtr& wire,
        uint32_t type,
        const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
        const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);

  /**
   * @brief Create Block of a specific type with empty wire buffer
   */
  explicit
  Block(uint32_t type);

  /**
   * @brief Create Block of a specific type with the specified value
   *
   * The underlying buffer hold only value, additional operations are needed
   * to construct wire encoding, one need to prepend the wire buffer with type
   * and value-length VAR-NUMBERs
   */
  Block(uint32_t type, const ConstBufferPtr& value);

  /**
   * @brief Create nested Block of a specific type with the specified value
   *
   * The underlying buffer hold only value, additional operations are needed
   * to construct wire encoding, one need to prepend the wire buffer with type
   * and value-length VAR-NUMBERs
   */
  explicit
  Block(uint32_t type, const Block& value);

  /**
   * @brief Try to construct block from Buffer, referencing data block pointed by wire
   *
   * @throws This method never throws an exception
   *
   * @returns true if Block successfully created, false if block cannot be created
   */
  static bool
  fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);

  /**
   * @brief Try to construct block from Buffer, referencing data block pointed by wire
   *
   * @throws This method never throws an exception
   *
   * @returns true if Block successfully created, false if block cannot be created
   */
  static bool
  fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);

  /**
   * @brief Check if the Block is empty
   */
  bool
  empty() const;

  /**
   * @brief Check if the Block has fully encoded wire
   */
  bool
  hasWire() const;

  /**
   * @brief Check if the Block has value block (no type and length are encoded)
   */
  bool
  hasValue() const;

  /**
   * @brief Reset wire buffer of the element
   */
  void
  reset();

  /**
   * @brief Reset wire buffer but keep sub elements (if any)
   */
  void
  resetWire();

  /**
   * @brief Parse wire buffer into subblocks
   *
   * This method is not really const, but it does not modify any data.  It simply
   * parses contents of the buffer into subblocks
   */
  void
  parse() const;

  /**
   * @brief Encode subblocks into wire buffer
   */
  void
  encode();

  uint32_t
  type() const;

  /**
   * @brief Get the first subelement of the requested type
   */
  const Block&
  get(uint32_t type) const;

  element_const_iterator
  find(uint32_t type) const;

  void
  remove(uint32_t type);

  element_iterator
  erase(element_iterator position);

  element_iterator
  erase(element_iterator first, element_iterator last);

  void
  push_back(const Block& element);

  Buffer::const_iterator
  begin() const;

  Buffer::const_iterator
  end() const;

  const uint8_t*
  wire() const;

  size_t
  size() const;

  Buffer::const_iterator
  value_begin() const;

  Buffer::const_iterator
  value_end() const;

  const uint8_t*
  value() const;

  size_t
  value_size() const;

  /**
   * @brief Get all subelements
   */
  const element_container&
  elements() const;

  element_const_iterator
  elements_begin() const;

  element_const_iterator
  elements_end() const;

  size_t
  elements_size() const;

  Block
  blockFromValue() const;

public: // EqualityComparable concept
  bool
  operator==(const Block& other) const;

  bool
  operator!=(const Block& other) const;

protected:
  ConstBufferPtr m_buffer;

  uint32_t m_type;

  Buffer::const_iterator m_begin;
  Buffer::const_iterator m_end;
  uint32_t m_size;

  Buffer::const_iterator m_value_begin;
  Buffer::const_iterator m_value_end;

  mutable element_container m_subBlocks;
  friend class EncodingImpl<true>;
};

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

inline bool
Block::empty() const
{
  return m_type == std::numeric_limits<uint32_t>::max();
}


inline bool
Block::hasWire() const
{
  return m_buffer && (m_begin != m_end);
}

inline bool
Block::hasValue() const
{
  return static_cast<bool>(m_buffer);
}

inline void
Block::reset()
{
  m_buffer.reset(); // reset of the shared_ptr
  m_subBlocks.clear(); // remove all parsed subelements

  m_type = std::numeric_limits<uint32_t>::max();
  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
}

inline void
Block::resetWire()
{
  m_buffer.reset(); // reset of the shared_ptr
  // keep subblocks

  // keep type
  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
}

inline uint32_t
Block::type() const
{
  return m_type;
}

inline const Block&
Block::get(uint32_t type) const
{
  for (element_const_iterator i = m_subBlocks.begin();
       i != m_subBlocks.end();
       i++)
    {
      if (i->type() == type)
        {
          return *i;
        }
    }

  throw Error("(Block::get) Requested a non-existed type [" +
              boost::lexical_cast<std::string>(type) + "] from Block");
}

inline Block::element_const_iterator
Block::find(uint32_t type) const
{
  for (element_const_iterator i = m_subBlocks.begin();
       i != m_subBlocks.end();
       i++)
    {
      if (i->type() == type)
        {
          return i;
        }
    }
  return m_subBlocks.end();
}

inline void
Block::remove(uint32_t type)
{
  resetWire();

  element_container newContainer;
  newContainer.reserve(m_subBlocks.size());
  for (element_iterator i = m_subBlocks.begin();
       i != m_subBlocks.end();
       ++i)
  {
      if (i->type() != type)
        newContainer.push_back(*i);
  }
  m_subBlocks.swap(newContainer);
}

inline Block::element_iterator
Block::erase(Block::element_iterator position)
{
  resetWire();
  return m_subBlocks.erase(position);
}

inline Block::element_iterator
Block::erase(Block::element_iterator first, Block::element_iterator last)
{
  resetWire();
  return m_subBlocks.erase(first, last);
}


inline void
Block::push_back(const Block& element)
{
  resetWire();
  m_subBlocks.push_back(element);
}

inline Buffer::const_iterator
Block::begin() const
{
  if (!hasWire())
      throw Error("Underlying wire buffer is empty");

  return m_begin;
}

inline Buffer::const_iterator
Block::end() const
{
  if (!hasWire())
      throw Error("Underlying wire buffer is empty");

  return m_end;
}

inline size_t
Block::size() const
{
  if (hasWire() || hasValue()) {
    return m_size;
  }
  else
    throw Error("Block size cannot be determined (undefined block size)");
}

inline Buffer::const_iterator
Block::value_begin() const
{
  return m_value_begin;
}

inline Buffer::const_iterator
Block::value_end() const
{
  return m_value_end;
}

inline const uint8_t*
Block::wire() const
{
  if (!hasWire())
      throw Error("(Block::wire) Underlying wire buffer is empty");

  return &*m_begin;
}

inline const uint8_t*
Block::value() const
{
  if (!hasValue())
    return 0;

  return &*m_value_begin;
}

inline size_t
Block::value_size() const
{
  if (!hasValue())
    return 0;

  return m_value_end - m_value_begin;
}

inline const Block::element_container&
Block::elements() const
{
  return m_subBlocks;
}

inline Block::element_const_iterator
Block::elements_begin() const
{
  return m_subBlocks.begin();
}

inline Block::element_const_iterator
Block::elements_end() const
{
  return m_subBlocks.end();
}

inline size_t
Block::elements_size() const
{
  return m_subBlocks.size();
}

inline bool
Block::operator==(const Block& other) const
{
  return (this->size() == other.size()) &&
         std::equal(this->begin(), this->end(), other.begin());
}

inline bool
Block::operator!=(const Block& other) const
{
  return !this->operator==(other);
}

} // ndn

#include "block-helpers.hpp"

#endif // NDN_BLOCK_HPP
