/* -*- 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.
 */

#include <stdexcept>
#include <ndn-cpp/common.hpp>
#include <ndn-cpp/interest.hpp>

#include <cryptopp/osrng.h>

using namespace std;

namespace ndn {

uint32_t
Interest::getNonce() const
{
  static CryptoPP::AutoSeededRandomPool rng;

  if (nonce_ == 0)
    nonce_ = rng.GenerateWord32();

  return nonce_;
}


bool
Interest::matchesName(const Name &name) const
{
  if (!name_.isPrefixOf(name))
    return false;
  
  if (minSuffixComponents_ >= 0 &&
    // Add 1 for the implicit digest.
      !(name.size() + 1 - name_.size() >= minSuffixComponents_))
    return false;

  if (maxSuffixComponents_ >= 0 &&
    // Add 1 for the implicit digest.
    !(name.size() + 1 - name_.size() <= maxSuffixComponents_))
    return false;

  if (!exclude_.empty() && name.size() > name_.size() &&
      exclude_.isExcluded(name[name_.size()]))
    return false;

  return true;
}

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

  char delim = '?';

  if (interest.getMinSuffixComponents() >= 0) {
    os << delim << "ndn.MinSuffixComponents=" << interest.getMinSuffixComponents();
    delim = '&';
  }
  if (interest.getMaxSuffixComponents() >= 0) {
    os << delim << "ndn.MaxSuffixComponents=" << interest.getMaxSuffixComponents();
    delim = '&';
  }
  if (interest.getChildSelector() >= 0) {
    os << delim << "ndn.ChildSelector=" << interest.getChildSelector();
    delim = '&';
  }
  if (interest.getMustBeFresh()) {
    os << delim << "ndn.MustBeFresh=" << interest.getMustBeFresh();
    delim = '&';
  }
  if (interest.getScope() >= 0) {
    os << delim << "ndn.Scope=" << interest.getScope();
    delim = '&';
  }
  if (interest.getInterestLifetime() >= 0) {
    os << delim << "ndn.InterestLifetime=" << interest.getInterestLifetime();
    delim = '&';
  }

  if (interest.getNonce() > 0) {
    os << delim << "ndn.Nonce=" << interest.getNonce();
    delim = '&';
  }
  if (!interest.getExclude().empty()) {
    os << delim << "ndn.Exclude=" << interest.getExclude();
    delim = '&';
  }

  return os;
}

const Block&
Interest::wireEncode() const
{
  if (wire_.hasWire())
    return wire_;

  // Interest ::= INTEREST-TYPE TLV-LENGTH
  //                Name
  //                Selectors?
  //                Nonce
  //                Scope?
  //                InterestLifetime?  
  
  wire_ = Block(Tlv::Interest);
  wire_.push_back(getName().wireEncode());

  // selectors
  {
    Block selectors(Tlv::Selectors);
    
    if (getMinSuffixComponents() >= 0) {
      selectors.push_back
        (nonNegativeIntegerBlock(Tlv::MinSuffixComponents, getMinSuffixComponents()));
    }
    if (getMaxSuffixComponents() >= 0) {
      selectors.push_back
        (nonNegativeIntegerBlock(Tlv::MaxSuffixComponents, getMaxSuffixComponents()));
    }
    if (!getExclude().empty()) {
      selectors.push_back
        (getExclude().wireEncode());
    }
    if (getChildSelector() >= 0) {
      selectors.push_back
        (nonNegativeIntegerBlock(Tlv::ChildSelector, getChildSelector()));
    }
    if (getMustBeFresh()) {
      selectors.push_back
        (booleanBlock(Tlv::MustBeFresh));
    }

    if (!selectors.getAll().empty())
      {
        selectors.encode();
        wire_.push_back(selectors);
      }
  }

  // Nonce
  {
    wire_.push_back
      (nonNegativeIntegerBlock(Tlv::Nonce, getNonce()));
  }
  
  if (getScope() >= 0) {
    wire_.push_back
      (nonNegativeIntegerBlock(Tlv::Scope, getScope()));
  }
  if (getInterestLifetime() >= 0) {
    wire_.push_back
      (nonNegativeIntegerBlock(Tlv::InterestLifetime, getInterestLifetime()));
  }
  
  wire_.encode();
  return wire_;
}
  
void 
Interest::wireDecode(const Block &wire) 
{
  wire_ = wire;
  wire_.parse();

  // Interest ::= INTEREST-TYPE TLV-LENGTH
  //                Name
  //                Selectors?
  //                Nonce
  //                Scope?
  //                InterestLifetime?  
  
  // Name
  name_.wireDecode(wire_.get(Tlv::Name));

  // Selectors
  Block::element_iterator selectors = wire_.find(Tlv::Selectors);
  if (selectors != wire_.getAll().end())
    {
      selectors->parse();

      // MinSuffixComponents
      Block::element_iterator val = selectors->find(Tlv::MinSuffixComponents);
      if (val != selectors->getAll().end())
        {
          minSuffixComponents_ = readNonNegativeInteger(*val);
        }

      // MaxSuffixComponents
      val = selectors->find(Tlv::MaxSuffixComponents);
      if (val != selectors->getAll().end())
        {
          maxSuffixComponents_ = readNonNegativeInteger(*val);
        }

      // Exclude
      val = selectors->find(Tlv::Exclude);
      if (val != selectors->getAll().end())
        {
          exclude_.wireDecode(*val);
        }

      // ChildSelector
      val = selectors->find(Tlv::ChildSelector);
      if (val != selectors->getAll().end())
        {
          childSelector_ = readNonNegativeInteger(*val);
        }

      //MustBeFresh aka AnswerOriginKind
      val = selectors->find(Tlv::MustBeFresh);
      if (val != selectors->getAll().end())
        {
          mustBeFresh_ = true;
        }
    }
  
  // Nonce
  Block::element_iterator val = wire_.find(Tlv::Nonce);
  if (val != wire_.getAll().end())
    {
      nonce_ = readNonNegativeInteger(*val);
    }

  // Scope
  val = wire_.find(Tlv::Scope);
  if (val != wire_.getAll().end())
    {
      scope_ = readNonNegativeInteger(*val);
    }
  
  // InterestLifetime
  val = wire_.find(Tlv::InterestLifetime);
  if (val != wire_.getAll().end())
    {
      interestLifetime_ = readNonNegativeInteger(*val);
    } 
}


}
