/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2015,  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_HPP
#define NFD_RIB_RIB_HPP

#include "common.hpp"

#include "rib-entry.hpp"
#include "rib-update-batch.hpp"

#include <ndn-cxx/management/nfd-control-parameters.hpp>

namespace nfd {
namespace rib {

using ndn::nfd::ControlParameters;

class FibUpdater;

/** \brief represents the RIB
 */
class Rib : noncopyable
{
public:
  typedef std::list<shared_ptr<RibEntry>> RibEntryList;
  typedef std::map<Name, shared_ptr<RibEntry>> RibTable;
  typedef RibTable::const_iterator const_iterator;
  typedef std::map<uint64_t, std::list<shared_ptr<RibEntry>>> FaceLookupTable;
  typedef bool (*RouteComparePredicate)(const Route&, const Route&);
  typedef std::set<Route, RouteComparePredicate> RouteSet;

  Rib();

  ~Rib();

  void
  setFibUpdater(FibUpdater* updater);

  const_iterator
  find(const Name& prefix) const;

  Route*
  find(const Name& prefix, const Route& route) const;

  const_iterator
  begin() const;

  const_iterator
  end() const;

  size_t
  size() const;

  bool
  empty() const;

  shared_ptr<RibEntry>
  findParent(const Name& prefix) const;

  /** \brief finds namespaces under the passed prefix
   *  \return{ a list of entries which are under the passed prefix }
   */
  std::list<shared_ptr<RibEntry>>
  findDescendants(const Name& prefix) const;

  /** \brief finds namespaces under the passed prefix
   *
   *  \note Unlike findDescendants, needs to find where prefix would fit in tree
   *  before collecting list of descendant prefixes
   *
   *  \return{ a list of entries which would be under the passed prefix if the prefix
   *  existed in the RIB }
   */
  std::list<shared_ptr<RibEntry>>
  findDescendantsForNonInsertedName(const Name& prefix) const;

public:
  typedef function<void()> UpdateSuccessCallback;
  typedef function<void(uint32_t code, const std::string& error)> UpdateFailureCallback;

  /** \brief passes the provided RibUpdateBatch to FibUpdater to calculate and send FibUpdates.
   *
   *  If the FIB is updated successfully, onFibUpdateSuccess() will be called, and the
   *  RIB will be updated
   *
   *  If the FIB update fails, onFibUpdateFailure() will be called, and the RIB will not
   *  be updated.
   */
  void
  beginApplyUpdate(const RibUpdate& update,
                   const UpdateSuccessCallback& onSuccess,
                   const UpdateFailureCallback& onFailure);

  /** \brief starts the FIB update process when a face has been destroyed
   */
  void
  beginRemoveFace(uint64_t faceId);

  void
  onFibUpdateSuccess(const RibUpdateBatch& batch,
                     const RibUpdateList& inheritedRoutes,
                     const Rib::UpdateSuccessCallback& onSuccess);

  void
  onFibUpdateFailure(const Rib::UpdateFailureCallback& onFailure,
                     uint32_t code, const std::string& error);

  void
  onRouteExpiration(const Name& prefix, const Route& route);

private:
  /** \brief adds the passed update to a RibUpdateBatch and adds the batch to
  *          the end of the update queue.
  *
  *   If an update is not in progress, the front update batch in the queue will be
  *   processed by the RIB.
  *
  *   If an update is in progress, the added update will eventually be processed
  *   when it reaches the front of the queue; after other update batches are
  *   processed, the queue is advanced.
  */
  void
  addUpdateToQueue(const RibUpdate& update,
                   const Rib::UpdateSuccessCallback& onSuccess,
                   const Rib::UpdateFailureCallback& onFailure);

  /** \brief Attempts to send the front update batch in the queue.
  *
  *   If an update is not in progress, the front update batch in the queue will be
  *   sent to the RIB for processing.
  *
  *   If an update is in progress, nothing will be done.
  */
  void
  sendBatchFromQueue();

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  // Used by RibManager unit-tests to get sent batch to simulate successful FIB update
  function<void(RibUpdateBatch)> m_onSendBatchFromQueue;

public:
  void
  insert(const Name& prefix, const Route& route);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  void
  erase(const Name& prefix, const Route& route);

private:
  RibTable::iterator
  eraseEntry(RibTable::iterator it);

  void
  updateRib(const RibUpdateBatch& batch);

  /** \brief returns routes inherited from the entry's ancestors
   *
   *  \return{ a list of inherited routes }
   */
  RouteSet
  getAncestorRoutes(const RibEntry& entry) const;

  /** \brief returns routes inherited from the parent of the name and the parent's ancestors
   *
   *  \note A parent is first found for the passed name before inherited routes are collected
   *
   *  \return{ a list of inherited routes }
   */
  RouteSet
  getAncestorRoutes(const Name& name) const;

  /** \brief applies the passed inheritedRoutes and their actions to the corresponding RibEntries'
   *  inheritedRoutes lists
   */
  void
  modifyInheritedRoutes(const RibUpdateList& inheritedRoutes);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  typedef std::pair<const Name&,const Route&> NameAndRoute;

  std::list<NameAndRoute>
  findRoutesWithFaceId(uint64_t faceId);

public:
  ndn::util::signal::Signal<Rib, Name> afterInsertEntry;
  ndn::util::signal::Signal<Rib, Name> afterEraseEntry;

private:
  RibTable m_rib;
  FaceLookupTable m_faceMap;
  FibUpdater* m_fibUpdater;

  size_t m_nItems;

  friend class FibUpdater;

private:
  struct UpdateQueueItem
  {
    RibUpdateBatch batch;
    const Rib::UpdateSuccessCallback managerSuccessCallback;
    const Rib::UpdateFailureCallback managerFailureCallback;
  };

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  typedef std::list<UpdateQueueItem> UpdateQueue;
  UpdateQueue m_updateBatches;

private:
  bool m_isUpdateInProgress;
};

inline Rib::const_iterator
Rib::begin() const
{
  return m_rib.begin();
}

inline Rib::const_iterator
Rib::end() const
{
  return m_rib.end();
}

inline size_t
Rib::size() const
{
  return m_nItems;
}

inline bool
Rib::empty() const
{
  return m_rib.empty();
}

std::ostream&
operator<<(std::ostream& os, const Rib& rib);

} // namespace rib
} // namespace nfd

#endif // NFD_RIB_RIB_HPP
