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

#ifndef NDN_EXCLUDE_H
#define NDN_EXCLUDE_H

#include "name.hpp"

#include <map>

namespace ndn {

namespace error {
struct Exclude : public std::runtime_error { Exclude(const std::string &what) : std::runtime_error(what) {} };
}

/**
 * @brief Class to represent Exclude component in NDN interests
 */
class Exclude
{
public:
  typedef std::map< Name::Component, bool /*any*/, std::greater<Name::Component> > exclude_type;

  typedef exclude_type::iterator iterator;
  typedef exclude_type::const_iterator const_iterator;
  typedef exclude_type::reverse_iterator reverse_iterator;
  typedef exclude_type::const_reverse_iterator const_reverse_iterator;

  /**
   * @brief Default constructor an empty exclude
   */
  Exclude ();

  /**
   * @brief Check if name component is excluded
   * @param comp Name component to check against exclude filter
   */
  bool
  isExcluded (const Name::Component &comp) const;

  /**
   * @brief Exclude specific name component
   * @param comp component to exclude
   * @returns *this to allow chaining
   */
  Exclude &
  excludeOne (const Name::Component &comp);

  /**
   * @brief Exclude components from range [from, to]
   * @param from first element of the range
   * @param to last element of the range
   * @returns *this to allow chaining
   */
  Exclude &
  excludeRange (const Name::Component &from, const Name::Component &to);

  /**
   * @brief Exclude all components from range [/, to]
   * @param to last element of the range
   * @returns *this to allow chaining
   */
  inline Exclude &
  excludeBefore (const Name::Component &to);

  /**
   * @brief Exclude all components from range [from, +Inf]
   * @param to last element of the range
   * @returns *this to allow chaining
   */
  Exclude &
  excludeAfter (const Name::Component &from);

  /**
   * @brief Method to directly append exclude element
   * @param name excluded name component
   * @param any  flag indicating if there is a postfix ANY component after the name
   *
   * This method is used during conversion from wire format of exclude filter
   *
   * If there is an error with ranges (e.g., order of components is wrong) an exception is thrown
   */
  void
  appendExclude (const Name::Component &name, bool any);

  /**
   * @brief Check if exclude filter is empty
   */
  inline bool
  empty () const;
  
  /**
   * @brief Get number of exclude terms
   */
  inline size_t
  size () const;

  /**
   * @brief Get begin iterator of the exclude terms
   */
  inline const_iterator
  begin () const;

  /**
   * @brief Get end iterator of the exclude terms
   */
  inline const_iterator
  end () const;

  /**
   * @brief Get begin iterator of the exclude terms
   */
  inline const_reverse_iterator
  rbegin () const;

  /**
   * @brief Get end iterator of the exclude terms
   */
  inline const_reverse_iterator
  rend () const;

  /**
   * @brief Get escaped string representation (e.g., for use in URI) of the exclude filter
   */
  inline std::string
  toUri () const;
  
private:
  Exclude &
  excludeRange (iterator fromLowerBound, iterator toLowerBound);

private:
  exclude_type m_exclude;
};

std::ostream&
operator << (std::ostream &os, const Exclude &name);

inline Exclude &
Exclude::excludeBefore (const Name::Component &to)
{
  return excludeRange (Name::Component (), to);
}

inline bool
Exclude::empty () const
{
  return m_exclude.empty ();
}

inline size_t
Exclude::size () const
{
  return m_exclude.size ();
}

inline Exclude::const_iterator
Exclude::begin () const
{
  return m_exclude.begin ();
}

inline Exclude::const_iterator
Exclude::end () const
{
  return m_exclude.end ();
}

inline Exclude::const_reverse_iterator
Exclude::rbegin () const
{
  return m_exclude.rbegin ();
}

inline Exclude::const_reverse_iterator
Exclude::rend () const
{
  return m_exclude.rend ();
}

inline std::string
Exclude::toUri () const
{
  std::ostringstream os;
  os << *this;
  return os.str();
}

} // ndn

#endif // NDN_EXCLUDE_H
