/* -*- 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 "public-key.hpp"
#include "signature-sha256-with-rsa.hpp"
#include "signature-sha256-with-ecdsa.hpp"
#include "digest-sha256.hpp"
#include "validation-request.hpp"
#include "identity-certificate.hpp"

namespace ndn {

/**
 * @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 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 PublicKey& publicKey);

  /// @brief Verify the blob using the publicKey against the signature.
  static bool
  verifySignature(const Buffer& blob, const Signature& sig, const 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 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 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 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 ndn

#endif // NDN_SECURITY_VALIDATOR_HPP
