/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2014 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 * @author Jeff Thompson <jefft0@remap.ucla.edu>
 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
 */

#include "common.hpp"

#include "certificate.hpp"
#include "../util/time.hpp"
#include "cryptopp.hpp"
#include "../encoding/cryptopp/asn_ext.hpp"
#include "../encoding/buffer-stream.hpp"
#include "../util/concepts.hpp"

#include <boost/algorithm/string/split.hpp>

namespace ndn {

BOOST_CONCEPT_ASSERT((WireEncodable<Certificate>));
BOOST_CONCEPT_ASSERT((WireDecodable<Certificate>));
static_assert(std::is_base_of<tlv::Error, Certificate::Error>::value,
              "Certificate::Error must inherit from tlv::Error");

Certificate::Certificate()
  : m_notBefore(time::system_clock::TimePoint::max())
  , m_notAfter(time::system_clock::TimePoint::min())
{
}

Certificate::Certificate(const Data& data)
  // Use the copy constructor.  It clones the signature object.
  : Data(data)
{
  decode();
}

Certificate::Certificate(const Block& block)
  : Data(block)
{
  decode();
}

Certificate::~Certificate()
{
}

void
Certificate::wireDecode(const Block& wire)
{
  Data::wireDecode(wire);
  decode();
}

bool
Certificate::isTooEarly()
{
  if (time::system_clock::now() < m_notBefore)
    return true;
  else
    return false;
}

bool
Certificate::isTooLate()
{
  if (time::system_clock::now() > m_notAfter)
    return true;
  else
    return false;
}

void
Certificate::encode()
{
  // Name
  //    <key_name>/ID-CERT/<id#>
  // Content
  // DER encoded idCert:
  //
  //    idCert ::= SEQUENCE {
  //        validity            Validity,
  //        subject             Name,
  //        subjectPubKeyInfo   SubjectPublicKeyInfo,
  //        extension           Extensions OPTIONAL   }
  //
  //    Validity ::= SEQUENCE {
  //        notBefore           Time,
  //        notAfter            Time   }
  //
  //    Name ::= CHOICE {
  //        RDNSequence   }
  //
  //    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  //
  //    RelativeDistinguishedName ::=
  //        SET OF AttributeTypeAndValue
  //
  //    SubjectPublicKeyInfo ::= SEQUENCE {
  //        algorithm           AlgorithmIdentifier
  //        keybits             BIT STRING   }
  //
  //    Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  //
  // (see http://www.ietf.org/rfc/rfc3280.txt for more detail)
  //
  // KeyLocator
  //    issuer’s certificate name
  // Signature

  using namespace CryptoPP;

  OBufferStream os;
  CryptoPP::FileSink sink(os);

  // idCert ::= SEQUENCE {
  //     validity            Validity,
  //     subject             Name,
  //     subjectPubKeyInfo   SubjectPublicKeyInfo,
  //     extension           Extensions OPTIONAL   }
  DERSequenceEncoder idCert(sink);
  {
    // Validity ::= SEQUENCE {
    //       notBefore           Time,
    //       notAfter            Time   }
    DERSequenceEncoder validity(idCert);
    {
      DEREncodeGeneralTime(validity, m_notBefore);
      DEREncodeGeneralTime(validity, m_notAfter);
    }
    validity.MessageEnd();

    // Name ::= CHOICE {
    //     RDNSequence   }
    //
    // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    DERSequenceEncoder name(idCert);
    {
      for (SubjectDescriptionList::iterator it = m_subjectDescriptionList.begin();
           it != m_subjectDescriptionList.end(); ++it)
        {
          it->encode(name);
        }
    }
    name.MessageEnd();

    // SubjectPublicKeyInfo
    m_key.encode(idCert);

    // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
    //
    // Extension ::= SEQUENCE {
    //        extnID      OBJECT IDENTIFIER,
    //        critical    BOOLEAN DEFAULT FALSE,
    //        extnValue   OCTET STRING  }
    if (!m_extensionList.empty())
      {
        DERSequenceEncoder extensions(idCert);
        {
          for (ExtensionList::iterator it = m_extensionList.begin();
               it != m_extensionList.end(); ++it)
            {
              it->encode(extensions);
            }
        }
        extensions.MessageEnd();
      }
  }

  idCert.MessageEnd();

  setContent(os.buf());
  setContentType(tlv::ContentType_Key);
}

void
Certificate::decode()
{
  using namespace CryptoPP;

  try {
    OBufferStream os;
    StringSource source(getContent().value(), getContent().value_size(), true);

    // idCert ::= SEQUENCE {
    //     validity            Validity,
    //     subject             Name,
    //     subjectPubKeyInfo   SubjectPublicKeyInfo,
    //     extension           Extensions OPTIONAL   }
    BERSequenceDecoder idCert(source);
    {
      // Validity ::= SEQUENCE {
      //       notBefore           Time,
      //       notAfter            Time   }
      BERSequenceDecoder validity(idCert);
      {
        BERDecodeTime(validity, m_notBefore);
        BERDecodeTime(validity, m_notAfter);
      }
      validity.MessageEnd();

      // Name ::= CHOICE {
      //     RDNSequence   }
      //
      // RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
      m_subjectDescriptionList.clear();
      BERSequenceDecoder name(idCert);
      {
        while (!name.EndReached())
          {
            m_subjectDescriptionList.push_back(CertificateSubjectDescription(name));
          }
      }
      name.MessageEnd();

      // SubjectPublicKeyInfo ::= SEQUENCE {
      //     algorithm           AlgorithmIdentifier
      //     keybits             BIT STRING   }
      m_key.decode(idCert);

      // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
      //
      // Extension ::= SEQUENCE {
      //        extnID      OBJECT IDENTIFIER,
      //        critical    BOOLEAN DEFAULT FALSE,
      //        extnValue   OCTET STRING  }
      m_extensionList.clear();
      if (!idCert.EndReached())
        {
          BERSequenceDecoder extensions(idCert);
          {
            while (!extensions.EndReached())
              {
                m_extensionList.push_back(CertificateExtension(extensions));
              }
          }
          extensions.MessageEnd();
        }
    }

    idCert.MessageEnd();
  }
  catch (CryptoPP::BERDecodeErr&) {
    throw Error("Certificate Decoding Error");
  }
}

/**
 * @brief Output to stream with specified indent
 *
 * Based on http://stackoverflow.com/a/2212940/2150331
 */
class IndentedStream : public std::ostream
{
public:
  IndentedStream(std::ostream& os, const std::string& indent = "")
    : std::ostream(&m_buffer)
    , m_buffer(os, indent)
  {
  }

  ~IndentedStream()
  {
    flush();
  }

private:
  // Write a stream buffer that prefixes each line with Plop
  class StreamBuf : public std::stringbuf
  {
  public:
    StreamBuf(std::ostream& os, const std::string& indent)
      : m_output(os)
      , m_indent(indent)
    {
    }

    virtual int
    sync()
    {
      typedef boost::iterator_range<std::string::const_iterator> StringView;

      const std::string& output = str();
      std::vector<StringView> splitOutput;
      boost::split(splitOutput, output, [] (const char& ch) { return ch == '\n'; });

      if (!splitOutput.empty() && splitOutput.back().empty()) {
        splitOutput.pop_back();
      }
      for (const StringView& line : splitOutput) {
        m_output << m_indent << line << "\n";
      }
      return 0; // success
    }
  private:
    std::ostream& m_output;
    std::string m_indent;
  };

  StreamBuf m_buffer;
};

void
Certificate::printCertificate(std::ostream& oss, const std::string& indent) const
{
  IndentedStream os(oss, indent);

  os << "Certificate name:\n";
  os << "  " << getName() << "\n";
  os << "Validity:\n";
  {
    os << "  NotBefore: " << time::toIsoString(m_notBefore) << "\n";
    os << "  NotAfter: "  << time::toIsoString(m_notAfter)  << "\n";
  }

  os << "Subject Description:\n";
  for (const auto& description : m_subjectDescriptionList)
    os << "  " << description.getOidString() << ": " << description.getValue() << "\n";

  os << "Public key bits: ";
  switch (m_key.getKeyType()) {
  case KEY_TYPE_RSA:
    os << "(RSA)";
    break;
  case KEY_TYPE_ECDSA:
    os << "(ECDSA)";
    break;
  default:
    os << "(Unknown key type)";
    break;
  }
  os << "\n";

  {
    IndentedStream os2(os, "  ");
    CryptoPP::Base64Encoder encoder(new CryptoPP::FileSink(os2), true, 64);
    m_key.encode(encoder);
  }

  os << "Signature Information:\n";
  {
    os << "  Signature Type: ";
    switch (getSignature().getType()) {
    case tlv::SignatureTypeValue::DigestSha256:
      os << "DigestSha256";
      break;
    case tlv::SignatureTypeValue::SignatureSha256WithRsa:
      os << "SignatureSha256WithRsa";
      break;
    case tlv::SignatureTypeValue::SignatureSha256WithEcdsa:
      os << "SignatureSha256WithEcdsa";
      break;
    default:
      os << "Unknown Signature Type";
    }
    os << "\n";

    if (getSignature().hasKeyLocator()) {
      const KeyLocator& keyLocator = getSignature().getKeyLocator();
      os << "  Key Locator: ";
      switch (keyLocator.getType()) {
      case KeyLocator::KeyLocator_Name:
        {
          const Name& signerName = keyLocator.getName();
          if (signerName.isPrefixOf(getName()))
            os << "(Self-Signed) " << keyLocator.getName();
          else
            os << "(Name) " << keyLocator.getName();
          break;
        }
      case KeyLocator::KeyLocator_KeyDigest:
        os << "(KeyDigest)";
        break;
      case KeyLocator::KeyLocator_None:
        os << "None";
        break;
      default:
        os << "Unknown";
      }
      os << "\n";
    }
  }
}

std::ostream&
operator<<(std::ostream& os, const Certificate& cert)
{
  cert.printCertificate(os);
  return os;
}


} // namespace ndn
