#include "ccnx-name.h"
#include <boost/lexical_cast.hpp>
#include <ctype.h>
#include <boost/algorithm/string/join.hpp>

namespace Ccnx{

CcnxCharbuf::CcnxCharbuf()
            : m_buf(NULL)
{
  m_buf = ccn_charbuf_create();
}

CcnxCharbuf::CcnxCharbuf(ccn_charbuf *buf)
            : m_buf(NULL)
{
  if (buf != NULL)
  {
    m_buf = ccn_charbuf_create();
    ccn_charbuf_reserve(m_buf, buf->length);
    memcpy(m_buf->buf, buf->buf, buf->length);
    m_buf->length = buf->length;
  }
}

CcnxCharbuf::~CcnxCharbuf()
{
  ccn_charbuf_destroy(&m_buf);
}

Name::Name()
{
}

Name::Name(const string &name)
{
  stringstream ss(name);
  string compStr;
  while(getline(ss, compStr, '/'))
  {
    Bytes comp(compStr.begin(), compStr.end());
    m_comps.push_back(comp);
  }
}

Name::Name(const vector<Bytes> &comps)
{
  m_comps = comps;
}

Name::Name(const Name &other)
{
  m_comps = other.m_comps;
}

Name::Name(const unsigned char *data, const ccn_indexbuf *comps)
{
  for (int i = 0; i < comps->n - 1; i++)
  {
    const unsigned char *compPtr;
    size_t size;
    ccn_name_comp_get(data, comps, i, &compPtr, &size);
    Bytes comp;
    readRaw(comp, compPtr, size);
    m_comps.push_back(comp);
  }
}

CcnxCharbufPtr
Name::toCcnxCharbuf() const
{
  CcnxCharbufPtr ptr(new CcnxCharbuf());
  ccn_charbuf *cbuf = ptr->getBuf();
  ccn_name_init(cbuf);
  int size = m_comps.size();
  for (int i = 0; i < size; i++)
  {
    ccn_name_append(cbuf, head(m_comps[i]), m_comps[i].size());
  }
  return ptr;
}

Name &
Name::appendComp(const Bytes &comp)
{
  m_comps.push_back(comp);
  return *this;
}

Name &
Name::appendComp(const string &compStr)
{
  Bytes comp(compStr.begin(), compStr.end());
  appendComp(comp);
  return *this;
}

Bytes
Name::getComp(int index) const
{
  if (index >= m_comps.size())
  {
    boost::throw_exception(NameException() << error_info_str("Index out of range: " + boost::lexical_cast<string>(index)));
  }
  return m_comps[index];
}

string
Name::getCompAsString(int index) const
{
  Bytes comp = getComp(index);
  stringstream ss(stringstream::out);
  int size = comp.size();
  for (int i = 0; i < size; i++)
  {
    unsigned char ch = comp[i];
    if (isprint(ch))
    {
      ss << (char) ch;
    }
    else
    {
      ss << "%" << hex << setfill('0') << setw(2) << ch;
    }
  }

  return ss.str();
}

Name
Name::getPartialName(int start, int n) const
{
  int size = m_comps.size();
  if (start < 0 || start >= size || start + n > size)
  {
    stringstream ss(stringstream::out);
    ss << "getPartialName() parameter out of range! ";
    ss << "start = " << start;
    ss << "n = " << n;
    ss << "size = " << size;
    boost::throw_exception(NameException() << error_info_str(ss.str()));
  }

  vector<Bytes> comps;
  for (int i = 0; i < n; i++)
  {
    comps.push_back(m_comps[start + i]);
  }
  return Name(comps);
}

ostream &
operator <<(ostream &os, const Name &name)
{
  int size = name.size();
  vector<string> strComps;
  for (int i = 0; i < size; i++)
  {
    strComps.push_back(name.getCompAsString(i));
  }
  string joined = boost::algorithm::join(strComps, "/");
  os << "/" << joined;
  return os;
}


Selectors::Selectors()
          : m_maxSuffixComps(-1)
          , m_minSuffixComps(-1)
          , m_answerOriginKind(AOK_DEFAULT)
          , m_interestLifetime(-1.0)
          , m_scope(-1)
          , m_childSelector(DEFAULT)
{
}

Selectors::Selectors(const Selectors &other)
{
  m_maxSuffixComps = other.m_maxSuffixComps;
  m_minSuffixComps = other.m_minSuffixComps;
  m_answerOriginKind = other.m_answerOriginKind;
  m_interestLifetime = other.m_interestLifetime;
  m_scope = other.m_scope;
  m_childSelector = other.m_childSelector;
  m_publisherPublicKeyDigest = other.m_publisherPublicKeyDigest;
}

CcnxCharbufPtr
Selectors::toCcnxCharbuf()
{
  CcnxCharbufPtr ptr(new CcnxCharbuf());
  ccn_charbuf *cbuf = ptr->getBuf();
  ccn_charbuf_append_tt(cbuf, CCN_DTAG_Interest, CCN_DTAG);
  ccn_charbuf_append_tt(cbuf, CCN_DTAG_Name, CCN_DTAG);
  ccn_charbuf_append_closer(cbuf); // </Name>

  if (m_maxSuffixComps < m_minSuffixComps)
  {
    boost::throw_exception(InterestSelectorException() << error_info_str("MaxSuffixComps = " + boost::lexical_cast<string>(m_maxSuffixComps) + " is smaller than  MinSuffixComps = " + boost::lexical_cast<string>(m_minSuffixComps)));
  }

  if (m_maxSuffixComps > 0)
  {
    ccnb_tagged_putf(cbuf, CCN_DTAG_MaxSuffixComponents, "%d", m_maxSuffixComps);
  }

  if (m_minSuffixComps > 0)
  {
    ccnb_tagged_putf(cbuf, CCN_DTAG_MinSuffixComponents, "%d", m_minSuffixComps);
  }

  if (m_answerOriginKind != AOK_DEFAULT)
  {
    // it was not using "ccnb_tagged_putf" in ccnx c code, no idea why
    ccn_charbuf_append_tt(cbuf, CCN_DTAG_AnswerOriginKind, CCN_DTAG);
    ccnb_append_number(cbuf, m_answerOriginKind);
    ccn_charbuf_append_closer(cbuf); // <AnswerOriginKind>
  }

  if (m_scope != -1)
  {
    ccnb_tagged_putf(cbuf, CCN_DTAG_Scope, "%d", m_scope);
  }

  if (m_interestLifetime > 0.0)
  {
    // Ccnx timestamp unit is weird 1/4096 second
    // this is from their code
    unsigned lifetime = 4096 * (m_interestLifetime + 1.0/8192.0);
    if (lifetime == 0 || lifetime > (30 << 12))
    {
      boost::throw_exception(InterestSelectorException() << error_info_str("Ccnx requires 0 < lifetime < 30.0. lifetime= " + boost::lexical_cast<string>(m_interestLifetime)));
    }
    unsigned char buf[3] = {0};
    for (int i = sizeof(buf) - 1; i >= 0; i--, lifetime >>= 8)
    {
      buf[i] = lifetime & 0xff;
    }
    ccnb_append_tagged_blob(cbuf, CCN_DTAG_InterestLifetime, buf, sizeof(buf));
  }

  if (m_childSelector != DEFAULT)
  {
    ccnb_tagged_putf(cbuf, CCN_DTAG_ChildSelector, "%d", m_childSelector);
  }


  ccn_charbuf_append_closer(cbuf); // </Interest>

  return ptr;
}

} // Ccnx
