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

#ifndef NDN_NAME_H
#define NDN_NAME_H

#include "ndn-cpp/fields/name-component.h"
#include "ndn-cpp/common.h"

namespace ndn {

class Name;
typedef boost::shared_ptr<Name> NamePtr;
typedef boost::shared_ptr<const Name> ConstNamePtr;

/**
 * @brief Class for NDN Name
 */
class Name
{
public:
  typedef std::vector<name::Component>::iterator iterator;
  typedef std::vector<name::Component>::const_iterator const_iterator;
  typedef std::vector<name::Component>::reverse_iterator reverse_iterator;
  typedef std::vector<name::Component>::const_reverse_iterator const_reverse_iterator;
  typedef std::vector<name::Component>::reference reference;
  typedef std::vector<name::Component>::const_reference const_reference;

  typedef name::Component partial_type;
  
  ///////////////////////////////////////////////////////////////////////////////
  //                              CONSTRUCTORS                                 //
  ///////////////////////////////////////////////////////////////////////////////

  /**
   * @brief Default constructor to create an empty name (zero components, or "/")
   */
  Name ();

  /**
   * @brief Copy constructor
   *
   * @param other reference to a NDN name object
   */
  Name (const Name &other);

  /**
   * @brief Create a name from URL string
   *
   * @param url URI-represented name
   */
  Name (const std::string &url);

  /**
   * @brief Create a name from a container of elements [begin, end)
   *
   * @param begin begin iterator of the container
   * @param end end iterator of the container
   */
  template<class Iterator>
  Name (Iterator begin, Iterator end);

  /**
   * @brief Assignment operator
   */
  Name &
  operator= (const Name &other);


  ///////////////////////////////////////////////////////////////////////////////
  //                                SETTERS                                    //
  ///////////////////////////////////////////////////////////////////////////////

  /**
   * @brief Append a binary blob as a name component
   *
   * @param comp a binary blob
   * @returns reference to self (to allow chaining of append methods)
   */
  inline Name &
  append (const name::Component &comp);

  /**
   * @brief Append a binary blob as a name component
   * @param comp a binary blob
   *
   * This version is a little bit more efficient, since it swaps contents of comp and newly added component
   *
   * Attention!!! This method has an intended side effect: content of comp becomes empty
   */
  inline Name &
  appendBySwap (name::Component &comp);
  
  /**
   * @brief Append components a container of elements [begin, end)
   *
   * @param begin begin iterator of the container
   * @param end end iterator of the container
   * @returns reference to self (to allow chaining of append methods)
   */
  template<class Iterator>
  inline Name &
  append (Iterator begin, Iterator end);

  /**
   * @brief Append components from another ndn::Name object
   *
   * @param comp reference to Name object
   * @returns reference to self (to allow chaining of append methods)
   */
  inline Name &
  append (const Name &comp);

  /**
   * @brief Append a string as a name component
   *
   * @param compStr a string
   * @returns reference to self (to allow chaining of append methods)
   *
   * No conversions will be done to the string.  The string is included in raw form,
   * without any leading '\0' symbols.
   */
  inline Name &
  append (const std::string &compStr);

  /**
   * @brief Append a binary blob as a name component
   *
   * @param buf pointer to the first byte of the binary blob
   * @param size length of the binary blob
   * @returns reference to self (to allow chaining of append methods)
   */
  inline Name &
  append (const void *buf, size_t size);

  /**
   * @brief Append network-ordered numeric component to the name
   *
   * @param number number to be encoded and added as a component
   *
   * Number is encoded and added in network order. Tail zero-bytes are not included.
   * For example, if the number is 1, then 1-byte binary blob will be added  0x01.
   * If the number is 256, then 2 binary blob will be added: 0x01 0x01
   *
   * If the number is zero, an empty component will be added
   */
  inline Name &
  appendNumber (uint64_t number);

  /**
   * @brief Append network-ordered numeric component to the name with marker
   *
   * @param number number to be encoded and added as a component
   * @param marker byte marker, specified by the desired naming convention
   *
   * Currently defined naming conventions of the marker:
   * - 0x00  sequence number
   * - 0xC1  control number
   * - 0xFB  block id
   * - 0xFD  version number
   *
   * This version is almost exactly as appendNumber, with exception that it adds initial marker.
   * The number is formatted in the exactly the same way.
   *
   * @see appendNumber
   */
  inline Name &
  appendNumberWithMarker (uint64_t number, unsigned char marker);

  /**
   * @brief Helper method to add sequence number to the name (marker = 0x00)
   * @param seqno sequence number
   * @see appendNumberWithMarker
   */
  inline Name &
  appendSeqNum (uint64_t seqno);

  /**
   * @brief Helper method to add control number to the name (marker = 0xC1)
   * @param control control number
   * @see appendNumberWithMarker
   */
  inline Name &
  appendControlNum (uint64_t control);

  /**
   * @brief Helper method to add block ID to the name (marker = 0xFB)
   * @param blkid block ID
   * @see appendNumberWithMarker
   */
  inline Name &
  appendBlkId (uint64_t blkid);

  /**
   * @brief Helper method to add version to the name (marker = 0xFD)
   * @param version fully formatted version in a desired format (e.g., timestamp).
   *                If version is Name::nversion, then the version number is automatically
   *                assigned based on UTC timestamp
   * @see appendNumberWithMarker
   */
  Name &
  appendVersion (uint64_t version = Name::nversion);

  ///////////////////////////////////////////////////////////////////////////////
  //                                GETTERS                                    //
  ///////////////////////////////////////////////////////////////////////////////

  /**
   * @brief Get number of the name components
   * @return number of name components
   */
  inline size_t
  size () const;

  /**
   * @brief Get binary blob of name component
   * @param index index of the name component.  If less than 0, then getting component from the back:
   *              get(-1) getting the last component, get(-2) is getting second component from back, etc.
   * @returns const reference to binary blob of the requested name component
   *
   * If index is out of range, an exception will be thrown
   */
  const name::Component &
  get (int index) const;

  /**
   * @brief Get binary blob of name component
   * @param index index of the name component.  If less than 0, then getting component from the back
   * @returns reference to binary blob of the requested name component
   *
   * If index is out of range, an exception will be thrown
   */
  name::Component &
  get (int index);

  /////
  ///// Iterator interface to name components
  /////
  inline Name::const_iterator
  begin () const;           ///< @brief Begin iterator (const)

  inline Name::iterator
  begin ();                 ///< @brief Begin iterator

  inline Name::const_iterator
  end () const;             ///< @brief End iterator (const)

  inline Name::iterator
  end ();                   ///< @brief End iterator

  inline Name::const_reverse_iterator
  rbegin () const;          ///< @brief Reverse begin iterator (const)

  inline Name::reverse_iterator
  rbegin ();                ///< @brief Reverse begin iterator

  inline Name::const_reverse_iterator
  rend () const;            ///< @brief Reverse end iterator (const)

  inline Name::reverse_iterator
  rend ();                  ///< @brief Reverse end iterator


  /////
  ///// Static helpers to convert name component to appropriate value
  /////

  /**
   * @brief Get a new name, constructed as a subset of components
   * @param pos Position of the first component to be copied to the subname
   * @param len Number of components to be copied. Value Name::npos indicates that all components till the end of the name.
   */
  Name
  getSubName (size_t pos = 0, size_t len = npos) const;

  /**
   * @brief Get prefix of the name
   * @param len length of the prefix
   * @param skip number of components to skip from beginning of the name
   */
  inline Name
  getPrefix (size_t len, size_t skip = 0) const;

  /**
   * @brief Get postfix of the name
   * @param len length of the postfix
   * @param skip number of components to skip from end of the name
   */
  inline Name
  getPostfix (size_t len, size_t skip = 0) const;

  /**
   * @brief Get text representation of the name (URI)
   */
  std::string
  toUri () const;

  /**
   * @brief Write name as URI to the specified output stream
   * @param os output stream
   */
  void
  toUri (std::ostream &os) const;

  /////////////////////////////////////////////////
  // Helpers and compatibility wrappers
  /////////////////////////////////////////////////

  /**
   * @brief Compare two names, using canonical ordering for each component
   * @return 0  They compare equal
   *         <0 If *this comes before other in the canonical ordering
   *         >0 If *this comes after in the canonical ordering
   */
  int
  compare (const Name &name) const;

  /**
   * @brief Check if to Name objects are equal (have the same number of components with the same binary data)
   */
  inline bool
  operator == (const Name &name) const;

  /**
   * @brief Check if two Name objects are not equal
   */
  inline bool
  operator != (const Name &name) const;

  /**
   * @brief Less or equal comparison of two name objects
   */
  inline bool
  operator <= (const Name &name) const;

  /**
   * @brief Less comparison of two name objects
   */
  inline bool
  operator < (const Name &name) const;

  /**
   * @brief Great or equal comparison of two name objects
   */
  inline bool
  operator >= (const Name &name) const;

  /**
   * @brief Great comparison of two name objects
   */
  inline bool
  operator > (const Name &name) const;

  /**
   * @brief Operator [] to simplify access to name components
   * @see get
   */
  inline name::Component &
  operator [] (int index);

  /**
   * @brief Operator [] to simplify access to name components
   * @see get
   */
  inline const name::Component &
  operator [] (int index) const;

  /**
   * @brief Create a new Name object, by copying components from first and second name
   */
  Name
  operator + (const Name &name) const;

  /**
   * @brief A wrapper for append method
   */
  template<class T>
  inline void
  push_back (const T &comp);

public:
  // Data Members (public):
  ///  Value returned by various member functions when they fail.
  const static size_t npos = static_cast<size_t> (-1);
  const static uint64_t nversion = static_cast<uint64_t> (-1);

private:
  std::vector<name::Component> m_comps;
};

inline std::ostream &
operator << (std::ostream &os, const Name &name)
{
  name.toUri (os);
  return os;
}


/////////////////////////////////////////////////////////////////////////////////////
// Definition of inline methods
/////////////////////////////////////////////////////////////////////////////////////

template<class Iterator>
Name::Name (Iterator begin, Iterator end)
{
  append (begin, end);
}

inline Name &
Name::append (const name::Component &comp)
{
  if (comp.size () != 0)
    m_comps.push_back (comp);
  return *this;
}

inline Name &
Name::appendBySwap (name::Component &comp)
{
  if (comp.size () != 0)
    {
      Name::iterator newComp = m_comps.insert (end (), name::Component ());
      newComp->swap (comp);
    }
  return *this;
}

template<class Iterator>
inline Name &
Name::append (Iterator begin, Iterator end)
{
  for (Iterator i = begin; i != end; i++)
    {
      append (*i);
    }
  return *this;
}

Name &
Name::append (const Name &comp)
{
  if (this == &comp)
    {
      // have to double-copy if the object is self, otherwise results very frustrating (because we use vector...)
      return append (Name (comp.begin (), comp.end ()));
    }
  return append (comp.begin (), comp.end ());
}

Name &
Name::append (const std::string &compStr)
{
  name::Component comp (compStr);
  return appendBySwap (comp);
}

Name &
Name::append (const void *buf, size_t size)
{
  name::Component comp (buf, size);
  return appendBySwap (comp);
}

Name &
Name::appendNumber (uint64_t number)
{
  name::Component comp;
  name::Component::fromNumber (number).swap (comp);
  return appendBySwap (comp);
}

Name &
Name::appendNumberWithMarker (uint64_t number, unsigned char marker)
{
  name::Component comp;
  name::Component::fromNumberWithMarker (number, marker).swap (comp);
  return appendBySwap (comp);
}

inline Name &
Name::appendSeqNum (uint64_t seqno)
{
  return appendNumberWithMarker (seqno, 0x00);
}

inline Name &
Name::appendControlNum (uint64_t control)
{
  return appendNumberWithMarker (control, 0xC1);
}

inline Name &
Name::appendBlkId (uint64_t blkid)
{
  return appendNumberWithMarker (blkid, 0xFB);
}

inline size_t
Name::size () const
{
  return m_comps.size ();
}

/////
///// Iterator interface to name components
/////
inline Name::const_iterator
Name::begin () const
{
  return m_comps.begin ();
}

inline Name::iterator
Name::begin ()
{
  return m_comps.begin ();
}

inline Name::const_iterator
Name::end () const
{
  return m_comps.end ();
}

inline Name::iterator
Name::end ()
{
  return m_comps.end ();
}

inline Name::const_reverse_iterator
Name::rbegin () const
{
  return m_comps.rbegin ();
}

inline Name::reverse_iterator
Name::rbegin ()
{
  return m_comps.rbegin ();
}

inline Name::const_reverse_iterator
Name::rend () const
{
  return m_comps.rend ();
}


inline Name::reverse_iterator
Name::rend ()
{
  return m_comps.rend ();
}


//// helpers


inline Name
Name::getPrefix (size_t len, size_t skip/* = 0*/) const
{
  return getSubName (skip, len);
}

inline Name
Name::getPostfix (size_t len, size_t skip/* = 0*/) const
{
  return getSubName (size () - len - skip, len);
}


template<class T>
inline void
Name::push_back (const T &comp)
{
  append (comp);
}

inline bool
Name::operator ==(const Name &name) const
{
  return (compare (name) == 0);
}

inline bool
Name::operator !=(const Name &name) const
{
  return (compare (name) != 0);
}

inline bool
Name::operator <= (const Name &name) const
{
  return (compare (name) <= 0);
}

inline bool
Name::operator < (const Name &name) const
{
  return (compare (name) < 0);
}

inline bool
Name::operator >= (const Name &name) const
{
  return (compare (name) >= 0);
}

inline bool
Name::operator > (const Name &name) const
{
  return (compare (name) > 0);
}

inline name::Component &
Name::operator [] (int index)
{
  return get (index);
}

inline const name::Component &
Name::operator [] (int index) const
{
  return get (index);
}

} // ndn

#endif
