/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_INTEREST_HPP
#define NDN_INTEREST_HPP

#include "common.hpp"
#include "name.hpp"
#include "exclude.hpp"
#include "encoding/block.hpp"

namespace ndn {
  
/**
 * An Interest holds a Name and other fields for an interest.
 */
class Interest {
public:    
  /**
   * Create a new Interest for the given name and values.
   * @param name
   * @param minSuffixComponents
   * @param maxSuffixComponents
   * @param exclude
   * @param childSelector
   * @param mustBeFresh
   * @param scope
   * @param interestLifetime
   * @param nonce
   */
  Interest(const Name& name,
           int minSuffixComponents, int maxSuffixComponents, 
           const Exclude& exclude,
           int childSelector,
           bool mustBeFresh, 
           int scope,
           Milliseconds interestLifetime,
           uint32_t nonce = 0) 
  : name_(name)
  , minSuffixComponents_(minSuffixComponents)
  , maxSuffixComponents_(maxSuffixComponents)
  , exclude_(exclude), childSelector_(childSelector)
  , mustBeFresh_(mustBeFresh)
  , scope_(scope)
  , interestLifetime_(interestLifetime)
  , nonce_(nonce)
  {
  }

  /**
   * Create a new Interest with the given name and interest lifetime and "none" for other values.
   * @param name The name for the interest.
   * @param interestLifetimeMilliseconds The interest lifetime in milliseconds, or -1 for none.
   */
  Interest(const Name& name, Milliseconds interestLifetime) 
  : name_(name)
  {
    construct();
    interestLifetime_ = interestLifetime;
  }

  /**
   * Create a new Interest with the given name and "none" for other values.
   * @param name The name for the interest.
   */
  Interest(const Name& name) 
  : name_(name)
  {
    construct();
  }

  /**
   * Create a new Interest with an empty name and "none" for all values.
   */
  Interest() 
  {
    construct();
  }
  
  /**
   * Encode this Interest for a particular wire format.
   * @return The encoded byte array.
   */
  const Block&
  wireEncode() const;
  
  /**
   * Decode the input using a particular wire format and update this Interest.
   * @param input The input byte array to be decoded.
   */
  void 
  wireDecode(const Block &wire);
  
  /**
   * Encode the name according to the "NDN URI Scheme".  If there are interest selectors, append "?" and
   * added the selectors as a query string.  For example "/test/name?ndn.ChildSelector=1".
   * @return The URI string.
   */
  inline std::string
  toUri() const;

  Name& 
  getName() { return name_; }
  
  const Name& 
  getName() const { return name_; }
  
  int 
  getMinSuffixComponents() const { return minSuffixComponents_; }
  
  int 
  getMaxSuffixComponents() const { return maxSuffixComponents_; }

  Exclude& 
  getExclude() { return exclude_; }
  
  const Exclude& 
  getExclude() const { return exclude_; }
  
  int 
  getChildSelector() const { return childSelector_; }

  int 
  getMustBeFresh() const { return mustBeFresh_; }

  int 
  getScope() const { return scope_; }

  Milliseconds 
  getInterestLifetime() const { return interestLifetime_; }

  /**
   * @brief Get Interest's nonce
   *
   * If nonce was not set before this call, it will be automatically assigned to a random value
   *
   * Const reference needed for C decoding
   */
  const uint32_t&
  getNonce() const;

  uint64_t
  getIncomingFaceId() const { return m_incomingFaceId; }
    
  void
  setName(const Name& name) { name_ = name; }
  
  void 
  setMinSuffixComponents(int minSuffixComponents) { minSuffixComponents_ = minSuffixComponents; }
  
  void 
  setMaxSuffixComponents(int maxSuffixComponents) { maxSuffixComponents_ = maxSuffixComponents; }
  
  void 
  setChildSelector(int childSelector) { childSelector_ = childSelector; }

  void 
  setMustBeFresh(bool mustBeFresh) { mustBeFresh_ = mustBeFresh; }

  void 
  setScope(int scope) { scope_ = scope; }

  void 
  setInterestLifetime(Milliseconds interestLifetime) { interestLifetime_ = interestLifetime; }

  void 
  setNonce(uint32_t nonce) { nonce_ = nonce; }

  void
  setIncomingFaceId(uint64_t incomingFaceId) { m_incomingFaceId = incomingFaceId; }

  inline bool
  hasSelectors() const;

  inline bool
  hasGuiders() const;

  /**
   * @brief Check if Interest name matches the given name (using ndn_Name_match) and the given name also conforms to the 
   * interest selectors.
   * @param self A pointer to the ndn_Interest struct.
   * @param name A pointer to the name to check.
   * @return 1 if the name and interest selectors match, 0 otherwise.
   */
  bool
  matchesName(const Name &name) const;
  
private:
  void 
  construct() 
  {
    minSuffixComponents_ = -1;
    maxSuffixComponents_ = -1;  
    childSelector_ = -1;
    mustBeFresh_ = false; // default
    scope_ = -1;
    interestLifetime_ = -1.0;
    nonce_ = 0;
  }
  
  Name name_;
  int minSuffixComponents_;
  int maxSuffixComponents_;  
  Exclude exclude_;
  int childSelector_;
  bool mustBeFresh_;
  int scope_;
  Milliseconds interestLifetime_;
  mutable uint32_t nonce_;

  mutable Block wire_;

  uint64_t m_incomingFaceId;
};

std::ostream &
operator << (std::ostream &os, const Interest &interest);

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

inline bool
Interest::hasSelectors() const
{
  return minSuffixComponents_ >= 0 ||
    maxSuffixComponents_ >= 0 ||
    !exclude_.empty() ||
    childSelector_ >= 0 ||
    mustBeFresh_ == true ||
    scope_ >= 0;
}

inline bool
Interest::hasGuiders() const
{
  return scope_ >= 0 ||
    interestLifetime_ >= 0 ||
    nonce_ > 0;
}

}

#endif
