/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016 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>
 */

#ifndef NDN_SECURITY_VALIDATOR_HPP
#define NDN_SECURITY_VALIDATOR_HPP

#include "../face.hpp"
#include "signature-sha256-with-rsa.hpp"
#include "signature-sha256-with-ecdsa.hpp"
#include "digest-sha256.hpp"
#include "validation-request.hpp"
#include "v1/public-key.hpp"
#include "v1/identity-certificate.hpp"

namespace ndn {
namespace security {

/**
 * @brief provides the interfaces for packet validation.
 */
class Validator
{
public:
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

  /**
   * @brief Validator constructor
   *
   * @param face Pointer to face through which validator may retrieve certificates.
   *             Passing a null pointer implies the validator is in offline mode.
   *
   * @note Make sure the lifetime of the passed Face is longer than validator.
   */
  explicit
  Validator(Face* face = nullptr);

  /// @deprecated Use the constructor taking Face* as parameter.
  explicit
  Validator(Face& face);

  virtual
  ~Validator();

  /**
   * @brief Validate Data and call either onValidated or onValidationFailed.
   *
   * @param data The Data with the signature to check.
   * @param onValidated If the Data is validated, this calls onValidated(data).
   * @param onValidationFailed If validation fails, this calls onValidationFailed(data).
   */
  void
  validate(const Data& data,
           const OnDataValidated& onValidated,
           const OnDataValidationFailed& onValidationFailed)
  {
    validate(data, onValidated, onValidationFailed, 0);
  }

  /**
   * @brief Validate Interest and call either onValidated or onValidationFailed.
   *
   * @param interest The Interest with the signature to check.
   * @param onValidated If the Interest is validated, this calls onValidated(interest).
   * @param onValidationFailed If validation fails, this calls onValidationFailed(interest).
   */
  void
  validate(const Interest& interest,
           const OnInterestValidated& onValidated,
           const OnInterestValidationFailed& onValidationFailed)
  {
    validate(interest, onValidated, onValidationFailed, 0);
  }

  /*****************************************
   *      verifySignature method set       *
   *****************************************/

  /// @brief Verify the data using the publicKey.
  static bool
  verifySignature(const Data& data, const v1::PublicKey& publicKey);

  /**
   * @brief Verify the signed Interest using the publicKey.
   *
   * (Note the signature covers the first n-2 name components).
   */
  static bool
  verifySignature(const Interest& interest, const v1::PublicKey& publicKey);

  /// @brief Verify the blob using the publicKey against the signature.
  static bool
  verifySignature(const Buffer& blob, const Signature& sig, const v1::PublicKey& publicKey)
  {
    return verifySignature(blob.buf(), blob.size(), sig, publicKey);
  }

  /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
  static bool
  verifySignature(const Data& data,
                  const Signature& sig,
                  const v1::PublicKey& publicKey)
  {
    return verifySignature(data.wireEncode().value(),
                           data.wireEncode().value_size() - data.getSignature().getValue().size(),
                           sig, publicKey);
  }

  /** @brief Verify the interest using the publicKey against the SHA256-RSA signature.
   *
   * (Note the signature covers the first n-2 name components).
   */
  static bool
  verifySignature(const Interest& interest,
                  const Signature& sig,
                  const v1::PublicKey& publicKey)
  {
    if (interest.getName().size() < 2)
      return false;

    const Name& name = interest.getName();

    return verifySignature(name.wireEncode().value(),
                           name.wireEncode().value_size() - name[-1].size(),
                           sig, publicKey);
  }

  /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
  static bool
  verifySignature(const uint8_t* buf,
                  const size_t size,
                  const Signature& sig,
                  const v1::PublicKey& publicKey);


  /// @brief Verify the data against the SHA256 signature.
  static bool
  verifySignature(const Data& data, const DigestSha256& sig)
  {
    return verifySignature(data.wireEncode().value(),
                           data.wireEncode().value_size() -
                           data.getSignature().getValue().size(),
                           sig);
  }

  /** @brief Verify the interest against the SHA256 signature.
   *
   * (Note the signature covers the first n-2 name components).
   */
  static bool
  verifySignature(const Interest& interest, const DigestSha256& sig)
  {
    if (interest.getName().size() < 2)
      return false;

    const Name& name = interest.getName();

    return verifySignature(name.wireEncode().value(),
                           name.wireEncode().value_size() - name[-1].size(),
                           sig);
  }

  /// @brief Verify the blob against the SHA256 signature.
  static bool
  verifySignature(const Buffer& blob, const DigestSha256& sig)
  {
    return verifySignature (blob.buf(), blob.size(), sig);
  }

  /// @brief Verify the blob against the SHA256 signature.
  static bool
  verifySignature(const uint8_t* buf, const size_t size, const DigestSha256& sig);

protected:
  /**
   * @brief Check the Data against policy and return the next validation step if necessary.
   *
   * If there is no next validation step, that validation MUST have been done.
   * i.e., either onValidated or onValidationFailed callback is invoked.
   *
   * @param data               The Data to check.
   * @param nSteps             The number of validation steps that have been done.
   * @param onValidated        If the Data is validated, this calls onValidated(data)
   * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
   * @param nextSteps          On return, contains the next validation step
   */
  virtual void
  checkPolicy(const Data& data,
              int nSteps,
              const OnDataValidated& onValidated,
              const OnDataValidationFailed& onValidationFailed,
              std::vector<shared_ptr<ValidationRequest>>& nextSteps) = 0;

  /**
   * @brief Check the Interest against validation policy and return the next validation step
   *        if necessary.
   *
   * If there is no next validation step, that validation MUST have been done.
   * i.e., either onValidated or onValidationFailed callback is invoked.
   *
   * @param interest           The Interest to check.
   * @param nSteps             The number of validation steps that have been done.
   * @param onValidated        If the Interest is validated, this calls onValidated(data)
   * @param onValidationFailed If validation fails, this calls onValidationFailed(data)
   * @param nextSteps          On return, contains the next validation step
   */
  virtual void
  checkPolicy(const Interest& interest,
              int nSteps,
              const OnInterestValidated& onValidated,
              const OnInterestValidationFailed& onValidationFailed,
              std::vector<shared_ptr<ValidationRequest>>& nextSteps) = 0;

  typedef function<void(const std::string&)> OnFailure;

  /// @brief Process the received certificate.
  void
  onData(const Interest& interest,
         const Data& data,
         const shared_ptr<ValidationRequest>& nextStep);

  void
  validate(const Data& data,
           const OnDataValidated& onValidated,
           const OnDataValidationFailed& onValidationFailed,
           int nSteps);

  void
  validate(const Interest& interest,
           const OnInterestValidated& onValidated,
           const OnInterestValidationFailed& onValidationFailed,
           int nSteps);

  /// Hooks

  /**
   * @brief trigger before validating requested certificate.
   *
   * The Data:
   * - matches the interest in the validation-request.
   * - may be certificate or a data encapsulating certificate.
   *
   * This method returns a data (actually certificate) that is will be passed as Data into:
   * Validator::validate(const Data& data,
   *                     const OnDataValidated& onValidated,
   *                     const OnDataValidationFailed& onValidationFailed,
   *                     int nSteps);
   */
  virtual shared_ptr<const Data>
  preCertificateValidation(const Data& data)
  {
    return data.shared_from_this();
  }

  /**
   * @brief trigger when interest retrieves a Nack.
   *
   * Validator can decide how to handle a Nack, either call onFailure, or retry.
   *
   * @param interest The interest that retrieves a Nack.
   * @param nack The Nack that is retrieved.
   * @param nRemainingRetries The number of retries left.
   * @param onFailure Failure callback when there is no more retries remaining.
   * @param validationRequest The validationRequest containing the context of the interest.
   */
  virtual void
  onNack(const Interest& interest,
         const lp::Nack& nack,
         int nRemainingRetries,
         const OnFailure& onFailure,
         const shared_ptr<ValidationRequest>& validationRequest);

  /**
   * @brief trigger when interest for certificate times out.
   *
   * Validator can decide how to handle the timeout, either call onFailure, or retry.
   *
   * @param interest The interest that times out.
   * @param nRemainingRetries The number of retries left.
   * @param onFailure Failure callback when there is no more retries remaining.
   * @param validationRequest The validationRequest containing the context of the interest.
   */
  virtual void
  onTimeout(const Interest& interest,
            int nRemainingRetries,
            const OnFailure& onFailure,
            const shared_ptr<ValidationRequest>& validationRequest);

  /**
   * @brief trigger after checkPolicy is done.
   *
   * Validator can decide how to handle the set of validation requests according to
   * the trust model.
   *
   * @param nextSteps A set of validation request made by checkPolicy.
   * @param onFailure Failure callback when errors happen in processing nextSteps.
   */
  virtual void
  afterCheckPolicy(const std::vector<shared_ptr<ValidationRequest>>& nextSteps,
                   const OnFailure& onFailure);

protected:
  Face* m_face;
};

} // namespace security

using security::Validator;

} // namespace ndn

#endif // NDN_SECURITY_VALIDATOR_HPP
