/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 */

#include "regex-top-matcher.hpp"

#include "regex-backref-manager.hpp"
#include "regex-pattern-list-matcher.hpp"

#include <boost/lexical_cast.hpp>

namespace ndn {

RegexTopMatcher::RegexTopMatcher(const std::string& expr, const std::string& expand)
  : RegexMatcher(expr, EXPR_TOP)
  , m_expand(expand)
  , m_isSecondaryUsed(false)
{
  m_primaryBackrefManager = make_shared<RegexBackrefManager>();
  m_secondaryBackrefManager = make_shared<RegexBackrefManager>();
  compile();
}

RegexTopMatcher::~RegexTopMatcher()
{
}

void
RegexTopMatcher::compile()
{
  std::string errMsg = "Error: RegexTopMatcher.Compile(): ";

  std::string expr = m_expr;

  if ('$' != expr[expr.size() - 1])
    expr = expr + "<.*>*";
  else
    expr = expr.substr(0, expr.size() - 1);

  if ('^' != expr[0]) {
    m_secondaryMatcher = make_shared<RegexPatternListMatcher>(
      "<.*>*" + expr,
      m_secondaryBackrefManager);
  }
  else {
    expr = expr.substr(1, expr.size() - 1);
  }

  // On OSX 10.9, boost, and C++03 the following doesn't work without ndn::
  // because the argument-dependent lookup prefers STL to boost
  m_primaryMatcher = ndn::make_shared<RegexPatternListMatcher>(expr,
                                                               m_primaryBackrefManager);
}

bool
RegexTopMatcher::match(const Name& name)
{
  m_isSecondaryUsed = false;

  m_matchResult.clear();

  if (m_primaryMatcher->match(name, 0, name.size()))
    {
      m_matchResult = m_primaryMatcher->getMatchResult();
      return true;
    }
  else
    {
      if (static_cast<bool>(m_secondaryMatcher) && m_secondaryMatcher->match(name, 0, name.size()))
        {
          m_matchResult = m_secondaryMatcher->getMatchResult();
          m_isSecondaryUsed = true;
          return true;
        }
      return false;
    }
}

bool
RegexTopMatcher::match(const Name& name, size_t, size_t)
{
  return match(name);
}

Name
RegexTopMatcher::expand(const std::string& expandStr)
{
  Name result;

  shared_ptr<RegexBackrefManager> backrefManager =
    (m_isSecondaryUsed ? m_secondaryBackrefManager : m_primaryBackrefManager);

  size_t backrefNo = backrefManager->size();

  std::string expand;

  if (!expandStr.empty())
    expand = expandStr;
  else
    expand = m_expand;

  size_t offset = 0;
  while (offset < expand.size())
    {
      std::string item = getItemFromExpand(expand, offset);
      if (item[0] == '<')
        {
          result.append(item.substr(1, item.size() - 2));
        }
      if (item[0] == '\\')
        {
          size_t index = boost::lexical_cast<size_t>(item.substr(1, item.size() - 1));

          if (0 == index) {
            std::vector<name::Component>::iterator it = m_matchResult.begin();
            std::vector<name::Component>::iterator end = m_matchResult.end();
            for (; it != end; it++)
              result.append(*it);
          }
          else if (index <= backrefNo)
            {
              std::vector<name::Component>::const_iterator it =
                backrefManager->getBackref(index - 1)->getMatchResult().begin();
              std::vector<name::Component>::const_iterator end =
                backrefManager->getBackref(index - 1)->getMatchResult().end();
              for (; it != end; it++)
                result.append(*it);
            }
          else
            throw RegexMatcher::Error("Exceed the range of back reference");
        }
    }
  return result;
}

std::string
RegexTopMatcher::getItemFromExpand(const std::string& expand, size_t& offset)
{
  size_t begin = offset;

  if (expand[offset] == '\\')
    {
      offset++;
      if (offset >= expand.size())
        throw RegexMatcher::Error("wrong format of expand string!");

      while (expand[offset] <= '9' and expand[offset] >= '0') {
        offset++;
        if (offset > expand.size())
          throw RegexMatcher::Error("wrong format of expand string!");
      }
      if (offset > begin + 1)
        return expand.substr(begin, offset - begin);
      else
        throw RegexMatcher::Error("wrong format of expand string!");
    }
  else if (expand[offset] == '<')
    {
      offset++;
      if (offset >= expand.size())
        throw RegexMatcher::Error("wrong format of expand string!");

      size_t left = 1;
      size_t right = 0;
      while (right < left)
        {
          if (expand[offset] == '<')
            left++;
          if (expand[offset] == '>')
            right++;
          offset++;
          if (offset >= expand.size())
            throw RegexMatcher::Error("wrong format of expand string!");
        }
      return expand.substr(begin, offset - begin);
    }
  else
    throw RegexMatcher::Error("wrong format of expand string!");
}

shared_ptr<RegexTopMatcher>
RegexTopMatcher::fromName(const Name& name, bool hasAnchor)
{
  std::string regexStr("^");

  for (Name::const_iterator it = name.begin(); it != name.end(); it++)
    {
      regexStr.append("<");
      regexStr.append(convertSpecialChar(it->toEscapedString()));
      regexStr.append(">");
    }

  if (hasAnchor)
    regexStr.append("$");

  // On OSX 10.9, boost, and C++03 the following doesn't work without ndn::
  // because the argument-dependent lookup prefers STL to boost
  return ndn::make_shared<RegexTopMatcher>(regexStr);
}

std::string
RegexTopMatcher::convertSpecialChar(const std::string& str)
{
  std::string newStr;
  for (size_t i = 0; i < str.size(); i++)
    {
      char c = str[i];
      switch (c)
        {
        case '.':
        case '[':
        case '{':
        case '}':
        case '(':
        case ')':
        case '\\':
        case '*':
        case '+':
        case '?':
        case '|':
        case '^':
        case '$':
          newStr.push_back('\\');
          // Fallthrough
        default:
          newStr.push_back(c);
          break;
        }
    }

  return newStr;
}

} // namespace ndn
