/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_RIB_RIB_MANAGER_HPP
#define NFD_RIB_RIB_MANAGER_HPP

#include "rib.hpp"
#include "core/config-file.hpp"
#include "core/manager-base.hpp"
#include "rib-status-publisher.hpp"
#include "auto-prefix-propagator.hpp"
#include "fib-updater.hpp"

#include <ndn-cxx/security/validator-config.hpp>
#include <ndn-cxx/management/nfd-face-monitor.hpp>
#include <ndn-cxx/management/nfd-controller.hpp>
#include <ndn-cxx/management/nfd-control-command.hpp>
#include <ndn-cxx/management/nfd-control-response.hpp>
#include <ndn-cxx/management/nfd-control-parameters.hpp>

namespace nfd {
namespace rib {

using ndn::nfd::ControlCommand;
using ndn::nfd::ControlResponse;
using ndn::nfd::ControlParameters;

using ndn::nfd::FaceEventNotification;

class RibManager : public nfd::ManagerBase
{
public:
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

public:
  RibManager(Dispatcher& dispatcher, ndn::Face& face, ndn::KeyChain& keyChain);

  ~RibManager();

  void
  registerWithNfd();

  void
  enableLocalControlHeader();

  void
  setConfigFile(ConfigFile& configFile);

  void
  onRibUpdateSuccess(const RibUpdate& update);

  void
  onRibUpdateFailure(const RibUpdate& update, uint32_t code, const std::string& error);

private: // initialization helpers
  void
  onConfig(const ConfigSection& configSection, bool isDryRun, const std::string& filename);

  void
  registerTopPrefix(const Name& topPrefix);

private: // ControlCommand and StatusDataset
  void
  registerEntry(const Name& topPrefix, const Interest& interest,
                ControlParameters parameters,
                const ndn::mgmt::CommandContinuation& done);

  void
  unregisterEntry(const Name& topPrefix, const Interest& interest,
                  ControlParameters parameters,
                  const ndn::mgmt::CommandContinuation& done);

  void
  listEntries(const Name& topPrefix, const Interest& interest,
              ndn::mgmt::StatusDatasetContext& context);

  void
  setFaceForSelfRegistration(const Interest& request, ControlParameters& parameters);

private: // command validation
  /**
   * @brief validate a request for ControlCommand.
   *
   * This is called by the dispatcher.
   *
   * @pre params != null
   * @pre typeid(*params) == typeid(ndn::nfd::ControlParameters)
   *
   * @param prefix the top prefix
   * @param interest a request for ControlCommand
   * @param params the parameters for ControlCommand
   * @param accept callback of successful validation, take the requester string as a argument
   * @param reject callback of failure in validation, take the action code as a argument
   *
   * use m_localhostValidator / m_localhopValidator to validate commands according to @p prefix.
   */
  virtual void
  authorize(const Name& prefix, const Interest& interest,
            const ndn::mgmt::ControlParameters* params,
            ndn::mgmt::AcceptContinuation accept,
            ndn::mgmt::RejectContinuation reject) override;

private: // Face monitor
  void
  fetchActiveFaces();

  void
  fetchSegments(const Data& data, shared_ptr<ndn::OBufferStream> buffer);

  void
  onFetchFaceStatusTimeout();

  void
  onFaceDestroyedEvent(uint64_t faceId);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  void
  scheduleActiveFaceFetch(const time::seconds& timeToWait);

  /**
   * @brief remove invalid faces
   *
   * @param buffer Face dataset contents
  */
  void
  removeInvalidFaces(shared_ptr<ndn::OBufferStream> buffer);

  /**
   * @brief response to face events
   *
   * @param notification
   */
  void
  onNotification(const FaceEventNotification& notification);

private:
  void
  onCommandPrefixAddNextHopSuccess(const Name& prefix,
                                   const ndn::nfd::ControlParameters& result);

  void
  onCommandPrefixAddNextHopError(const Name& name, const std::string& msg);

  void
  onControlHeaderSuccess();

  void
  onControlHeaderError(uint32_t code, const std::string& reason);

private:
  ndn::Face& m_face;
  ndn::KeyChain& m_keyChain;
  ndn::nfd::Controller m_nfdController;
  ndn::nfd::FaceMonitor m_faceMonitor;
  ndn::ValidatorConfig m_localhostValidator;
  ndn::ValidatorConfig m_localhopValidator;
  bool m_isLocalhopEnabled;
  AutoPrefixPropagator m_prefixPropagator;

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  Rib m_rib;
  FibUpdater m_fibUpdater;

private:
  static const Name LOCAL_HOST_TOP_PREFIX;
  static const Name LOCAL_HOP_TOP_PREFIX;
  static const std::string MGMT_MODULE_NAME;
  static const Name FACES_LIST_DATASET_PREFIX;
  static const time::seconds ACTIVE_FACE_FETCH_INTERVAL;
  scheduler::EventId m_activeFaceFetchEvent;

  typedef std::set<uint64_t> FaceIdSet;
  /** \brief contains FaceIds with one or more Routes in the RIB
  */
  FaceIdSet m_registeredFaces;

  std::function<void(const Name& topPrefix)> m_addTopPrefix;
};

} // namespace rib
} // namespace nfd

#endif // NFD_RIB_RIB_MANAGER_HPP
