/* -*- 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_VALIDATOR_REGEX_HPP
#define NDN_VALIDATOR_REGEX_HPP

#include "validator.hpp"
#include "identity-certificate.hpp"
#include "sec-rule-relative.hpp"
#include "certificate-cache.hpp"
#include "../util/regex.hpp"

namespace ndn {

class ValidatorRegex : public Validator
{
public:
  struct Error : public Validator::Error { Error(const std::string &what) : Validator::Error(what) {} };

  static const shared_ptr<CertificateCache> DefaultCertificateCache;
  
  ValidatorRegex(shared_ptr<Face> face,
                 shared_ptr<CertificateCache> certificateCache = DefaultCertificateCache, 
                 const int stepLimit = 3);
  
  virtual 
  ~ValidatorRegex() {}
  
  /**
   * @brief Add a rule for data verification.
   *
   * @param policy The verification rule
   */
  inline void
  addDataVerificationRule (shared_ptr<SecRuleRelative> rule);
    
  /**
   * @brief Add a trust anchor
   *
   * @param certificate The trust anchor 
   */
  inline void 
  addTrustAnchor(shared_ptr<IdentityCertificate> certificate);

protected:
  virtual void
  checkPolicy (const shared_ptr<const Data>& data, 
               int stepCount, 
               const OnDataValidated &onValidated, 
               const OnDataValidationFailed &onValidationFailed,
               std::vector<shared_ptr<ValidationRequest> > &nextSteps);

  virtual void
  checkPolicy (const shared_ptr<const Interest>& interest, 
               int stepCount, 
               const OnInterestValidated &onValidated, 
               const OnInterestValidationFailed &onValidationFailed,
               std::vector<shared_ptr<ValidationRequest> > &nextSteps)
  { onValidationFailed(interest); }

  void
  onCertificateValidated(const shared_ptr<const Data> &signCertificate, 
                         const shared_ptr<const Data> &data, 
                         const OnDataValidated &onValidated, 
                         const OnDataValidationFailed &onValidationFailed);
  
  void
  onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate, 
                                const shared_ptr<const Data> &data, 
                                const OnDataValidationFailed &onValidationFailed);
  
protected:
  typedef std::vector< shared_ptr<SecRuleRelative> > RuleList;
  typedef std::vector< shared_ptr<Regex> > RegexList;

  int m_stepLimit;
  shared_ptr<CertificateCache> m_certificateCache;
  RuleList m_mustFailVerify;
  RuleList m_verifyPolicies;
  std::map<Name, shared_ptr<IdentityCertificate> > m_trustAnchors;
};

void 
ValidatorRegex::addDataVerificationRule (shared_ptr<SecRuleRelative> rule)
{ rule->isPositive() ? m_verifyPolicies.push_back(rule) : m_mustFailVerify.push_back(rule); }
      
void  
ValidatorRegex::addTrustAnchor(shared_ptr<IdentityCertificate> certificate)
{ m_trustAnchors[certificate->getName().getPrefix(-1)] = certificate; }

}//ndn

#endif
