#include "ccnx-tunnel.h"
#include "ccnx-pco.h"

namespace Ccnx
{

CcnxTunnel::CcnxTunnel()
                          : CcnxWrapper()
                          , m_localPrefix("/")
{
  refreshLocalPrefix();
}

CcnxTunnel::~CcnxTunnel()
{
}

void
CcnxTunnel::refreshLocalPrefix()
{
  Name newPrefix = getLocalPrefix();
  if (!newPrefix.toString().empty() && m_localPrefix != newPrefix)
  {
    CcnxWrapper::clearInterestFilter(m_localPrefix);
    CcnxWrapper::setInterestFilter(newPrefix, bind(&CcnxTunnel::handleTunneledInterest, this, _1));
    m_localPrefix = newPrefix;
  }
}

int
CcnxTunnel::sendInterest (const Name &interest, const Closure *closure, const Selectors &selectors)
{
  Name tunneledInterest = queryRoutableName(interest);
  Closure *cp = new TunnelClosure(closure, this, interest);
  CcnxWrapper::sendInterest(tunneledInterest, cp, selectors);
  delete cp;
}

void
CcnxTunnel::handleTunneledData(const Name &name, const Bytes &tunneledData, const Closure::DataCallback &originalDataCallback)
{
  ParsedContentObject pco(tunneledData);
  originalDataCallback(pco.name(), pco.content());
}

int
CcnxTunnel::publishData(const Name &name, const unsigned char *buf, size_t len, int freshness)
{
  Bytes content = createContentObject(name, buf, len, freshness);
  storeContentObject(name, content);

  return publishContentObject(name, content, freshness);
}

int
CcnxTunnel::publishContentObject(const Name &name, const Bytes &contentObject, int freshness)
{
  Name tunneledName = m_localPrefix + name;
  Bytes tunneledCo = createContentObject(tunneledName, head(contentObject), contentObject.size(), freshness);
  return putToCcnd(tunneledCo);
}

void
CcnxTunnel::handleTunneledInterest(const Name &tunneledInterest)
{
  // The interest must have m_localPrefix as a prefix (component-wise), otherwise ccnd would not deliver it to us
  Name interest = tunneledInterest.getPartialName(m_localPrefix.size());

  ReadLock(m_ritLock);

  // This is linear scan, but should be acceptable under the assumption that the caller wouldn't be listening to a lot prefixes (as of now, most app listen to one or two prefixes)
  for (RitIter it = m_rit.begin(); it != m_rit.end(); it++)
  {
    // evoke callback for any prefix that is the prefix of the interest
    if (isPrefix(it->first, interest))
    {
      (it->second)(interest);
    }
  }
}

bool
CcnxTunnel::isPrefix(const Name &prefix, const Name &name)
{
  if (prefix.size() > name.size())
  {
    return false;
  }

  int size = prefix.size();
  for (int i = 0; i < size; i++)
  {
    if (prefix.getCompAsString(i) != name.getCompAsString(i))
    {
      return false;
    }
  }

  return true;
}

int
CcnxTunnel::setInterestFilter(const Name &prefix, const InterestCallback &interestCallback)
{
  WriteLock(m_ritLock);
  // make sure copy constructor for boost::function works properly
  m_rit.insert(make_pair(prefix, interestCallback));
  return 0;
}

void
CcnxTunnel::clearInterestFilter(const Name &prefix)
{
  WriteLock(m_ritLock);
  // remove all
  m_rit.erase(prefix);
}

TunnelClosure::TunnelClosure(int retry, const DataCallback &dataCallback, CcnxTunnel *tunnel, const Name &originalInterest, const TimeoutCallback &timeoutCallback)
                  : Closure(retry, dataCallback, timeoutCallback)
                  , m_tunnel(tunnel)
                  , m_originalInterest(originalInterest)
{
}

TunnelClosure::TunnelClosure(const Closure *closure, CcnxTunnel *tunnel, const Name &originalInterest)
                 : Closure(*closure)
                 , m_tunnel(tunnel)
{
}

Closure *
TunnelClosure::dup() const
{
  Closure *closure = new TunnelClosure(m_retry, *m_dataCallback, m_tunnel, m_originalInterest, *m_timeoutCallback);
  return closure;
}

void
TunnelClosure::runDataCallback(const Name &name, const Bytes &content)
{
  if (m_tunnel != NULL)
  {
    m_tunnel->handleTunneledData(name, content, (*m_dataCallback));
  }
}

Closure::TimeoutCallbackReturnValue
TunnelClosure::runTimeoutCallback(const Name &interest)
{
  return Closure::runTimeoutCallback(m_originalInterest);
}

} // Ccnx
