/* -*- 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
