/* -*- 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 "ns3/ndn-common.h"
#include "ns3/simple-ref-count.h"
#include "ns3/attribute.h"
#include "ns3/attribute-helper.h"

#include "name-component.h"

NDN_NAMESPACE_BEGIN

/**
 * @brief Class for NDN Name
 */
class Name : public SimpleRefCount<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;
}

inline std::istream &
operator >> (std::istream &is, Name &name)
{
  std::string line;
  is >> line;
  name = Name (line);

  return is;
}

/////////////////////////////////////////////////////////////////////////////////////
// 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;
  return appendBySwap (comp.fromNumber (number));
}

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

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);
}

ATTRIBUTE_HELPER_HEADER (Name);

NDN_NAMESPACE_END

#endif
