/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
#define NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP

#include "../../common.hpp"

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

namespace ndn {

class RegexComponentSetMatcher : public RegexMatcher {

public:
  /**
   * @brief Create a RegexComponentSetMatcher matcher from expr
   * @param expr The standard regular expression to match a component
   * @param exact The flag to provide exact match
   * @param backRefNum The starting back reference number
   */
  RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager);    

  virtual ~RegexComponentSetMatcher();

  virtual bool 
  match(const Name& name, const int& offset, const int& len = 1);

protected:    
  /**
   * @brief Compile the regular expression to generate the more matchers when necessary
   * @returns true if compiling succeeds
   */
  virtual void 
  compile();

private:
  int
  extractComponent(int index);

  void
  compileSingleComponent();
    
  void
  compileMultipleComponents(const int start, const int lastIndex);

private:
  typedef std::set<shared_ptr<RegexComponentMatcher> > ComponentsSet;
  ComponentsSet m_components;
  bool m_include;
};


inline
RegexComponentSetMatcher::RegexComponentSetMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager)
  : RegexMatcher(expr, EXPR_COMPONENT_SET, backRefManager),
    m_include(true)
{
  // _LOG_TRACE ("Enter RegexComponentSetMatcher Constructor");
  compile();
  // _LOG_TRACE ("Exit RegexComponentSetMatcher Constructor");
}

inline
RegexComponentSetMatcher::~RegexComponentSetMatcher()
{
  // ComponentsSet::iterator it = m_components.begin();

  // for(; it != m_components.end(); it++)
  //   delete *it;
}

inline void 
RegexComponentSetMatcher::compile()
{
  int index = 0;

  switch(m_expr[0]){
  case '<':
    return compileSingleComponent();
  case '[':
    {
      int lastIndex = m_expr.size() - 1;
      if(']' != m_expr[lastIndex])
        throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
                                  + " No matched ']' " + m_expr);
      
      if('^' == m_expr[1]){
        m_include = false;
        compileMultipleComponents(2, lastIndex);
      }
      else
        compileMultipleComponents(1, lastIndex);
      break;
    }
  default:
    throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compile(): ")
                              + "Parsing error in expr " + m_expr);
  }
}

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

  if(m_expr.size() != end)
    {
      throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileSingleComponent: ")
                                + m_expr);
    }
  else
    {
      shared_ptr<RegexComponentMatcher> component =
        make_shared<RegexComponentMatcher>(m_expr.substr(1, end - 2), m_backrefManager);
      
      m_components.insert(component);      
    }
}

inline void 
RegexComponentSetMatcher::compileMultipleComponents(const int start, const int lastIndex)
{
  int index = start;
  int tmp_index = start;
    
  while(index < lastIndex){
    if('<' != m_expr[index])
      throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ")
                                + "Component expr error " + m_expr);
      
    tmp_index = index + 1;
    index = extractComponent(tmp_index);

    shared_ptr<RegexComponentMatcher> component =
      make_shared<RegexComponentMatcher>(m_expr.substr(tmp_index, index - tmp_index - 1), m_backrefManager);
    
    m_components.insert(component);
  }
    
  if(index != lastIndex)
    throw RegexMatcher::Error(std::string("Error: RegexComponentSetMatcher.compileMultipleComponents: ")
                              + "Not sufficient expr to parse " + m_expr);        
}

inline bool 
RegexComponentSetMatcher::match(const Name & name, const int & offset, const int & len)
{
  bool matched = false;

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

  for (ComponentsSet::iterator it = m_components.begin();
       it != m_components.end();
       ++it)
    {
      if((*it)->match(name, offset, len))
        {
          matched = true;
          break;
        }
    }
    
  m_matchResult.clear();

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

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

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

    case '>':
      rcount++;
      break;

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

  }

  return index;
}

} // namespace ndn

#endif // NDN_UTIL_REGEX_COMPONENT_SET_MATCHER_HPP
