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

#include "name.h"

#include "detail/error.h"
#include <boost/algorithm/string.hpp>

#include <ctype.h>

using namespace std;

NDN_NAMESPACE_BEGIN

ATTRIBUTE_HELPER_CPP (Name);

///////////////////////////////////////////////////////////////////////////////
//                              CONSTRUCTORS                                 //
///////////////////////////////////////////////////////////////////////////////

Name::Name ()
{
}

Name::Name (const string &uri)
{ 
  string::const_iterator i = uri.begin ();
  string::const_iterator end = uri.end ();

  string::const_iterator firstSlash = std::find (i, end, '/');
  if (firstSlash == end)
    {
      BOOST_THROW_EXCEPTION (error::Name ()
                             << error::msg ("Name should include at least one slash (did you forget to specify initial /?)"));
    }

  if (firstSlash != i)
    {
      string schema (i, firstSlash);
      if (*schema.rbegin () != ':')
        {
          BOOST_THROW_EXCEPTION (error::Name ()
                                 << error::msg ("First component of the name does not start with a slash (did you forget to specify initial /?)"));
        }

      i = firstSlash;

      if (!boost::iequals (schema, "ccnx:") &&
          !boost::iequals (schema, "ndn:"))
        {
          BOOST_THROW_EXCEPTION (error::Name ()
                                 << error::msg ("URI schema is not supported (only ccnx: or ndn: is allowed)")
                                 << error::msg (schema));
        }
    }

  string::const_iterator secondSlash = i;
  secondSlash ++;
  if (secondSlash != end && *secondSlash == '/')
    {
      // The authority component (the part after the initial "//" in the familiar http and ftp URI schemes) is present,
      // but it is not relevant to NDN name.
      // skipping it
      secondSlash ++;
      i = std::find (secondSlash, end, '/');
    }
  
  if (i == end)
    {
      BOOST_THROW_EXCEPTION (error::Name ()
                             << error::msg ("Invalid URI")
                             << error::msg (uri));
    }

  while (i != end)
    {
      // skip any extra slashes
      while (i != end && *i == '/')
        {
          i ++;
        }
      if (i == end)
        break;
      
      string::const_iterator endOfComponent = std::find (i, end, '/');
      name::Component comp;
      appendBySwap (comp.fromUri (i, endOfComponent));

      i = endOfComponent;
    }
}

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

Name &
Name::operator= (const Name &other)
{
  m_comps = other.m_comps;
  return *this;
}

///////////////////////////////////////////////////////////////////////////////
//                                SETTERS                                    //
///////////////////////////////////////////////////////////////////////////////

Name &
Name::appendVersion (uint64_t version/* = Name::nversion*/)
{
  if (version != Name::nversion)
    return appendNumberWithMarker (version, 0xFD);
  else
    {
      TimeInterval now = time::NowUnixTimestamp ();
#ifdef NDNSIM_MODE
      int64_t seconds = now.GetSeconds ();
      int64_t microseconds = now.GetMicroSeconds () - seconds * 1000000;
      
      version = (seconds << 12) | (0xFFF & (microseconds / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
#else
      version = (now.total_seconds () << 12) | (0xFFF & (now.fractional_seconds () / 244 /*( 1000,000 microseconds / 4096.0 resolution = last 12 bits)*/));
#endif
      return appendNumberWithMarker (version, 0xFD);
    }
}


///////////////////////////////////////////////////////////////////////////////
//                                GETTERS                                    //
///////////////////////////////////////////////////////////////////////////////

const name::Component &
Name::get (int index) const
{
  if (index < 0)
    {
      index = size () - (-index);
    }

  if (static_cast<unsigned int> (index) >= size ())
    {
      BOOST_THROW_EXCEPTION (error::Name ()
                             << error::msg ("Index out of range")
                             << error::pos (index));
    }
  return m_comps [index];
}

name::Component &
Name::get (int index)
{
  if (index < 0)
    {
      index = size () - (-index);
    }

  if (static_cast<unsigned int> (index) >= size())
    {
      BOOST_THROW_EXCEPTION (error::Name ()
                             << error::msg ("Index out of range")
                             << error::pos (index));
    }
  return m_comps [index];
}


/////
///// Static helpers to convert name component to appropriate value
/////


Name
Name::getSubName (size_t pos/* = 0*/, size_t len/* = Name::npos*/) const
{
  Name retval;

  if (len == npos)
    {
      len = size () - pos;
    }

  if (pos + len > size ())
    {
      BOOST_THROW_EXCEPTION (error::Name ()
                             << error::msg ("getSubName parameter out of range")
                             << error::pos (pos)
                             << error::pos (len));
    }

  for (size_t i = pos; i < pos + len; i++)
    {
      retval.append (get (i));
    }

  return retval;
}

Name
Name::operator+ (const Name &name) const
{
  Name newName;
  newName
    .append (*this)
    .append (name);

  return newName;
}

std::string
Name::toUri () const
{
  ostringstream os;
  toUri (os);
  return os.str ();
}

void
Name::toUri (std::ostream &os) const
{
  for (Name::const_iterator comp = begin (); comp != end (); comp++)
    {
      os << "/";
      comp->toUri (os);
    }
  if (size () == 0)
    os << "/";
}

// ostream &
// operator << (ostream &os, const Name &name)
// {
//   for (Name::const_iterator comp = name.begin (); comp != name.end (); comp++)
//     {
//       os << "/" << *comp;
//     }
//   if (name.size () == 0)
//     os << "/";
//   return os;
// }

int
Name::compare (const Name &name) const
{
  Name::const_iterator i = this->begin ();
  Name::const_iterator j = name.begin ();

  for (; i != this->end () && j != name.end (); i++, j++)
    {
      int res = i->compare (*j);
      if (res == 0)
        continue;
      else
        return res;
    }

  if (i == this->end () && j == name.end ())
    return 0; // prefixes are equal

  return (i == this->end ()) ? -1 : +1;
}

NDN_NAMESPACE_END
