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

#include "ndn-cxx/data.hpp"
#include "ndn-cxx/interest.hpp"
#include "ndn-cxx/interest-filter.hpp"
#include "ndn-cxx/detail/asio-fwd.hpp"
#include "ndn-cxx/detail/cancel-handle.hpp"
#include "ndn-cxx/encoding/nfd-constants.hpp"
#include "ndn-cxx/lp/nack.hpp"
#include "ndn-cxx/security/key-chain.hpp"
#include "ndn-cxx/security/signing-info.hpp"

namespace ndn {

class Transport;

class PendingInterestId;
class PendingInterestHandle;
class RegisteredPrefixId;
class RegisteredPrefixHandle;
class InterestFilterId;
class InterestFilterHandle;

namespace nfd {
class Controller;
} // namespace nfd

/**
 * @brief Callback invoked when expressed Interest gets satisfied with a Data packet
 */
typedef function<void(const Interest&, const Data&)> DataCallback;

/**
 * @brief Callback invoked when Nack is sent in response to expressed Interest
 */
typedef function<void(const Interest&, const lp::Nack&)> NackCallback;

/**
 * @brief Callback invoked when expressed Interest times out
 */
typedef function<void(const Interest&)> TimeoutCallback;

/**
 * @brief Callback invoked when incoming Interest matches the specified InterestFilter
 */
typedef function<void(const InterestFilter&, const Interest&)> InterestCallback;

/**
 * @brief Callback invoked when registerPrefix or setInterestFilter command succeeds
 */
typedef function<void(const Name&)> RegisterPrefixSuccessCallback;

/**
 * @brief Callback invoked when registerPrefix or setInterestFilter command fails
 */
typedef function<void(const Name&, const std::string&)> RegisterPrefixFailureCallback;

/**
 * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command succeeds
 */
typedef function<void()> UnregisterPrefixSuccessCallback;

/**
 * @brief Callback invoked when unregisterPrefix or unsetInterestFilter command fails
 */
typedef function<void(const std::string&)> UnregisterPrefixFailureCallback;

/**
 * @brief Provide a communication channel with local or remote NDN forwarder
 */
class Face : noncopyable
{
public:
  class Error : public std::runtime_error
  {
  public:
    using std::runtime_error::runtime_error;
  };

  /**
   * @brief Exception thrown when attempting to send a packet over size limit
   */
  class OversizedPacketError : public Error
  {
  public:
    /**
     * @brief Constructor
     * @param pktType packet type, 'I' for Interest, 'D' for Data, 'N' for Nack
     * @param name packet name
     * @param wireSize wire encoding size
     */
    OversizedPacketError(char pktType, const Name& name, size_t wireSize);

  public:
    const char pktType;
    const Name name;
    const size_t wireSize;
  };

public: // constructors
  /**
   * @brief Create Face using given transport (or default transport if omitted)
   * @param transport the transport for lower layer communication. If nullptr,
   *                  a default transport will be used. The default transport is
   *                  determined from a FaceUri in NDN_CLIENT_TRANSPORT environ,
   *                  a FaceUri in configuration file 'transport' key, or UnixTransport.
   *
   * @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
   *                          parsed or specifies an unsupported protocol
   * @note shared_ptr is passed by value because ownership is shared with this class
   */
  explicit
  Face(shared_ptr<Transport> transport = nullptr);

  /**
   * @brief Create Face using default transport and given io_service
   *
   * Usage examples:
   *
   * @code
   * Face face1;
   * Face face2(face1.getIoService());
   *
   * // Now the following ensures that events on both faces are processed
   * face1.processEvents();
   * // or face1.getIoService().run();
   * @endcode
   *
   * or
   *
   * @code
   * boost::asio::io_service ioService;
   * Face face1(ioService);
   * Face face2(ioService);
   *
   * ioService.run();
   * @endcode
   *
   * @param ioService A reference to boost::io_service object that should control all
   *                  IO operations.
   * @throw ConfigFile::Error the configuration file cannot be parsed or specifies an unsupported protocol
   */
  explicit
  Face(boost::asio::io_service& ioService);

  /**
   * @brief Create Face using TcpTransport
   *
   * @param host IP address or hostname of the NDN forwarder
   * @param port port number or service name of the NDN forwarder (**default**: "6363")
   */
  explicit
  Face(const std::string& host, const std::string& port = "6363");

  /**
   * @brief Create Face using given transport and KeyChain
   * @param transport the transport for lower layer communication. If nullptr,
   *                  a default transport will be used.
   * @param keyChain the KeyChain to sign commands
   *
   * @sa Face(shared_ptr<Transport>)
   *
   * @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
   *                          parsed or specifies an unsupported protocol
   * @note shared_ptr is passed by value because ownership is shared with this class
   */
  Face(shared_ptr<Transport> transport, KeyChain& keyChain);

  /**
   * @brief Create Face using given transport and io_service
   * @param transport the transport for lower layer communication. If nullptr,
   *                  a default transport will be used.
   * @param ioService the io_service that controls all IO operations
   *
   * @sa Face(boost::asio::io_service&)
   * @sa Face(shared_ptr<Transport>)
   *
   * @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
   *                          parsed or specifies an unsupported protocol
   * @note shared_ptr is passed by value because ownership is shared with this class
   */
  Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);

  /**
   * @brief Create a new Face using given Transport and io_service
   * @param transport the transport for lower layer communication. If nullptr,
   *                  a default transport will be used.
   * @param ioService the io_service that controls all IO operations
   * @param keyChain the KeyChain to sign commands
   *
   * @sa Face(boost::asio::io_service&)
   * @sa Face(shared_ptr<Transport>, KeyChain&)
   *
   * @throw ConfigFile::Error @p transport is nullptr, and the configuration file cannot be
   *                          parsed or specifies an unsupported protocol
   * @note shared_ptr is passed by value because ownership is shared with this class
   */
  Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);

  virtual
  ~Face();

public: // consumer
  /**
   * @brief Express Interest
   * @param interest the Interest; a copy will be made, so that the caller is not
   *                 required to maintain the argument unchanged
   * @param afterSatisfied function to be invoked if Data is returned
   * @param afterNacked function to be invoked if Network NACK is returned
   * @param afterTimeout function to be invoked if neither Data nor Network NACK
   *                     is returned within InterestLifetime
   * @throw OversizedPacketError encoded Interest size exceeds MAX_NDN_PACKET_SIZE
   * @return A handle for canceling the pending Interest.
   */
  PendingInterestHandle
  expressInterest(const Interest& interest,
                  const DataCallback& afterSatisfied,
                  const NackCallback& afterNacked,
                  const TimeoutCallback& afterTimeout);

  /**
   * @brief Cancel previously expressed Interest
   * @param pendingInterestId a handle returned by expressInterest.
   */
  void
  removePendingInterest(const PendingInterestId* pendingInterestId);

  /**
   * @brief Cancel all previously expressed Interests
   */
  void
  removeAllPendingInterests();

  /**
   * @brief Get number of pending Interests
   */
  size_t
  getNPendingInterests() const;

public: // producer
  /**
   * @brief Set InterestFilter to dispatch incoming matching interest to onInterest
   * callback and register the filtered prefix with the connected NDN forwarder
   *
   * This version of setInterestFilter combines setInterestFilter and registerPrefix
   * operations and is intended to be used when only one filter for the same prefix needed
   * to be set.  When multiple names sharing the same prefix should be dispatched to
   * different callbacks, use one registerPrefix call, followed (in onSuccess callback) by
   * a series of setInterestFilter calls.
   *
   * @param interestFilter Interest filter (prefix part will be registered with the forwarder)
   * @param onInterest     A callback to be called when a matching interest is received
   * @param onFailure      A callback to be called when prefixRegister command fails
   * @param flags          (optional) RIB flags
   * @param signingInfo    (optional) Signing parameters.  When omitted, a default parameters
   *                       used in the signature will be used.
   *
   * @return A handle for unregistering the prefix.
   */
  RegisteredPrefixHandle
  setInterestFilter(const InterestFilter& interestFilter,
                    const InterestCallback& onInterest,
                    const RegisterPrefixFailureCallback& onFailure,
                    const security::SigningInfo& signingInfo = security::SigningInfo(),
                    uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);

  /**
   * @brief Set InterestFilter to dispatch incoming matching interest to onInterest
   * callback and register the filtered prefix with the connected NDN forwarder
   *
   * This version of setInterestFilter combines setInterestFilter and registerPrefix
   * operations and is intended to be used when only one filter for the same prefix needed
   * to be set.  When multiple names sharing the same prefix should be dispatched to
   * different callbacks, use one registerPrefix call, followed (in onSuccess callback) by
   * a series of setInterestFilter calls.
   *
   * @param interestFilter Interest filter (prefix part will be registered with the forwarder)
   * @param onInterest     A callback to be called when a matching interest is received
   * @param onSuccess      A callback to be called when prefixRegister command succeeds
   * @param onFailure      A callback to be called when prefixRegister command fails
   * @param flags          (optional) RIB flags
   * @param signingInfo    (optional) Signing parameters.  When omitted, a default parameters
   *                       used in the signature will be used.
   *
   * @return A handle for unregistering the prefix.
   */
  RegisteredPrefixHandle
  setInterestFilter(const InterestFilter& interestFilter,
                    const InterestCallback& onInterest,
                    const RegisterPrefixSuccessCallback& onSuccess,
                    const RegisterPrefixFailureCallback& onFailure,
                    const security::SigningInfo& signingInfo = security::SigningInfo(),
                    uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);

  /**
   * @brief Set InterestFilter to dispatch incoming matching interest to onInterest callback
   *
   * @param interestFilter Interest
   * @param onInterest A callback to be called when a matching interest is received
   *
   * This method modifies library's FIB only, and does not register the prefix with the
   * forwarder.  It will always succeed.  To register prefix with the forwarder, use
   * registerPrefix, or use the setInterestFilter overload taking two callbacks.
   *
   * @return A handle for unsetting the Interest filter.
   */
  InterestFilterHandle
  setInterestFilter(const InterestFilter& interestFilter,
                    const InterestCallback& onInterest);

  /**
   * @brief Register prefix with the connected NDN forwarder
   *
   * This method only modifies forwarder's RIB and does not associate any
   * onInterest callbacks.  Use setInterestFilter method to dispatch incoming Interests to
   * the right callbacks.
   *
   * @param prefix      A prefix to register with the connected NDN forwarder
   * @param onSuccess   A callback to be called when prefixRegister command succeeds
   * @param onFailure   A callback to be called when prefixRegister command fails
   * @param signingInfo (optional) Signing parameters.  When omitted, a default parameters
   *                    used in the signature will be used.
   * @param flags       Prefix registration flags
   *
   * @return A handle for unregistering the prefix.
   * @see nfd::RouteFlags
   */
  RegisteredPrefixHandle
  registerPrefix(const Name& prefix,
                 const RegisterPrefixSuccessCallback& onSuccess,
                 const RegisterPrefixFailureCallback& onFailure,
                 const security::SigningInfo& signingInfo = security::SigningInfo(),
                 uint64_t flags = nfd::ROUTE_FLAG_CHILD_INHERIT);

  /**
   * @brief Remove the registered prefix entry with the registeredPrefixId
   *
   * This does not affect another registered prefix with a different registeredPrefixId,
   * even it if has the same prefix name.  If there is no entry with the
   * registeredPrefixId, do nothing.
   *
   * unsetInterestFilter will use the same credentials as original
   * setInterestFilter/registerPrefix command
   *
   * @param registeredPrefixId a handle returned by registerPrefix
   */
  void
  unsetInterestFilter(const RegisteredPrefixId* registeredPrefixId);

  /**
   * @brief Remove previously set InterestFilter from library's FIB
   *
   * This method always succeeds and will **NOT** send any request to the connected
   * forwarder.
   *
   * @param interestFilterId a handle returned by setInterestFilter.
   */
  void
  unsetInterestFilter(const InterestFilterId* interestFilterId);

  /**
   * @brief Unregister prefix from RIB
   *
   * unregisterPrefix will use the same credentials as original
   * setInterestFilter/registerPrefix command
   *
   * If registeredPrefixId was obtained using setInterestFilter, the corresponding
   * InterestFilter will be unset too.
   *
   * @param registeredPrefixId a handle returned by registerPrefix
   * @param onSuccess          Callback to be called when operation succeeds
   * @param onFailure          Callback to be called when operation fails
   */
  void
  unregisterPrefix(const RegisteredPrefixId* registeredPrefixId,
                   const UnregisterPrefixSuccessCallback& onSuccess,
                   const UnregisterPrefixFailureCallback& onFailure);

  /**
   * @brief Publish data packet
   * @param data the Data; a copy will be made, so that the caller is not required to
   *             maintain the argument unchanged
   *
   * This method can be called to satisfy incoming Interests, or to add Data packet into the cache
   * of the local NDN forwarder if forwarder is configured to accept unsolicited Data.
   *
   * @throw OversizedPacketError encoded Data size exceeds MAX_NDN_PACKET_SIZE
   */
  void
  put(Data data);

  /**
   * @brief Send a network NACK
   * @param nack the Nack; a copy will be made, so that the caller is not required to
   *             maintain the argument unchanged
   * @throw OversizedPacketError encoded Nack size exceeds MAX_NDN_PACKET_SIZE
   */
  void
  put(lp::Nack nack);

public: // IO routine
  /**
   * @brief Process any data to receive or call timeout callbacks.
   *
   * This call will block forever (default timeout == 0) to process IO on the face.
   * To exit cleanly on a producer, unset any Interest filters with unsetInterestFilter() and wait
   * for processEvents() to return. To exit after an error, one can call shutdown().
   * In consumer applications, processEvents() will return when all expressed Interests have been
   * satisfied, Nacked, or timed out. To terminate earlier, a consumer application should call
   * removePendingInterests() for all previously expressed and still-pending Interests.
   *
   * If a positive timeout is specified, then processEvents() will exit after this timeout, provided
   * it is not stopped earlier with shutdown() or when all active events finish. processEvents()
   * can be called repeatedly, if desired.
   *
   * If a negative timeout is specified, then processEvents will not block and will process only
   * pending events.
   *
   * @param timeout     maximum time to block the thread
   * @param keepThread  Keep thread in a blocked state (in event processing), even when
   *                    there are no outstanding events (e.g., no Interest/Data is expected).
   *                    If timeout is zero and this parameter is true, the only way to stop
   *                    processEvents() is to call shutdown().
   *
   * @note This may throw an exception for reading data or in the callback for processing
   * the data.  If you call this from an main event loop, you may want to catch and
   * log/disregard all exceptions.
   *
   * @throw OversizedPacketError encoded packet size exceeds MAX_NDN_PACKET_SIZE
   */
  void
  processEvents(time::milliseconds timeout = time::milliseconds::zero(),
                bool keepThread = false)
  {
    this->doProcessEvents(timeout, keepThread);
  }

  /**
   * @brief Shutdown face operations
   *
   * This method cancels all pending operations and closes connection to NDN Forwarder.
   *
   * Note that this method does not stop the io_service if it is shared between multiple Faces or
   * with other IO objects (e.g., Scheduler).
   *
   * @warning Calling this method could cause outgoing packets to be lost. Producers that shut down
   *          immediately after sending a Data packet should instead use unsetInterestFilter() to
   *          shut down cleanly.
   */
  void
  shutdown();

  /**
   * @return reference to io_service object
   */
  boost::asio::io_service&
  getIoService()
  {
    return m_ioService;
  }

NDN_CXX_PUBLIC_WITH_TESTS_ELSE_PROTECTED:
  /**
   * @return underlying transport
   */
  shared_ptr<Transport>
  getTransport();

protected:
  virtual void
  doProcessEvents(time::milliseconds timeout, bool keepThread);

private:
  /**
   * @throw ConfigFile::Error on parse error and unsupported protocols
   */
  shared_ptr<Transport>
  makeDefaultTransport();

  /**
   * @throw Face::Error on unsupported protocol
   * @note shared_ptr is passed by value because ownership is transferred to this function
   */
  void
  construct(shared_ptr<Transport> transport, KeyChain& keyChain);

  void
  onReceiveElement(const Block& blockFromDaemon);

  void
  asyncShutdown();

private:
  /// the io_service owned by this Face, could be null
  unique_ptr<boost::asio::io_service> m_internalIoService;
  /// the io_service used by this Face
  boost::asio::io_service& m_ioService;

  shared_ptr<Transport> m_transport;

  /**
   * @brief if not null, a pointer to an internal KeyChain owned by Face
   * @note if a KeyChain is supplied to constructor, this pointer will be null,
   *       and the passed KeyChain is given to nfdController;
   *       currently Face does not keep the KeyChain passed in constructor
   *       because it's not needed, but this may change in the future
   */
  unique_ptr<KeyChain> m_internalKeyChain;

  unique_ptr<nfd::Controller> m_nfdController;

  class Impl;
  shared_ptr<Impl> m_impl;
};

/** \brief A handle of pending Interest.
 *
 *  \code
 *  PendingInterestHandle hdl = face.expressInterest(interest, satisfyCb, nackCb, timeoutCb);
 *  hdl.cancel(); // cancel the pending Interest
 *  \endcode
 *
 *  \warning Canceling the same pending Interest more than once, using same or different
 *           PendingInterestHandle or ScopedPendingInterestHandle, may trigger undefined behavior.
 *  \warning Canceling a pending Interest after the face has been destructed may trigger undefined
 *           behavior.
 */
class PendingInterestHandle : public detail::CancelHandle
{
public:
  PendingInterestHandle() noexcept = default;

  PendingInterestHandle(Face& face, const PendingInterestId* id);

  operator const PendingInterestId*() const noexcept
  {
    return m_id;
  }

private:
  const PendingInterestId* m_id = nullptr;
};

/** \brief A scoped handle of pending Interest.
 *
 *  Upon destruction of this handle, the pending Interest is canceled automatically.
 *  Most commonly, the application keeps a ScopedPendingInterestHandle as a class member field,
 *  so that it can cleanup its pending Interest when the class instance is destructed.
 *
 *  \code
 *  {
 *    ScopedPendingInterestHandle hdl = face.expressInterest(interest, satisfyCb, nackCb, timeoutCb);
 *  } // hdl goes out of scope, canceling the pending Interest
 *  \endcode
 *
 *  \warning Canceling the same pending Interest more than once, using same or different
 *           PendingInterestHandle or ScopedPendingInterestHandle, may trigger undefined behavior.
 *  \warning Canceling a pending Interest after the face has been destructed may trigger undefined
 *           behavior.
 */
using ScopedPendingInterestHandle = detail::ScopedCancelHandle;

/** \brief A handle of registered prefix.
 */
class RegisteredPrefixHandle : public detail::CancelHandle
{
public:
  RegisteredPrefixHandle() noexcept
  {
    // This could have been '= default', but there's compiler bug in Apple clang 9.0.0,
    // see https://stackoverflow.com/a/44693603
  }

  RegisteredPrefixHandle(Face& face, const RegisteredPrefixId* id);

  operator const RegisteredPrefixId*() const noexcept
  {
    return m_id;
  }

  /** \brief Unregister the prefix.
   *  \warning Unregistering the same prefix more than once, using same or different
   *           RegisteredPrefixHandle or ScopedRegisteredPrefixHandle, may trigger undefined
   *           behavior.
   *  \warning Unregistering a prefix after the face has been destructed may trigger undefined
   *           behavior.
   */
  void
  unregister(const UnregisterPrefixSuccessCallback& onSuccess = nullptr,
             const UnregisterPrefixFailureCallback& onFailure = nullptr);

private:
  Face* m_face = nullptr;
  const RegisteredPrefixId* m_id = nullptr;
};

/** \brief A scoped handle of registered prefix.
 *
 *  Upon destruction of this handle, the prefix is unregistered automatically.
 *  Most commonly, the application keeps a ScopedRegisteredPrefixHandle as a class member field,
 *  so that it can cleanup its prefix registration when the class instance is destructed.
 *  The application will not be notified whether the unregistration was successful.
 *
 *  \code
 *  {
 *    ScopedRegisteredPrefixHandle hdl = face.registerPrefix(prefix, onSuccess, onFailure);
 *  } // hdl goes out of scope, unregistering the prefix
 *  \endcode
 *
 *  \warning Unregistering the same prefix more than once, using same or different
 *           RegisteredPrefixHandle or ScopedRegisteredPrefixHandle, may trigger undefined
 *           behavior.
 *  \warning Unregistering a prefix after the face has been destructed may trigger undefined
 *           behavior.
 */
using ScopedRegisteredPrefixHandle = detail::ScopedCancelHandle;

/** \brief A handle of registered Interest filter.
 *
 *  \code
 *  InterestFilterHandle hdl = face.setInterestFilter(prefix, onInterest);
 *  hdl.cancel(); // unset the Interest filter
 *  \endcode
 *
 *  \warning Unsetting the same Interest filter more than once, using same or different
 *           InterestFilterHandle or ScopedInterestFilterHandle, may trigger undefined behavior.
 *  \warning Unsetting an Interest filter after the face has been destructed may trigger
 *           undefined behavior.
 */
class InterestFilterHandle : public detail::CancelHandle
{
public:
  InterestFilterHandle() noexcept = default;

  InterestFilterHandle(Face& face, const InterestFilterId* id);

  operator const InterestFilterId*() const noexcept
  {
    return m_id;
  }

private:
  const InterestFilterId* m_id = nullptr;
};

/** \brief A scoped handle of registered Interest filter.
 *
 *  Upon destruction of this handle, the Interest filter is unset automatically.
 *  Most commonly, the application keeps a ScopedInterestFilterHandle as a class member field,
 *  so that it can cleanup its Interest filter when the class instance is destructed.
 *
 *  \code
 *  {
 *    ScopedInterestFilterHandle hdl = face.setInterestFilter(prefix, onInterest);
 *  } // hdl goes out of scope, unsetting the Interest filter
 *  \endcode
 *
 *  \warning Unsetting the same Interest filter more than once, using same or different
 *           InterestFilterHandle or ScopedInterestFilterHandle, may trigger undefined behavior.
 *  \warning Unsetting an Interest filter after the face has been destructed may trigger
 *           undefined behavior.
 */
using ScopedInterestFilterHandle = detail::ScopedCancelHandle;

} // namespace ndn

#endif // NDN_FACE_HPP
