/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2015 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "regex-component-set-matcher.hpp"

namespace ndn {

RegexComponentSetMatcher::RegexComponentSetMatcher(const std::string& expr,
                                                   shared_ptr<RegexBackrefManager> backrefManager)
  : RegexMatcher(expr, EXPR_COMPONENT_SET, backrefManager)
  , m_isInclusion(true)
{
  compile();
}

RegexComponentSetMatcher::~RegexComponentSetMatcher()
{
}

bool
RegexComponentSetMatcher::match(const Name& name, size_t offset, size_t len)
{
  bool isMatched = false;

  /* componentset only matches one component */
  if (len != 1)
    {
      return false;
    }

  for (auto& component : m_components) {
    if (component->match(name, offset, len)) {
      isMatched = true;
      break;
    }
  }

  m_matchResult.clear();

  if (m_isInclusion ? isMatched : !isMatched) {
    m_matchResult.push_back(name.get(offset));
    return true;
  }
  else
    return false;
}

void
RegexComponentSetMatcher::compile()
{
  if (m_expr.size() < 2)
    throw Error("Regexp compile error (cannot parse " + m_expr + ")");

  switch (m_expr[0]) {
  case '<':
    return compileSingleComponent();
  case '[':
    {
      size_t lastIndex = m_expr.size() - 1;
      if (']' != m_expr[lastIndex])
        throw Error("Regexp compile error (no matching ']' in " + m_expr + ")");

      if ('^' == m_expr[1]) {
        m_isInclusion = false;
        compileMultipleComponents(2, lastIndex);
      }
      else
        compileMultipleComponents(1, lastIndex);
      break;
    }
  default:
    throw Error("Regexp compile error (cannot parse " + m_expr + ")");
  }
}

void
RegexComponentSetMatcher::compileSingleComponent()
{
  size_t end = extractComponent(1);

  if (m_expr.size() != end) {
    throw Error("Component expr error " + m_expr);
  }
  else {
    auto component = make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2),
                                                        m_backrefManager);

    m_components.insert(component);
  }
}

void
RegexComponentSetMatcher::compileMultipleComponents(size_t start, size_t lastIndex)
{
  size_t index = start;
  size_t tempIndex = start;

  while (index < lastIndex) {
    if ('<' != m_expr[index])
      throw Error("Component expr error " + m_expr);

    tempIndex = index + 1;
    index = extractComponent(tempIndex);

    auto component = make_shared<RegexComponentMatcher>(m_expr.substr(tempIndex,
                                                                      index - tempIndex - 1),
                                                        m_backrefManager);

    m_components.insert(component);
  }

  if (index != lastIndex)
    throw Error("Not sufficient expr to parse " + m_expr);
}

size_t
RegexComponentSetMatcher::extractComponent(size_t index)
{
  size_t lcount = 1;
  size_t rcount = 0;

  while (lcount > rcount) {
    switch (m_expr[index]) {
    case '<':
      lcount++;
      break;

    case '>':
      rcount++;
      break;

    case 0:
      throw Error("Error: square brackets mismatch");
      break;
    }
    index++;

  }

  return index;
}

} // namespace ndn
