/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2018,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 **/

#ifndef NLSR_SYNC_LOGIC_HANDLER_HPP
#define NLSR_SYNC_LOGIC_HANDLER_HPP

#include "test-access-control.hpp"
#include "signals.hpp"
#include "lsa.hpp"

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ChronoSync/socket.hpp>
#include <boost/throw_exception.hpp>

class InterestManager;

namespace nlsr {

class ConfParameter;

/*! \brief NLSR-to-ChronoSync interaction point
 *
 * This class serves as the abstraction for the syncing portion of
 * NLSR and its components. NLSR has no particular reliance on
 * ChronoSync, except that the NLSR source would need to be modified
 * for use with other sync protocols.
 *
 */
class SyncLogicHandler
{
public:
  using IsLsaNew =
    std::function<bool(const ndn::Name&, const Lsa::Type& lsaType, const uint64_t&)>;

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

  SyncLogicHandler(ndn::Face& face, const IsLsaNew& isLsaNew, const ConfParameter& conf);

  /*! \brief Hook function to call whenever sync detects new data.
   *
   * This function packages the sync information into discrete updates
   * and passes those off to another function, processUpdateFromSync.
   * \sa processUpdateFromSync
   *
   * \param v A container with the new information sync has received
   */
  void
  onChronoSyncUpdate(const std::vector<chronosync::MissingDataInfo>& v);

  /*! \brief Instruct ChronoSync to publish an update.
   *
   * This function instructs sync to push an update into the network,
   * based on whatever the state of the sequencing manager is when
   * this is called. Since each ChronoSync instance maintains its own
   * PIT, doing this satisfies those interests so that other routers
   * know a sync update is available.
   * \sa publishSyncUpdate
   */
  void
  publishRoutingUpdate(const Lsa::Type& type, const uint64_t& seqNo);

  /*! \brief Create and configure a socket to enable ChronoSync for this NLSR.
   *
   * In a typical situation this only needs to be called once, when NLSR starts.
   * \param syncPrefix The sync prefix you want this ChronoSync to use
   * \sa Nlsr::initialize
   */
  void
  createSyncSocket(const ndn::Name& syncPrefix);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  /*! \brief Simple function to glue Name components together
   */
  void
  buildUpdatePrefix();

private:
  /*! \brief Determine which kind of LSA was updated and fetch it.
   *
   * Checks that the received update is not from us, which can happen,
   * and then inspects the update to determine which kind of LSA the
   * update is for. Finally, it expresses interest for the correct LSA
   * type.
   * \throws SyncUpdate::Error If the sync update doesn't look like a sync LSA update.
   */
  void
  processUpdateFromSync(const ndn::Name& originRouter,
                        const ndn::Name& updateName, const uint64_t& seqNo);

  /*! \brief Instruct ChronoSync, via the sync socket, to publish an update.
   *
   * Each ChronoSync instance maintains its own PIT for sync
   * updates. This function creates a data that satisfies that update,
   * so that the interested routers will know new data is available.
   */
  void
  publishSyncUpdate(const ndn::Name& updatePrefix, uint64_t seqNo);

public:
  std::unique_ptr<OnNewLsa> onNewLsa;

private:
  ndn::Face& m_syncFace;
  std::shared_ptr<chronosync::Socket> m_syncSocket;
  ndn::Name m_syncPrefix;
  IsLsaNew m_isLsaNew;
  const ConfParameter& m_confParam;

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  ndn::Name m_nameLsaUserPrefix;
  ndn::Name m_adjLsaUserPrefix;
  ndn::Name m_coorLsaUserPrefix;

private:
  static const std::string NLSR_COMPONENT;
  static const std::string LSA_COMPONENT;

};

} // namespace nlsr

#endif // NLSR_SYNC_LOGIC_HANDLER_HPP
