/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2013 Regents of the University of California.
 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
 * See COPYING for copyright and distribution information.
 */

#ifndef NDN_VALIDATOR_HPP
#define NDN_VALIDATOR_HPP

#include "../data.hpp"
#include "../face.hpp"
#include "public-key.hpp"
#include "signature-sha256-with-rsa.hpp"
#include "validation-request.hpp"

namespace ndn {
/**
 * Validator is one of the main classes of the security library.
 *
 * The Validator class provides the interfaces for packet validation.
 */
class Validator {
public:
  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };

  static const shared_ptr<Face> DefaultFace;

  Validator (shared_ptr<Face> face = DefaultFace);

  /**
   * @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 the Data validation fails, this calls onValidationFailed(data).
   */
  void
  validate (const shared_ptr<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 the Interest validation fails, this calls onValidationFailed(interest).
   */
  void
  validate (const shared_ptr<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.
  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);

  /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
  static bool
  verifySignature (const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey);

  /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
  static bool
  verifySignature (const Buffer &blob, const SignatureSha256WithRsa &sig, const PublicKey &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 SignatureSha256WithRsa &sig, const PublicKey &publicKey);

protected:
  /**
   * @brief Check the Data 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 data The Data to check.
   * @param stepCount The number of validation steps that have been done, used to track the validation progress.
   * @param onDataValidated If the Data is validated, this calls onValidated(data).
   * @param onDataValidationFailed If the Data validation fails, this calls onValidationFailed(data).
   * @param nextSteps On return, contains the next validation step.
   */
  virtual void
  checkPolicy (const shared_ptr<const Data> &data, 
               int stepCount, 
               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 data The Interest to check.
   * @param stepCount The number of validation steps that have been done, used to track the validation progress.
   * @param OnInterestValidated If the Interest is validated, this calls onValidated(data).
   * @param OnInterestValidationFailed If the Interest validation fails, this calls onValidationFailed(data).
   * @return the indication of next validation step, null if there is no further step.
   */
  virtual void
  checkPolicy (const shared_ptr<const Interest> &interest, 
               int stepCount, 
               const OnInterestValidated &onValidated, 
               const OnInterestValidationFailed &onValidationFailed,
               std::vector<shared_ptr<ValidationRequest> > &nextSteps) = 0;

private:
  typedef function< void () > OnFailure;
  
  /// @brief Process the received certificate.
  void
  onData (const shared_ptr<const Interest> &interest, 
          const shared_ptr<const Data> &data, 
          shared_ptr<ValidationRequest> nextStep);
  
  /// @brief Re-express the interest if it times out.
  void
  onTimeout (const shared_ptr<const Interest> &interest, 
             int retry, 
             const OnFailure &onFailure, 
             shared_ptr<ValidationRequest> nextStep);

  void
  validate (const shared_ptr<const Data> &data, 
            const OnDataValidated &onValidated, 
            const OnDataValidationFailed &onValidationFailed, 
            int stepCount);

  void
  validate (const shared_ptr<const Interest> &interest, 
            const OnInterestValidated &onValidated, 
            const OnInterestValidationFailed &onValidationFailed, 
            int stepCount);

protected:
  shared_ptr<Face> m_face;
};

}

#endif
