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

#ifndef NDN_MGMT_DISPATCHER_HPP
#define NDN_MGMT_DISPATCHER_HPP

#include "../face.hpp"
#include "../security/key-chain.hpp"
#include "../encoding/block.hpp"
#include "../util/in-memory-storage-fifo.hpp"
#include "control-response.hpp"
#include "control-parameters.hpp"
#include "status-dataset-context.hpp"

#include <unordered_map>

namespace ndn {
namespace mgmt {

// ---- AUTHORIZATION ----

/** \brief a function to be called if authorization is successful
 *  \param requester a string that indicates the requester, whose semantics is determined by
 *                   the Authorization function; this value is intended for logging only,
 *                   and should not affect how the request is processed
 */
typedef std::function<void(const std::string& requester)> AcceptContinuation;

/** \brief indicate how to reply in case authorization is rejected
 */
enum class RejectReply {
  /** \brief do not reply
   */
  SILENT,
  /** \brief reply with a ControlResponse where StatusCode is 403
   */
  STATUS403
};

/** \brief a function to be called if authorization is rejected
 */
typedef std::function<void(RejectReply act)> RejectContinuation;

/** \brief a function that performs authorization
 *  \param prefix top-level prefix, e.g., "/localhost/nfd";
 *                This argument can be inspected to allow Interests only under a subset of
 *                top-level prefixes (e.g., allow "/localhost/nfd" only),
 *                or to use different trust model regarding to the prefix.
 *  \param interest incoming Interest
 *  \param params parsed ControlParameters for ControlCommand, otherwise nullptr;
 *                This is guaranteed to be not-null and have correct type for the command,
 *                but may not be valid (e.g., can have missing fields).
 *
 *  Either accept or reject must be called after authorization completes.
 */
typedef std::function<void(const Name& prefix, const Interest& interest,
                           const ControlParameters* params,
                           const AcceptContinuation& accept,
                           const RejectContinuation& reject)> Authorization;

/** \return an Authorization that accepts all Interests, with empty string as requester
 */
Authorization
makeAcceptAllAuthorization();

// ---- CONTROL COMMAND ----

/** \brief a function to validate input ControlParameters
 *  \param params parsed ControlParameters;
 *                This is guaranteed to have correct type for the command.
 */
typedef std::function<bool(const ControlParameters& params)> ValidateParameters;

/** \brief a function to be called after ControlCommandHandler completes
 *  \param resp the response to be sent to requester
 */
typedef std::function<void(const ControlResponse& resp)> CommandContinuation;

/** \brief a function to handle an authorized ControlCommand
 *  \param prefix top-level prefix, e.g., "/localhost/nfd";
 *  \param interest incoming Interest
 *  \param params parsed ControlParameters;
 *                This is guaranteed to have correct type for the command,
 *                and is valid (e.g., has all required fields).
 */
typedef std::function<void(const Name& prefix, const Interest& interest,
                           const ControlParameters& params,
                           const CommandContinuation& done)> ControlCommandHandler;


/** \brief a function to handle a StatusDataset request
 *  \param prefix top-level prefix, e.g., "/localhost/nfd";
 *  \param interest incoming Interest; its Name doesn't contain version and segment components
 *
 *  This function can generate zero or more blocks and pass them to \p append,
 *  and must call \p end upon completion.
 */
typedef std::function<void(const Name& prefix, const Interest& interest,
                           StatusDatasetContext& context)> StatusDatasetHandler;

//---- NOTIFICATION STREAM ----

/** \brief a function to post a notification
 */
typedef std::function<void(const Block& notification)> PostNotification;

// ---- DISPATCHER ----

/** \brief represents a dispatcher on server side of NFD Management protocol
 */
class Dispatcher : noncopyable
{
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

public:
  /** \brief constructor
   *  \param face the Face on which the dispatcher operates
   *  \param keyChain a KeyChain to sign Data
   *  \param signingInfo signing parameters to sign Data with \p keyChain
   *  \param imsCapacity capacity of the internal InMemoryStorage used by dispatcher
   */
  Dispatcher(Face& face, security::KeyChain& keyChain,
             const security::SigningInfo& signingInfo = security::SigningInfo(),
             size_t imsCapacity = 256);

  virtual
  ~Dispatcher();

  /** \brief add a top-level prefix
   *  \param prefix a top-level prefix, e.g., "/localhost/nfd"
   *  \param wantRegister whether prefix registration should be performed through the Face
   *  \param signingInfo signing parameters to sign the prefix registration command
   *  \throw std::out_of_range \p prefix overlaps with an existing top-level prefix
   *
   *  Procedure for adding a top-level prefix:
   *  1. if the new top-level prefix overlaps with an existing top-level prefix
   *     (one top-level prefix is a prefix of another top-level prefix), throw std::domain_error
   *  2. if wantRegister is true, invoke face.registerPrefix for the top-level prefix;
   *     the returned RegisteredPrefixId shall be recorded internally, indexed by the top-level
   *     prefix
   *  3. foreach relPrefix from ControlCommands and StatusDatasets,
   *     join the top-level prefix with the relPrefix to obtain the full prefix,
   *     and invoke non-registering overload of face.setInterestFilter,
   *     with the InterestHandler set to an appropriate private method to handle incoming Interests
   *     for the ControlCommand or StatusDataset;
   *     the returned InterestFilterId shall be recorded internally, indexed by the top-level
   *     prefix
   */
  void
  addTopPrefix(const Name& prefix, bool wantRegister = true,
               const security::SigningInfo& signingInfo = security::SigningInfo());

  /** \brief remove a top-level prefix
   *  \param prefix a top-level prefix, e.g., "/localhost/nfd"
   *
   *  Procedure for removing a top-level prefix:
   *  1. if the top-level prefix has not been added, abort these steps
   *  2. if the top-level prefix has been added with wantRegister,
   *     invoke face.unregisterPrefix with the RegisteredPrefixId
   *  3. foreach InterestFilterId recorded during addTopPrefix,
   *     invoke face.unsetInterestFilter with the InterestFilterId
   */
  void
  removeTopPrefix(const Name& prefix);

public: // ControlCommand
  /** \brief register a ControlCommand
   *  \tparam CP subclass of ControlParameters used by this command
   *  \param relPrefix a prefix for this command, e.g., "faces/create";
   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
   *                   non-overlapping
   *                   (no relPrefix is a prefix of another relPrefix)
   *  \param authorization Callback to authorize the incoming commands
   *  \param validateParams Callback to validate parameters of the incoming commands
   *  \param handler Callback to handle the commands
   *  \pre no top-level prefix has been added
   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
   *  \throw std::domain_error one or more top-level prefix has been added
   *
   *  Procedure for processing a ControlCommand:
   *  1. extract the NameComponent containing ControlParameters (the component after relPrefix),
   *     and parse ControlParameters into type CP; if parsing fails, abort these steps
   *  2. perform authorization; if authorization is rejected,
   *     perform the RejectReply action, and abort these steps
   *  3. validate ControlParameters; if validation fails,
   *     make ControlResponse with StatusCode 400, and go to step 5
   *  4. invoke handler, wait until CommandContinuation is called
   *  5. encode the ControlResponse into one Data packet
   *  6. sign the Data packet
   *  7. if the Data packet is too large, abort these steps and log an error
   *  8. send the signed Data packet
   */
  template<typename CP>
  void
  addControlCommand(const PartialName& relPrefix,
                    const Authorization& authorization,
                    const ValidateParameters& validateParams,
                    const ControlCommandHandler& handler);

public: // StatusDataset
  /** \brief register a StatusDataset or a prefix under which StatusDatasets can be requested
   *  \param relPrefix a prefix for this dataset, e.g., "faces/list";
   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
   *                   non-overlapping
   *                   (no relPrefix is a prefix of another relPrefix)
   *  \param authorization should set identity to Name() if the dataset is public
   *  \param handler Callback to process the incoming dataset requests
   *  \pre no top-level prefix has been added
   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
   *  \throw std::domain_error one or more top-level prefix has been added
   *
   * The payload of the returned status dataset data packet is at most half of the maximum
   * data packet size.
   *
   *  Procedure for processing a StatusDataset request:
   *  1. if the request Interest contains version or segment components, abort these steps;
   *     note: the request may contain more components after relPrefix, e.g., a query condition
   *  2. perform authorization; if authorization is rejected,
   *     perform the RejectReply action, and abort these steps
   *  3. invoke handler, store blocks passed to StatusDatasetAppend calls in a buffer,
   *     wait until StatusDatasetEnd is called
   *  4. allocate a version
   *  5. segment the buffer into one or more segments under the allocated version,
   *     such that the Data packets will not become too large after signing
   *  6. set FinalBlockId on at least the last segment
   *  7. sign the Data packets
   *  8. send the signed Data packets
   *
   *  As an optimization, a Data packet may be sent as soon as enough octets have been collected
   *  through StatusDatasetAppend calls.
   */
  void
  addStatusDataset(const PartialName& relPrefix,
                   const Authorization& authorization,
                   const StatusDatasetHandler& handler);

public: // NotificationStream
  /** \brief register a NotificationStream
   *  \param relPrefix a prefix for this notification stream, e.g., "faces/events";
   *                   relPrefixes in ControlCommands, StatusDatasets, NotificationStreams must be
   *                   non-overlapping
   *                   (no relPrefix is a prefix of another relPrefix)
   *  \return a function into which notifications can be posted
   *  \pre no top-level prefix has been added
   *  \throw std::out_of_range \p relPrefix overlaps with an existing relPrefix
   *  \throw std::domain_error one or more top-level prefix has been added
   *
   *  Procedure for posting a notification:
   *  1. if no top-level prefix has been added, or more than one top-level prefixes have been
   *     added,
   *     abort these steps and log an error
   *  2. assign the next sequence number to the notification
   *  3. place the notification block into one Data packet under the sole top-level prefix
   *  4. sign the Data packet
   *  5. if the Data packet is too large, abort these steps and log an error
   *  6. send the signed Data packet
   */
  PostNotification
  addNotificationStream(const PartialName& relPrefix);

private:
  typedef std::function<void(const Name& prefix,
                             const Interest& interest)> InterestHandler;

  typedef std::function<void(const std::string& requester,
                             const Name& prefix,
                             const Interest& interest,
                             const ControlParameters*)> AuthorizationAcceptedCallback;

  typedef std::function<void(RejectReply act,
                             const Interest& interest)> AuthorizationRejectedCallback;

  /**
   * @brief the parser of extracting control parameters from name component.
   *
   * @param component name component that may encode control parameters.
   * @return a shared pointer to the extracted control parameters.
   * @throw tlv::Error if the NameComponent cannot be parsed as ControlParameters
   */
  typedef std::function<shared_ptr<ControlParameters>(const name::Component& component)>
  ControlParametersParser;

  bool
  isOverlappedWithOthers(const PartialName& relPrefix);

  /**
   * @brief process unauthorized request
   *
   * @param act action to reply
   * @param interest the incoming Interest
   */
  void
  afterAuthorizationRejected(RejectReply act, const Interest& interest);

  /**
   * @brief query Data the in-memory storage by a given Interest
   *
   * if the query fails, invoke @p missContinuation to process @p interest.
   *
   * @param prefix the top-level prefix
   * @param interest the request
   * @param missContinuation the handler of request when the query fails
   */
  void
  queryStorage(const Name& prefix, const Interest& interest, const InterestHandler& missContinuation);

  enum class SendDestination {
    NONE = 0,
    FACE = 1,
    IMS  = 2,
    FACE_AND_IMS = 3
  };

  /**
   * @brief send data to the face or in-memory storage
   *
   * create a data packet with the given @p dataName, @p content, and @p metaInfo,
   * set its FreshnessPeriod to DEFAULT_FRESHNESS_PERIOD, and then send it out through the face and/or
   * insert it into the in-memory storage as specified in @p option.
   *
   * if it's toward the in-memory storage, set its CachePolicy to NO_CACHE and limit
   * its FreshnessPeriod in the storage as @p imsFresh
   *
   * @param dataName the name of this piece of data
   * @param content the content of this piece of data
   * @param metaInfo some meta information of this piece of data
   * @param destination where to send this piece of data
   * @param imsFresh freshness period of this piece of data in in-memory storage
   */
  void
  sendData(const Name& dataName, const Block& content, const MetaInfo& metaInfo,
           SendDestination destination, time::milliseconds imsFresh);

  /**
   * @brief send out a data packt through the face
   *
   * @param data the data packet to insert
   */
  void
  sendOnFace(const Data& data);

  /**
   * @brief process the control-command Interest before authorization.
   *
   * @param prefix the top-level prefix
   * @param relPrefix the relative prefix
   * @param interest the incoming Interest
   * @param parser to extract control parameters from the \p interest
   * @param authorization to process validation on this command
   * @param accepted the callback for successful authorization
   * @param rejected the callback for failed authorization
   */
  void
  processControlCommandInterest(const Name& prefix,
                                const Name& relPrefix,
                                const Interest& interest,
                                const ControlParametersParser& parser,
                                const Authorization& authorization,
                                const AuthorizationAcceptedCallback& accepted,
                                const AuthorizationRejectedCallback& rejected);

  /**
   * @brief process the authorized control-command.
   *
   * @param requester the requester
   * @param prefix the top-level prefix
   * @param interest the incoming Interest
   * @param parameters control parameters of this command
   * @param validate to validate control parameters
   * @param handler to process this command
   */
  void
  processAuthorizedControlCommandInterest(const std::string& requester,
                                          const Name& prefix,
                                          const Interest& interest,
                                          const ControlParameters* parameters,
                                          const ValidateParameters& validate,
                                          const ControlCommandHandler& handler);

  void
  sendControlResponse(const ControlResponse& resp, const Interest& interest, bool isNack = false);

  /**
   * @brief process the status-dataset Interest before authorization.
   *
   * @param prefix the top-level prefix
   * @param interest the incoming Interest
   * @param authorization to process verification
   * @param accepted callback for successful authorization
   * @param rejected callback for failed authorization
   */
  void
  processStatusDatasetInterest(const Name& prefix,
                               const Interest& interest,
                               const Authorization& authorization,
                               const AuthorizationAcceptedCallback& accepted,
                               const AuthorizationRejectedCallback& rejected);

  /**
   * @brief process the authorized status-dataset request
   *
   * @param requester the requester
   * @param prefix the top-level prefix
   * @param interest the incoming Interest
   * @param handler to process this request
   */
  void
  processAuthorizedStatusDatasetInterest(const std::string& requester,
                                         const Name& prefix,
                                         const Interest& interest,
                                         const StatusDatasetHandler& handler);

  /**
   * @brief send a segment of StatusDataset
   *
   * @param dataName the name of this piece of data
   * @param content the content of this piece of data
   * @param imsFresh the freshness period of this piece of data in the in-memory storage
   * @param isFinalBlock indicates whether this piece of data is the final block
   */
  void
  sendStatusDatasetSegment(const Name& dataName, const Block& content,
                           time::milliseconds imsFresh, bool isFinalBlock);

  void
  postNotification(const Block& notification, const PartialName& relPrefix);

private:
  struct TopPrefixEntry
  {
    Name topPrefix;
    bool wantRegister;
    const ndn::RegisteredPrefixId* registerPrefixId;
    std::vector<const ndn::InterestFilterId*> interestFilters;
  };
  std::unordered_map<Name, TopPrefixEntry> m_topLevelPrefixes;

  Face& m_face;
  security::KeyChain& m_keyChain;
  security::SigningInfo m_signingInfo;

  typedef std::unordered_map<PartialName, InterestHandler> HandlerMap;
  typedef HandlerMap::iterator HandlerMapIt;
  HandlerMap m_handlers;

  // NotificationStream name => next sequence number
  std::unordered_map<Name, uint64_t> m_streams;

NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  util::InMemoryStorageFifo m_storage;
};

template<typename CP>
void
Dispatcher::addControlCommand(const PartialName& relPrefix,
                              const Authorization& authorization,
                              const ValidateParameters& validateParams,
                              const ControlCommandHandler& handler)
{
  if (!m_topLevelPrefixes.empty()) {
    throw std::domain_error("one or more top-level prefix has been added");
  }

  if (isOverlappedWithOthers(relPrefix)) {
    throw std::out_of_range("relPrefix overlaps with another relPrefix");
  }

  ControlParametersParser parser =
    [] (const name::Component& component) -> shared_ptr<ControlParameters> {
    return make_shared<CP>(component.blockFromValue());
  };

  AuthorizationAcceptedCallback accepted =
    bind(&Dispatcher::processAuthorizedControlCommandInterest, this,
         _1, _2, _3, _4, validateParams, handler);

  AuthorizationRejectedCallback rejected =
    bind(&Dispatcher::afterAuthorizationRejected, this, _1, _2);

  m_handlers[relPrefix] = bind(&Dispatcher::processControlCommandInterest, this,
                               _1, relPrefix, _2, parser, authorization, accepted, rejected);
}

} // namespace mgmt
} // namespace ndn
#endif // NDN_MGMT_DISPATCHER_HPP
