/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2012-2014 University of California, Los Angeles
 *
 * This file is part of ChronoSync, synchronization library for distributed realtime
 * applications for NDN.
 *
 * ChronoSync is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * ChronoSync 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * ChronoSync, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/web/index.html>
 */

#include "sync-validator.h"
#include "sync-logging.h"
#include <ndn-cxx/security/certificate-cache-ttl.hpp>
#include <queue>

using namespace ndn;

INIT_LOGGER ("SyncValidator")

namespace Sync {

using ndn::shared_ptr;

const shared_ptr<CertificateCache> SyncValidator::DefaultCertificateCache = shared_ptr<CertificateCache>();
const shared_ptr<SecRuleRelative> SyncValidator::DefaultDataRule = shared_ptr<SecRuleRelative>();

SyncValidator::SyncValidator(const Name& prefix,
                             const IdentityCertificate& anchor,
                             Face& face,
                             const PublishCertCallback& publishCertCallback,
                             shared_ptr<SecRuleRelative> rule,
                             shared_ptr<CertificateCache> certificateCache,
                             const int stepLimit)
  : Validator(face)
  , m_prefix(prefix)
  , m_anchor(anchor)
  , m_stepLimit(stepLimit)
  , m_certificateCache(certificateCache)
  , m_publishCertCallback(publishCertCallback)
  , m_dataRule(rule)
{
  if(!static_cast<bool>(m_certificateCache))
    m_certificateCache = make_shared<CertificateCacheTtl>(boost::ref(m_face.getIoService()));

  Name certPrefix = prefix;
  certPrefix.append("CHRONOS-INTRO-CERT");
  m_prefixId = m_face.setInterestFilter(certPrefix,
                                         bind(&SyncValidator::onCertInterest, this, _1, _2),
                                         bind(&SyncValidator::onCertRegisterFailed, this, _1, _2));

  setAnchor(m_anchor);
}

void
SyncValidator::deriveTrustNodes()
{
  std::queue<Name> nodeQueue;

  // Clear existing trust nodes.
  m_trustedNodes.clear();

  // Add the trust anchor.
  IntroNode origin(m_anchor);
  m_trustedNodes[origin.name()] = m_anchor.getPublicKeyInfo();
  nodeQueue.push(origin.name());

  // BFS trusted nodes.
  while(!nodeQueue.empty())
    {
      // Get next trusted node to process.
      Nodes::const_iterator it = m_introNodes.find(nodeQueue.front());
      const PublicKey& publicKey = m_trustedNodes[nodeQueue.front()];

      if(it != m_introNodes.end())
        {
          // If the trusted node exists in the graph.
          IntroNode::const_iterator eeIt = it->second.introduceeBegin();
          IntroNode::const_iterator eeEnd = it->second.introduceeEnd();
          for(; eeIt != eeEnd; eeIt++)
            {
              // Check the nodes introduced by the trusted node.
              Edges::const_iterator edgeIt = m_introCerts.find(*eeIt);
              if(edgeIt != m_introCerts.end()
                 && m_trustedNodes.find(edgeIt->second.getIntroduceeCertName()) == m_trustedNodes.end()
                 && verifySignature(edgeIt->second, publicKey))
                {
                  // If the introduced node can be validated, add it into trusted node set and the node queue.
                  m_trustedNodes[edgeIt->second.getIntroduceeCertName()] = edgeIt->second.getIntroduceeCert().getPublicKeyInfo();
                  nodeQueue.push(edgeIt->second.getIntroduceeCertName());
                }
            }
        }
      nodeQueue.pop();
    }
}

void
SyncValidator::checkPolicy (const Data& data,
                            int stepCount,
                            const OnDataValidated& onValidated,
                            const OnDataValidationFailed& onValidationFailed,
                            std::vector<shared_ptr<ValidationRequest> >& nextSteps)
{
  if(m_stepLimit == stepCount)
    return onValidationFailed(data.shared_from_this(),
                              "Maximum steps of validation reached: " + data.getName().toUri());

  if(m_prefix.isPrefixOf(data.getName()) || (static_cast<bool>(m_dataRule) && m_dataRule->satisfy(data)))
    {
      try
        {
          SignatureSha256WithRsa sig(data.getSignature());
          Name keyLocatorName = sig.getKeyLocator().getName();

          TrustNodes::const_iterator it = m_trustedNodes.find(keyLocatorName);
          if(m_trustedNodes.end() != it)
            {
              if(verifySignature(data, sig, it->second))
                return onValidated(data.shared_from_this());
              else
                return onValidationFailed(data.shared_from_this(),
                                          "Cannot verify signature: " + data.getName().toUri());
            }
          else
            {
              _LOG_DEBUG("I am: " << m_anchor.getName().get(0).toUri() << " for " << data.getName());

              Name interestName = m_prefix;
              interestName.append("CHRONOS-INTRO-CERT").append(keyLocatorName.wireEncode());
              Interest interest(interestName);
              interest.setInterestLifetime(time::milliseconds(500));

              OnDataValidated onKeyValidated = bind(&SyncValidator::onCertificateValidated, this,
                                                    _1, data.shared_from_this(), onValidated, onValidationFailed);

              OnDataValidationFailed onKeyValidationFailed = bind(&SyncValidator::onCertificateValidationFailed, this,
                                                                  _1, _2, data.shared_from_this(), onValidationFailed);

              shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest,
                                                                                      onKeyValidated,
                                                                                      onKeyValidationFailed,
                                                                                      1,
                                                                                      stepCount + 1);
              nextSteps.push_back(nextStep);

              return;
            }
        }
      catch(SignatureSha256WithRsa::Error& e)
        {
          return onValidationFailed(data.shared_from_this(),
                                    "Not SignatureSha256WithRsa signature: " + std::string(e.what()));
        }
      catch(KeyLocator::Error& e)
        {
          return onValidationFailed(data.shared_from_this(),
                                    "Key Locator is not a name: " + data.getName().toUri());
        }
    }
  else
    return onValidationFailed(data.shared_from_this(),
                              "No rule or rule is not satisfied: " + data.getName().toUri());
}

void
SyncValidator::checkPolicy (const Interest& interest,
                            int stepCount,
                            const OnInterestValidated& onValidated,
                            const OnInterestValidationFailed& onValidationFailed,
                            std::vector<shared_ptr<ValidationRequest> >& nextSteps)
{
  onValidationFailed(interest.shared_from_this(),  "No policy for signed interest checking");
}

void
SyncValidator::onCertificateValidated(const shared_ptr<const Data>& signCertificate,
                                      const shared_ptr<const Data>& data,
                                      const OnDataValidated& onValidated,
                                      const OnDataValidationFailed& onValidationFailed)
{
  try
    {
      IntroCertificate introCert(*signCertificate);
      addParticipant(introCert);

      if(verifySignature(*data, introCert.getIntroduceeCert().getPublicKeyInfo()))
        return onValidated(data);
      else
        return onValidationFailed(data,
                                  "Cannot verify signature: " + data->getName().toUri());
    }
  catch(IntroCertificate::Error& e)
    {
      return onValidationFailed(data,
                                "Intro cert decoding error: " + std::string(e.what()));
    }
}

void
SyncValidator::onCertificateValidationFailed(const shared_ptr<const Data>& signCertificate,
                                             const std::string& failureInfo,
                                             const shared_ptr<const Data>& data,
                                             const OnDataValidationFailed& onValidationFailed)
{
  onValidationFailed(data, failureInfo);
}

void
SyncValidator::onCertInterest(const Name& prefix, const Interest& interest)
{
  Name name = interest.getName();
  Edges::const_iterator it = m_introCerts.begin();
  for(; it != m_introCerts.end(); it++)
    {
      if(name.isPrefixOf(it->first))
        {
          m_face.put(it->second);
          return;
        }
    }
}

void
SyncValidator::onCertRegisterFailed(const Name& prefix, const std::string& msg)
{
  _LOG_DEBUG("SyncValidator::onCertRegisterFailed: " << msg);
}

} // namespace Sync
