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

#ifndef SYNC_VALIDATOR_H
#define SYNC_VALIDATOR_H

#include "sync-intro-certificate.h"
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/sec-rule-relative.hpp>
#include <ndn-cxx/security/certificate-cache.hpp>
#include <map>

namespace Sync {

class SyncValidator : public ndn::Validator
{
public:
  typedef ndn::function< void (const uint8_t*, size_t, int) > PublishCertCallback;

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

  static const ndn::shared_ptr<ndn::CertificateCache> DefaultCertificateCache;
  static const ndn::shared_ptr<ndn::SecRuleRelative> DefaultDataRule;

  SyncValidator(const ndn::Name& prefix,
                const ndn::IdentityCertificate& anchor,
                ndn::Face& face,
                const PublishCertCallback& publishCertCallback,
                ndn::shared_ptr<ndn::SecRuleRelative> rule = DefaultDataRule,
                ndn::shared_ptr<ndn::CertificateCache> certificateCache = DefaultCertificateCache,
                const int stepLimit = 10);

  virtual
  ~SyncValidator()
  {
    m_face.unsetInterestFilter(m_prefixId);
  }

  /**
   * @brief Set the trust anchor
   *
   * The anchor should be the participant's own certificate.
   * This anchor node is the origin of the derived trust graph.
   * Once the new anchor is set, derive the TrustNode set.
   *
   * @param anchor.
   */
  inline void
  setAnchor(const ndn::IdentityCertificate& anchor);

  /**
   * @brief Add a node into the trust graph.
   *
   * The method also create an edge from trust anchor to the node.
   *
   * @param introducee.
   * @return IntroCertificate for the introducee.
   */
  inline ndn::shared_ptr<const IntroCertificate>
  addParticipant(const ndn::IdentityCertificate& introducee);

  /**
   * @brief Add an edge into the trust graph.
   *
   * Create nodes if it is one of the edge's ends and does not exist in the graph.
   *
   * @param introCert.
   */
  inline void
  addParticipant(const IntroCertificate& introCert);

  inline void
  getIntroCertNames(std::vector<ndn::Name>& list);

  inline const IntroCertificate&
  getIntroCertificate(const ndn::Name& name);

#ifdef _TEST
  bool
  canTrust(const ndn::Name& certName)
  {
    return (m_trustedNodes.find(certName.getPrefix(-1)) != m_trustedNodes.end());
  }
#endif //_DEBUG

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

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


  void
  onCertificateValidated(const ndn::shared_ptr<const ndn::Data>& signCertificate,
                         const ndn::shared_ptr<const ndn::Data>& data,
                         const ndn::OnDataValidated& onValidated,
                         const ndn::OnDataValidationFailed& onValidationFailed);

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

  void
  onCertInterest (const ndn::Name& prefix, const ndn::Interest& interest);

  void
  onCertRegisterFailed(const ndn::Name& prefix, const std::string& msg);

private:
  class IntroNode;

  // Syncprefix
  ndn::Name m_prefix;

  // The map
  typedef std::map<const ndn::Name, IntroNode> Nodes;
  typedef std::map<const ndn::Name, IntroCertificate> Edges;
  Nodes m_introNodes;
  Edges m_introCerts;

  // The derived trust info
  typedef std::map<const ndn::Name, ndn::PublicKey> TrustNodes;
  ndn::IdentityCertificate m_anchor;
  TrustNodes m_trustedNodes;

  // others
  int m_stepLimit;
  ndn::shared_ptr<ndn::CertificateCache> m_certificateCache;
  ndn::KeyChain m_keychain;
  const ndn::RegisteredPrefixId* m_prefixId;
  PublishCertCallback m_publishCertCallback;
  ndn::shared_ptr<ndn::SecRuleRelative> m_dataRule;

  class IntroNode
  {
  public:
    typedef std::vector<ndn::Name>::const_iterator const_iterator;

    IntroNode()
    {}

    IntroNode(const ndn::IdentityCertificate& idCert)
      : m_nodeName(idCert.getName().getPrefix(-1))
    {}

    IntroNode(const IntroCertificate& introCert, bool isIntroducer)
    {
      if(isIntroducer)
        {
          m_nodeName = introCert.getIntroducerCertName();
          m_introduceeCerts.push_back(introCert.getName());
        }
      else
        {
          m_nodeName = introCert.getIntroduceeCertName();
          m_introducerCerts.push_back(introCert.getName());
        }
    }

    ~IntroNode()
    {}

    const ndn::Name&
    name() const
    {
      return m_nodeName;
    }

    const_iterator
    introducerBegin() const
    {
      return m_introducerCerts.begin();
    }

    const_iterator
    introducerEnd() const
    {
      return m_introducerCerts.end();
    }

    const_iterator
    introduceeBegin() const
    {
      return m_introduceeCerts.begin();
    }

    const_iterator
    introduceeEnd() const
    {
      return m_introduceeCerts.end();
    }

    void
    addIntroCertAsIntroducer(const ndn::Name& introCertName)
    {
      if(std::find(m_introduceeCerts.begin(), m_introduceeCerts.end(), introCertName) == m_introduceeCerts.end())
        m_introduceeCerts.push_back(introCertName);
    }

    void
    addIntroCertAsIntroducee(const ndn::Name& introCertName)
    {
      if(std::find(m_introducerCerts.begin(), m_introducerCerts.end(), introCertName) == m_introducerCerts.end())
        m_introducerCerts.push_back(introCertName);
    }

  private:
    ndn::Name m_nodeName;
    std::vector<ndn::Name> m_introducerCerts;
    std::vector<ndn::Name> m_introduceeCerts;
  };

};

inline void
SyncValidator::setAnchor(const ndn::IdentityCertificate& anchor)
{
  m_anchor = anchor;

  // Add anchor into trust graph if it does not exist.
  IntroNode origin(m_anchor);
  Nodes::const_iterator nodeIt = m_introNodes.find(origin.name());
  if(nodeIt == m_introNodes.end())
    m_introNodes[origin.name()] = origin;

  deriveTrustNodes();
}

inline void
SyncValidator::addParticipant(const IntroCertificate& introCert)
{
  // Check if the edge has been added before.
  ndn::Name certName = introCert.getName();
  Edges::const_iterator edgeIt = m_introCerts.find(certName);
  if(edgeIt != m_introCerts.end())
    return; // the edge has been added before.

  m_introCerts[certName] = introCert;

  // Check if the introducer has been added.
  Nodes::iterator nodeIt = m_introNodes.find(introCert.getIntroducerCertName());
  if(nodeIt == m_introNodes.end())
    {
      IntroNode node(introCert, true);
      m_introNodes[node.name()] = node;
    }
  else
    nodeIt->second.addIntroCertAsIntroducer(certName);

  // Check if the introducee has been added.
  nodeIt = m_introNodes.find(introCert.getIntroduceeCertName());
  if(nodeIt == m_introNodes.end())
    {
      IntroNode node(introCert, false);
      m_introNodes[node.name()] = node;
    }
  else
    nodeIt->second.addIntroCertAsIntroducee(certName);

  // Check if the introducer is one of the trusted nodes.
  TrustNodes::const_iterator trustNodeIt = m_trustedNodes.find(introCert.getIntroducerCertName());
  if(trustNodeIt != m_trustedNodes.end() && verifySignature(introCert, trustNodeIt->second))
    // If the introducee, add it into trusted node set.
    m_trustedNodes[introCert.getIntroduceeCertName()] = introCert.getIntroduceeCert().getPublicKeyInfo();
}

inline ndn::shared_ptr<const IntroCertificate>
SyncValidator::addParticipant(const ndn::IdentityCertificate& introducee)
{
  ndn::shared_ptr<IntroCertificate> introCert
    = ndn::shared_ptr<IntroCertificate>(new IntroCertificate(m_prefix, introducee, m_anchor.getName().getPrefix(-1)));

  m_keychain.sign(*introCert, m_anchor.getName());

  addParticipant(*introCert);

  // Publish certificate as normal data.
  ndn::Block block = introCert->wireEncode();
  m_publishCertCallback(block.wire(), block.size(), 1000);

  return introCert;
}

inline void
SyncValidator::getIntroCertNames(std::vector<ndn::Name>& list)
{
  Edges::const_iterator it = m_introCerts.begin();
  Edges::const_iterator end = m_introCerts.end();
  for(; it != end; it++)
    list.push_back(it->first);
}

inline const IntroCertificate&
SyncValidator::getIntroCertificate(const ndn::Name& name)
{
  Edges::const_iterator it = m_introCerts.find(name);
  if(it != m_introCerts.end())
    return it->second;
  else
    throw Error("No cert");
}

} // namespace Sync

#endif //SYNC_VALIDATOR_H
