/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2013, Regents of the University of California
 *                     Yingdi Yu
 *
 * BSD license, See the LICENSE file for more information
 *
 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
 */

#include "sync-intro-certificate.h"
#include "sync-logging.h"
#include <ndn-cpp/security/verifier.hpp>
#include <ndn-cpp/security/signature-sha256-with-rsa.hpp>

#include "sec-policy-sync.h"

using namespace ndn;
using namespace ndn::ptr_lib;
using namespace std;

INIT_LOGGER("SecPolicySync");

SecPolicySync::SecPolicySync(const Name& signingIdentity,
				     const Name& signingCertificateName,
				     const Name& syncPrefix,
                                     shared_ptr<Face> face,
                                     int stepLimit)
  : m_signingIdentity(signingIdentity)
  , m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
  , m_syncPrefix(syncPrefix)
  , m_stepLimit(stepLimit)
  , m_keyChain(new KeyChain())
{  
  Name wotPrefix = syncPrefix;
  wotPrefix.append("WOT");
  m_syncPrefixRegex = Regex::fromName(syncPrefix);
  m_wotPrefixRegex = Regex::fromName(wotPrefix);
  m_chatDataPolicy = make_shared<SecRuleIdentity>("^[^<%F0.>]*<%F0.>([^<chronos>]*)<chronos><>",
                                                  "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
                                                  "==", "\\1", "\\1", true);  
}
  
SecPolicySync::~SecPolicySync()
{}

bool 
SecPolicySync::skipVerifyAndTrust (const Data& data)
{ return false; }

bool
SecPolicySync::requireVerify (const Data& data)
{ return true; }

shared_ptr<ValidationRequest>
SecPolicySync::checkVerificationPolicy(const shared_ptr<Data>& data, 
					   int stepCount, 
					   const OnVerified& onVerified,
					   const OnVerifyFailed& onVerifyFailed)
{
  if(stepCount > m_stepLimit)
    {
      onVerifyFailed(data);
      return shared_ptr<ValidationRequest>();
    }

  try{
    SignatureSha256WithRsa sig(data->getSignature());

    const Name& keyLocatorName = sig.getKeyLocator().getName();
  
    // if data is intro cert
    if(m_wotPrefixRegex->match(data->getName()))
      {
        // _LOG_DEBUG("Intro Cert");
        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
        map<string, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName.toUri());
        if(m_trustedIntroducers.end() != it)
          {
            if(Verifier::verifySignature(*data, sig, it->second))
              onVerified(data);
            else
              onVerifyFailed(data);
            return shared_ptr<ValidationRequest>();
          }
        else
          return prepareRequest(keyName, true, data, stepCount, onVerified, onVerifyFailed);
      }

    // if data is sync data or chat data
    if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
      {
        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);

        map<string, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName.toUri());
        if(m_trustedIntroducers.end() != it)
          {
            if(Verifier::verifySignature(*data, sig, it->second))
              onVerified(data);
            else
              onVerifyFailed(data);
            return shared_ptr<ValidationRequest>();
          }

        it = m_trustedProducers.find(keyName.toUri());
        if(m_trustedProducers.end() != it)
          {
            if(Verifier::verifySignature(*data, sig, it->second))
              onVerified(data);
            else
              onVerifyFailed(data);
            return shared_ptr<ValidationRequest>();
          }

        return prepareRequest(keyName, false, data, stepCount, onVerified, onVerifyFailed);
      }
  }catch(SignatureSha256WithRsa::Error &e){
    _LOG_DEBUG("SecPolicySync Error: " << e.what());
    onVerifyFailed(data);
    return shared_ptr<ValidationRequest>();
  }catch(KeyLocator::Error &e){
    _LOG_DEBUG("SecPolicySync Error: " << e.what());
    onVerifyFailed(data);
    return shared_ptr<ValidationRequest>();
  }
    
  onVerifyFailed(data);
  return shared_ptr<ValidationRequest>();
}

bool 
SecPolicySync::checkSigningPolicy(const Name& dataName, 
				      const Name& certificateName)
{ 
  return true;
}
    
Name 
SecPolicySync::inferSigningIdentity(const ndn::Name& dataName)
{ return m_signingIdentity; }

void
SecPolicySync::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
{
  // _LOG_DEBUG("Add intro/producer: " << identityCertificate.getPublicKeyName());
  if(isIntroducer)
    m_trustedIntroducers.insert(pair <string, PublicKey > (identityCertificate.getPublicKeyName().toUri(),
                                                           identityCertificate.getPublicKeyInfo()));
  else
    m_trustedProducers.insert(pair <string, PublicKey > (identityCertificate.getPublicKeyName().toUri(),
                                                         identityCertificate.getPublicKeyInfo()));
}

void
SecPolicySync::addChatDataRule(const Name& prefix, 
                                   const IdentityCertificate& identityCertificate,
                                   bool isIntroducer)
{
  addTrustAnchor(identityCertificate, isIntroducer);
}


shared_ptr<const vector<Name> >
SecPolicySync::getAllIntroducerName()
{
  shared_ptr<vector<Name> > nameList = make_shared<vector<Name> >();
  
  map<string, PublicKey>::iterator it =  m_trustedIntroducers.begin();
  for(; it != m_trustedIntroducers.end(); it++)
    nameList->push_back(Name(it->first));
  
  return nameList;
}

shared_ptr<ValidationRequest>
SecPolicySync::prepareRequest(const Name& keyName, 
				  bool forIntroducer,
				  shared_ptr<Data> data,
				  const int & stepCount, 
				  const OnVerified& onVerified,
				  const OnVerifyFailed& onVerifyFailed)
{
  shared_ptr<Name> interestPrefixName = make_shared<Name>(m_syncPrefix);
  interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");

  shared_ptr<const vector<Name> > nameList = getAllIntroducerName();
  if(0 == nameList->size())
    {
      onVerifyFailed(data);
      return shared_ptr<ValidationRequest>();
    }

  Name interestName = *interestPrefixName;
  interestName.append(nameList->at(0));

  if(forIntroducer)
    interestName.append("INTRODUCER");

  shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(interestName);
  // _LOG_DEBUG("send interest for intro cert: " << interest->getName());

  OnVerified requestedCertVerifiedCallback = boost::bind(&SecPolicySync::onIntroCertVerified, 
                                                         this, 
                                                         _1,
                                                         forIntroducer, 
                                                         data,
                                                         onVerified,
                                                         onVerifyFailed);
                                                             
  OnVerifyFailed requestedCertUnverifiedCallback = boost::bind(&SecPolicySync::onIntroCertVerifyFailed, 
                                                               this, 
                                                               _1, 
                                                               interestPrefixName,
                                                               forIntroducer,
                                                               nameList,
                                                               1,
                                                               data,
                                                               onVerified,
                                                               onVerifyFailed);

    
  shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest, 
                                                                          requestedCertVerifiedCallback,
                                                                          requestedCertUnverifiedCallback,
                                                                          1,
                                                                          m_stepLimit-1);
  return nextStep;
}

void
SecPolicySync::OnIntroCertInterest(const shared_ptr<const Name>& prefix, 
                                       const shared_ptr<const ndn::Interest>& interest, 
                                       Transport& transport, 
                                       uint64_t registeredPrefixId)
{
  map<string, Data>::const_iterator it = m_introCert.find(prefix->toUri());

  if(m_introCert.end() != it)
    m_face->put(it->second);
}

void
SecPolicySync::OnIntroCertRegisterFailed(const shared_ptr<const Name>& prefix)
{
}

void
SecPolicySync::onIntroCertVerified(const shared_ptr<Data>& introCertificateData,
				       bool forIntroducer,
				       shared_ptr<Data> originalData,
				       const OnVerified& onVerified,
				       const OnVerifyFailed& onVerifyFailed)
{
  shared_ptr<SyncIntroCertificate> introCertificate = make_shared<SyncIntroCertificate>(*introCertificateData);
  if(forIntroducer)
    {
      m_trustedIntroducers.insert(pair <string, PublicKey > (introCertificate->getPublicKeyName().toUri(),
                                                             introCertificate->getPublicKeyInfo()));
      SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
                                                introCertificate->getPublicKeyName(),
                                                m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
                                                introCertificate->getNotBefore(),
                                                introCertificate->getNotAfter(),
                                                introCertificate->getPublicKeyInfo(),
                                                SyncIntroCertificate::INTRODUCER);

      Name certName = m_keyChain->getDefaultCertificateNameForIdentity(m_signingIdentity);
      _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
      m_keyChain->sign(syncIntroCertificate, certName);

      m_face->put(syncIntroCertificate);

      // Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);

      // map<string, Data>::const_iterator it = m_introCert.find(prefix.toEscapedString());
      // if(m_introCert.end() != it)
      //   {
      //     it->second = syncIntroCertificate;
      //   }
      // else
      //   {         
      //     m_introCert.insert(pair <string, Data> (prefix.toEscapedString(), syncIntroCertificate));
      //     m_face->registerPrefix(prefix, 
      //                           boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4), 
      //                           boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
      //   }
    }
  else
    {
      m_trustedProducers.insert(pair <string, PublicKey > (introCertificate->getPublicKeyName().toUri(), 
                                                           introCertificate->getPublicKeyInfo()));
      SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
                                                introCertificate->getPublicKeyName(),
                                                m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
                                                introCertificate->getNotBefore(),
                                                introCertificate->getNotAfter(),
                                                introCertificate->getPublicKeyInfo(),
                                                SyncIntroCertificate::PRODUCER);

      Name certName = m_keyChain->getDefaultCertificateNameForIdentity(m_signingIdentity);
      _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
      m_keyChain->sign(syncIntroCertificate, certName);
      
      m_face->put(syncIntroCertificate);

      // Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);

      // map<string, Data>::const_iterator it = m_introCert.find(prefix.toEscapedString());
      // if(m_introCert.end() != it)
      //   {
      //     it->second = syncIntroCertificate;
      //   }
      // else
      //   {
      //     m_introCert.insert(pair <string, Data> (prefix.toEscapedString(), syncIntroCertificate));
      //     m_face->registerPrefix(prefix, 
      //                           boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4), 
      //                           boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
      //   }
    }

  try{
    SignatureSha256WithRsa sig(originalData->getSignature());
    if(Verifier::verifySignature(*originalData, sig, introCertificate->getPublicKeyInfo()))      
      onVerified(originalData);    
    else
      onVerifyFailed(originalData);
  }catch(SignatureSha256WithRsa::Error &e){
    onVerifyFailed(originalData);
  }catch(KeyLocator::Error &e){
    onVerifyFailed(originalData);
  }
}

void 
SecPolicySync::onIntroCertVerifyFailed(const shared_ptr<Data>& introCertificateData,
                                           shared_ptr<Name> interestPrefixName,
                                           bool forIntroducer,
                                           shared_ptr<const vector<Name> > introNameList,
                                           int nextIntroducerIndex,
                                           shared_ptr<Data> originalData,
                                           const OnVerified& onVerified,
                                           const OnVerifyFailed& onVerifyFailed)
{
  Name interestName = *interestPrefixName;
  if(nextIntroducerIndex < introNameList->size())
    interestName.append(introNameList->at(nextIntroducerIndex));
  else
    onVerifyFailed(originalData);

  if(forIntroducer)
    interestName.append("INTRODUCER");
  
  shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(interestName);

  OnVerified onRecursiveVerified = boost::bind(&SecPolicySync::onIntroCertVerified, 
                                      this, 
                                      _1,
                                      forIntroducer, 
                                      originalData,
                                      onVerified,
                                      onVerifyFailed);

  OnVerifyFailed onRecursiveVerifyFailed = boost::bind(&SecPolicySync::onIntroCertVerifyFailed, 
                                              this, 
                                              _1,
                                              interestPrefixName,
                                              forIntroducer,
                                              introNameList,
                                              nextIntroducerIndex + 1,
                                              originalData, 
                                              onVerified,
                                              onVerifyFailed);
        
  m_face->expressInterest(*interest, 
                          boost::bind(&SecPolicySync::onIntroCertData,
                                      this,
                                      _1,
                                      _2,     
                                      m_stepLimit-1,
                                      onRecursiveVerified,
                                      onRecursiveVerifyFailed,
                                      originalData,
                                      onVerifyFailed),
                          boost::bind(&SecPolicySync::onIntroCertTimeout, 
                                      this,
                                      _1,
                                      1,
                                      m_stepLimit-1,
                                      onRecursiveVerified,
                                      onRecursiveVerifyFailed,
                                      originalData,
                                      onVerifyFailed));
}

void
SecPolicySync::onIntroCertData(const shared_ptr<const ndn::Interest> &interest,
                                   const shared_ptr<Data>& introCertificateData,
                                   int stepCount,
                                   const OnVerified& onRecursiveVerified,
                                   const OnVerifyFailed& onRecursiveVerifyFailed,
                                   shared_ptr<Data> originalData,
                                   const OnVerifyFailed& onVerifyFailed)
{
  shared_ptr<ValidationRequest> nextStep = checkVerificationPolicy(introCertificateData, stepCount, onRecursiveVerified, onRecursiveVerifyFailed);
  if (nextStep)
    m_face->expressInterest
      (*nextStep->interest_, 
       boost::bind(&SecPolicySync::onIntroCertData, 
                   this, 
                   _1, 
                   _2,
                   nextStep->stepCount_,
                   nextStep->onVerified_, 
                   nextStep->onVerifyFailed_,
                   introCertificateData,
                   onRecursiveVerifyFailed), 
       boost::bind(&SecPolicySync::onIntroCertTimeout, 
                   this, 
                   _1, 
                   nextStep->retry_, 
                   nextStep->stepCount_, 
                   nextStep->onVerified_, 
                   nextStep->onVerifyFailed_,
                   introCertificateData,
                   onRecursiveVerifyFailed));
}

void
SecPolicySync::onIntroCertTimeout(const shared_ptr<const ndn::Interest>& interest, 
				      int retry, 
                                      int stepCount,
                                      const OnVerified& onRecursiveVerified,
                                      const OnVerifyFailed& onRecursiveVerifyFailed,
                                      shared_ptr<Data> originalData,
                                      const OnVerifyFailed& onVerifyFailed)
{
  if(retry > 0)
    {
      m_face->expressInterest(*interest, 
                              boost::bind(&SecPolicySync::onIntroCertData, 
                                          this,
                                          _1,
                                          _2,
                                          stepCount,
                                          onRecursiveVerified,
                                          onRecursiveVerifyFailed,
                                          originalData,
                                          onVerifyFailed),
                              boost::bind(&SecPolicySync::onIntroCertTimeout, 
                                          this,
                                          _1,
                                          retry - 1,
                                          stepCount,
                                          onRecursiveVerified,
                                          onRecursiveVerifyFailed,
                                          originalData,
                                          onVerifyFailed));
    }
  else
    onVerifyFailed(originalData);
}
