/* -*- 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_REGEX_REPEAT_MATCHER_HPP
#define NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP

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

#include <boost/regex.hpp>

#include "regex-matcher.hpp"

namespace ndn {

class RegexRepeatMatcher : public RegexMatcher
{
public:
  RegexRepeatMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backRefManager, int indicator);
    
  virtual ~RegexRepeatMatcher(){}

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

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

private:
  bool 
  parseRepetition();

  bool 
  recursiveMatch (int repeat,
                  const Name & name,
                  const int & offset,
                  const int &len);
  
private:
  int m_indicator;
  int m_repeatMin;
  int m_repeatMax;
};

} // namespace ndn

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

namespace ndn {

inline
RegexRepeatMatcher::RegexRepeatMatcher(const std::string& expr, shared_ptr<RegexBackrefManager> backrefManager, int indicator)
  : RegexMatcher (expr, EXPR_REPEAT_PATTERN, backrefManager),
    m_indicator(indicator)
{
  // _LOG_TRACE ("Enter RegexRepeatMatcher Constructor");
  compile();
  // _LOG_TRACE ("Exit RegexRepeatMatcher Constructor");
}

inline void 
RegexRepeatMatcher::compile()
{
  // _LOG_TRACE ("Enter RegexRepeatMatcher::compile");
    
  shared_ptr<RegexMatcher> matcher;

  if('(' == m_expr[0]){
    matcher = make_shared<RegexBackrefMatcher>(m_expr.substr(0, m_indicator), m_backrefManager);
    m_backrefManager->pushRef(matcher);
    boost::dynamic_pointer_cast<RegexBackrefMatcher>(matcher)->lateCompile();
  }
  else{
    matcher = make_shared<RegexComponentSetMatcher>(m_expr.substr(0, m_indicator), m_backrefManager);
  }
  m_matcherList.push_back(matcher);
      
  parseRepetition();

  // _LOG_TRACE ("Exit RegexRepeatMatcher::compile");

}

inline bool 
RegexRepeatMatcher::parseRepetition()
{
  // _LOG_DEBUG ("Enter RegexRepeatMatcher::ParseRepetition()" << m_expr << " indicator: " << m_indicator);
    
  int exprSize = m_expr.size();
  int intMax = std::numeric_limits<int>::max();
    
  if(exprSize == m_indicator){
    m_repeatMin = 1;
    m_repeatMax = 1;

    return true;
  }
  else{
    if(exprSize == (m_indicator + 1)){
      if('?' == m_expr[m_indicator]){
        m_repeatMin = 0;
        m_repeatMax = 1;
        return true;
      }
      if('+' == m_expr[m_indicator]){
        m_repeatMin = 1;
        m_repeatMax = intMax;
        return true;
      }
      if('*' == m_expr[m_indicator]){
        m_repeatMin = 0;
        m_repeatMax = intMax;
        return true;
      }
    }
    else{
      std::string repeatStruct = m_expr.substr(m_indicator, exprSize - m_indicator);
      int rsSize = repeatStruct.size();
      int min = 0;
      int max = 0;

      if(boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,[0-9]+\\}"))){
        int separator = repeatStruct.find_first_of(',', 0);
        min = atoi(repeatStruct.substr(1, separator - 1).c_str());
        max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
      }
      else if(boost::regex_match(repeatStruct, boost::regex("\\{,[0-9]+\\}"))){
        int separator = repeatStruct.find_first_of(',', 0);
        min = 0;
        max = atoi(repeatStruct.substr(separator + 1, rsSize - separator - 2).c_str());
      }
      else if(boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+,\\}"))){
        int separator = repeatStruct.find_first_of(',', 0);
        min = atoi(repeatStruct.substr(1, separator).c_str());
        max = intMax;
      }
      else if(boost::regex_match(repeatStruct, boost::regex("\\{[0-9]+\\}"))){
        min = atoi(repeatStruct.substr(1, rsSize - 1).c_str());
        max = min;
      }
      else
        throw RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition(): ")
                                  + "Unrecognized format "+ m_expr);
        
      if(min > intMax || max > intMax || min > max)
        throw RegexMatcher::Error(std::string("Error: RegexRepeatMatcher.ParseRepetition(): ")
                                  + "Wrong number " + m_expr);
          
      m_repeatMin = min;
      m_repeatMax = max;
        
      return true;
    }
  }
  return false;
}

inline bool
RegexRepeatMatcher::match(const Name & name, const int & offset, const int & len)
{
  // _LOG_TRACE ("Enter RegexRepeatMatcher::match");

  m_matchResult.clear();

  if (0 == m_repeatMin)
    if (0 == len)
      return true;

  if (recursiveMatch(0, name, offset, len))
    {
      for (int i = offset; i < offset + len; i++)
        m_matchResult.push_back(name.get(i));
      return true;
    }
  else
    return false;
}

inline bool 
RegexRepeatMatcher::recursiveMatch(int repeat, const Name & name, const int & offset, const int & len)
{
  // _LOG_TRACE ("Enter RegexRepeatMatcher::recursiveMatch");

  // _LOG_DEBUG ("repeat: " << repeat << " offset: " << offset << " len: " << len);
  // _LOG_DEBUG ("m_repeatMin: " << m_repeatMin << " m_repeatMax: " << m_repeatMax);

  int tried = len;
  shared_ptr<RegexMatcher> matcher = m_matcherList[0];

  if (0 < len && repeat >= m_repeatMax)
    {
      // _LOG_DEBUG("Match Fail: Reach m_repeatMax && More components");
      return false;
    }

  if (0 == len && repeat < m_repeatMin)
    {
      // _LOG_DEBUG("Match Fail: No more components && have NOT reached m_repeatMin " << len << ", " << m_repeatMin);
      return false;
    }

  if (0 == len && repeat >= m_repeatMin)
    {
      // _LOG_DEBUG("Match Succeed: No more components && reach m_repeatMin");
      return true;
    }
    
  while(tried >= 0)
    {
      // _LOG_DEBUG("Attempt tried: " << tried);

      if (matcher->match(name, offset, tried) and recursiveMatch(repeat + 1, name, offset + tried, len - tried))
        return true;
      // _LOG_DEBUG("Failed at tried: " << tried);
      tried --;
    }

  return false;
}


} // namespace ndn

#endif // NDN_UTIL_REGEX_REGEX_REPEAT_MATCHER_HPP
