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

#ifndef SYNC_INTRO_CERTIFICATE_H
#define SYNC_INTRO_CERTIFICATE_H

#include <ndn-cxx/security/identity-certificate.hpp>
#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>

namespace Sync {

class IntroCertificate : public ndn::Data
{
  /**
   * Naming convention of IntroCertificate:
   * /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
   * Content: introducee's identity certificate;
   * KeyLocator: introducer's identity certificate;
   */
public:
  struct Error : public ndn::Data::Error { Error(const std::string &what) : ndn::Data::Error(what) {} };

  IntroCertificate()
  {}

  /**
   * @brief Construct IntroCertificate from IdentityCertificate
   *
   * @param syncPrefix
   * @param introduceeCert
   * @param introducerName
   */
  IntroCertificate(const ndn::Name& syncPrefix,
                   const ndn::IdentityCertificate& introduceeCert,
                   const ndn::Name& introducerCertName); //without version number

  /**
   * @brief Construct IntroCertificate using a plain data.
   *
   * if data is not actually IntroCertificate, Error will be thrown out.
   *
   * @param data
   * @throws ndn::IntroCertificate::Error.
   */
  IntroCertificate(const ndn::Data& data);

  virtual
  ~IntroCertificate() {};

  const ndn::IdentityCertificate&
  getIntroduceeCert() const
  {
    return m_introduceeCert;
  }

  const ndn::Name&
  getIntroducerCertName() const
  {
    return m_introducerCertName;
  }

  const ndn::Name&
  getIntroduceeCertName() const
  {
    return m_introduceeCertName;
  }

private:
  ndn::Name m_syncPrefix;
  ndn::IdentityCertificate m_introduceeCert;
  ndn::Name m_introducerCertName;
  ndn::Name m_introduceeCertName;
};

inline
IntroCertificate::IntroCertificate(const ndn::Name& syncPrefix,
                                   const ndn::IdentityCertificate& introduceeCert,
                                   const ndn::Name& introducerCertName)
  : m_syncPrefix(syncPrefix)
  , m_introduceeCert(introduceeCert)
  , m_introducerCertName(introducerCertName)
  , m_introduceeCertName(introduceeCert.getName().getPrefix(-1))
{
  // Naming convention /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
  ndn::Name dataName = m_syncPrefix;
  dataName.append("CHRONOS-INTRO-CERT")
    .append(m_introduceeCertName.wireEncode())
    .append(m_introducerCertName.wireEncode())
    .appendVersion();

  setName(dataName);
  setContent(m_introduceeCert.wireEncode());
}

inline
IntroCertificate::IntroCertificate(const ndn::Data& data)
  : Data(data)
{
  // Naming convention /<sync_prefix>/CHRONOS-INTRO-CERT/introducee_certname/introducer_certname/version
  ndn::Name dataName = data.getName();

  if(dataName.size() < 4 || dataName.get(-4).toEscapedString() != "CHRONOS-INTRO-CERT")
    throw Error("Not a Sync::IntroCertificate");

  try
    {
      m_introduceeCert.wireDecode(data.getContent().blockFromValue());
      m_introducerCertName.wireDecode(dataName.get(-2).blockFromValue());
      m_introduceeCertName.wireDecode(dataName.get(-3).blockFromValue());
      m_syncPrefix = dataName.getPrefix(-4);
    }
  catch(ndn::IdentityCertificate::Error& e)
    {
      throw Error("Cannot decode introducee cert");
    }
  catch(ndn::Name::Error& e)
    {
      throw Error("Cannot decode name");
    }
  catch(ndn::Block::Error& e)
    {
      throw Error("Cannot decode block name");
    }

  if(m_introduceeCertName != m_introduceeCert.getName().getPrefix(-1))
    throw Error("Invalid Sync::IntroCertificate (inconsistent introducee name)");

  ndn::Name keyLocatorName;
  try
    {
      ndn::SignatureSha256WithRsa sig(data.getSignature());
      keyLocatorName = sig.getKeyLocator().getName();
    }
  catch(ndn::KeyLocator::Error& e)
    {
      throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#1)");
    }
  catch(ndn::SignatureSha256WithRsa::Error& e)
    {
      throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#2)");
    }

  if(m_introducerCertName != keyLocatorName)
    throw Error("Invalid Sync::IntroCertificate (inconsistent introducer name#3)");
}


} // namespace Sync

#endif //SYNC_INTRO_CERTIFICATE_H
