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

#include "conf-parameter.hpp"
#include "lsa.hpp"
#include "sequencing-manager.hpp"
#include "test-access-control.hpp"
#include "communication/sync-logic-handler.hpp"
#include "statistics.hpp"
#include "route/name-prefix-table.hpp"

#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/util/time.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>

#include <PSync/segment-publisher.hpp>

#include <utility>
#include <boost/cstdint.hpp>

namespace nlsr {

class Lsdb
{
public:
  Lsdb(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam,
       NamePrefixTable& namePrefixTable, RoutingTable& routingTable);

  ~Lsdb();

  bool
  isLsaNew(const ndn::Name& routerName, const Lsa::Type& lsaType, const uint64_t& sequenceNumber);

  bool
  doesLsaExist(const ndn::Name& key, const Lsa::Type& lsType);

  /*! \brief Builds a name LSA for this router and then installs it
      into the LSDB.
  */
  bool
  buildAndInstallOwnNameLsa();

  /*! \brief Returns the name LSA with the given key.
    \param key The name of the router that the desired LSA comes from.
  */
  NameLsa*
  findNameLsa(const ndn::Name& key);

  /*! \brief Installs a name LSA into the LSDB
    \param nlsa The name LSA to install into the LSDB.
  */
  bool
  installNameLsa(NameLsa& nlsa);

  /*! \brief Remove a name LSA from the LSDB.
    \param key The name of the router that published the LSA to remove.

    This function will remove a name LSA from the LSDB by finding an
    LSA whose name matches key. This removal also causes the NPT to
    remove those name prefixes if no more LSAs advertise them.
   */
  bool
  removeNameLsa(const ndn::Name& key);

  /*! Returns whether a seq. no. from a certain router signals a new LSA.
    \param key The name of the originating router.
    \param seqNo The sequence number to check.
  */
  bool
  isNameLsaNew(const ndn::Name& key, uint64_t seqNo);

  void
  writeNameLsdbLog();

  const std::list<NameLsa>&
  getNameLsdb() const;

  /*! \brief Builds a cor. LSA for this router and installs it into the LSDB. */
  bool
  buildAndInstallOwnCoordinateLsa();

  /*! \brief Finds a cor. LSA in the LSDB.
    \param key The name of the originating router that published the LSA.
  */
  CoordinateLsa*
  findCoordinateLsa(const ndn::Name& key);

  /*! \brief Installs a cor. LSA into the LSDB.
    \param clsa The cor. LSA to install.
  */
  bool
  installCoordinateLsa(CoordinateLsa& clsa);

  /*! \brief Removes a cor. LSA from the LSDB.
    \param key The name of the router that published the LSA to remove.

    Removes the coordinate LSA whose origin router name matches that
    given by key. Additionally, ask the NPT to remove the prefix,
    which will occur if no other LSAs point there.
  */
  bool
  removeCoordinateLsa(const ndn::Name& key);

  /*! \brief Returns whether a cor. LSA from a router is new or not.
    \param key The name prefix of the originating router.
    \param seqNo The sequence number of the candidate LSA.
  */
  bool
  isCoordinateLsaNew(const ndn::Name& key, uint64_t seqNo);

  void
  writeCorLsdbLog();

  const std::list<CoordinateLsa>&
  getCoordinateLsdb() const;

  //function related to Adj LSDB

  /*! \brief Schedules a build of this router's LSA. */
  void
  scheduleAdjLsaBuild();

  /*! \brief Wrapper event to build and install an adj. LSA for this router. */
  bool
  buildAndInstallOwnAdjLsa();

  /*! \brief Removes an adj. LSA from the LSDB.
    \param key The name of the publishing router whose LSA to remove.
  */
  bool
  removeAdjLsa(const ndn::Name& key);

  /*! \brief Returns whether an LSA is new.
    \param key The name of the publishing router.
    \param seqNo The seq. no. of the candidate LSA.

    This function determines whether the LSA with the name key and
    seq. no. seqNo would be new to this LSDB.
  */
  bool
  isAdjLsaNew(const ndn::Name& key, uint64_t seqNo);

  /*! \brief Installs an adj. LSA into the LSDB.
    \param alsa The adj. LSA to add to the LSDB.
  */
  bool
  installAdjLsa(AdjLsa& alsa);

  /*! \brief Finds an adj. LSA in the LSDB.
    \param key The name of the publishing router whose LSA to find.
   */
  AdjLsa*
  findAdjLsa(const ndn::Name& key);

  const std::list<AdjLsa>&
  getAdjLsdb() const;

  void
  setAdjLsaBuildInterval(uint32_t interval)
  {
    m_adjLsaBuildInterval = ndn::time::seconds(interval);
  }

  void
  writeAdjLsdbLog();

  void
  expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
                  ndn::time::steady_clock::TimePoint deadline = DEFAULT_LSA_RETRIEVAL_DEADLINE);

  /* \brief Process interest which can be either:
   * 1) Discovery interest from segment fetcher:
   *    /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>
   * 2) Interest containing segment number:
   *    /localhop/<network>/nlsr/LSA/<site>/<router>/<lsaType>/<seqNo>/<version>/<segmentNo>
  */
  void
  processInterest(const ndn::Name& name, const ndn::Interest& interest);

  bool
  getIsBuildAdjLsaSheduled()
  {
    return m_isBuildAdjLsaSheduled;
  }

  SyncLogicHandler&
  getSync() {
    return m_sync;
  }

private:
  /* \brief Add a name LSA to the LSDB if it isn't already there.
     \param nlsa The candidade name LSA.
  */
  bool
  addNameLsa(NameLsa& nlsa);

  /*! \brief Returns whether the LSDB contains some LSA.
    \param key The name of the publishing router whose LSA to check for.
   */
  bool
  doesNameLsaExist(const ndn::Name& key);

  /*! \brief Adds a cor. LSA to the LSDB if it isn't already there.
    \param clsa The candidate cor. LSA.
  */
  bool
  addCoordinateLsa(CoordinateLsa& clsa);

  /*! \brief Returns whether a cor. LSA is in the LSDB.
    \param key The name of the router that published the queried LSA.
   */
  bool
  doesCoordinateLsaExist(const ndn::Name& key);

  /*! \brief Attempts to construct an adj. LSA.

    This function will attempt to construct an adjacency LSA. An LSA
    can only be built when the status of all of the router's neighbors
    is known. That is, when we are not currently trying to contact any
    neighbor.
   */
  void
  buildAdjLsa();

  /*! \brief Adds an adj. LSA to the LSDB if it isn't already there.
    \param alsa The candidate adj. LSA to add to the LSDB.
  */
  bool
  addAdjLsa(AdjLsa& alsa);

  /*! \brief Returns whether the LSDB contains an LSA.
    \param key The name of a router whose LSA to check for in the LSDB.
  */
  bool
  doesAdjLsaExist(const ndn::Name& key);

  /*! \brief Schedules a refresh/expire event in the scheduler.
    \param key The name of the router that published the LSA.
    \param seqNo The seq. no. associated with the LSA.
    \param expTime How many seconds to wait before triggering the event.
   */
  ndn::scheduler::EventId
  scheduleNameLsaExpiration(const ndn::Name& key, int seqNo,
                            const ndn::time::seconds& expTime);

  /*! \brief Either allow to expire, or refresh a name LSA.
    \param lsaKey The name of the router that published the LSA.
    \param seqNo The seq. no. of the LSA to check.
  */
  void
  expireOrRefreshNameLsa(const ndn::Name& lsaKey, uint64_t seqNo);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  /*! \brief Schedules an expire/refresh event in the LSA.
    \param key The name of the router whose LSA is in question.
    \param seqNo The sequence number of the LSA to check.
    \param expTime The number of seconds to wait before triggering the event.
  */
  ndn::scheduler::EventId
  scheduleAdjLsaExpiration(const ndn::Name& key, int seqNo,
                           const ndn::time::seconds& expTime);

private:
  void
  expireOrRefreshAdjLsa(const ndn::Name& lsaKey, uint64_t seqNo);

  ndn::scheduler::EventId
  scheduleCoordinateLsaExpiration(const ndn::Name& key, int seqNo,
                                  const ndn::time::seconds& expTime);

  void
  expireOrRefreshCoordinateLsa(const ndn::Name& lsaKey,
                               uint64_t seqNo);

  void
  processInterestForNameLsa(const ndn::Interest& interest,
                            const ndn::Name& lsaKey,
                            uint64_t seqNo);

  void
  processInterestForAdjacencyLsa(const ndn::Interest& interest,
                                 const ndn::Name& lsaKey,
                                 uint64_t seqNo);

  void
  processInterestForCoordinateLsa(const ndn::Interest& interest,
                                  const ndn::Name& lsaKey,
                                  uint64_t seqNo);

  void
  onContentValidated(const std::shared_ptr<const ndn::Data>& data);

  void
  processContentNameLsa(const ndn::Name& lsaKey,
                        uint64_t lsSeqNo, std::string& dataContent);

  void
  processContentAdjacencyLsa(const ndn::Name& lsaKey,
                             uint64_t lsSeqNo, std::string& dataContent);

  void
  processContentCoordinateLsa(const ndn::Name& lsaKey,
                              uint64_t lsSeqNo, std::string& dataContent);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  /*!
     \brief Error callback when SegmentFetcher fails to return an LSA

     In all error cases, a reattempt to fetch the LSA will be made.

     Segment validation can fail either because the packet does not have a
     valid signature (fatal) or because some of the certificates in the trust chain
     could not be fetched (non-fatal).

     Currently, the library does not provide clear indication (besides a plain-text message
     in the error callback) of the reason for the failure nor the segment that failed
     to be validated, thus we will continue to try to fetch the LSA until the deadline
     is reached.
   */
  void
  onFetchLsaError(uint32_t errorCode,
                  const std::string& msg,
                  const ndn::Name& interestName,
                  uint32_t retransmitNo,
                  const ndn::time::steady_clock::TimePoint& deadline,
                  ndn::Name lsaName,
                  uint64_t seqNo);

  /*!
     \brief Success callback when SegmentFetcher returns a valid LSA

     \param interestName The base Interest used to fetch the LSA in the format:
            /<network>/NLSR/LSA/<site>/%C1.Router/<router>/<lsa-type>/<seqNo>
   */
  void
  afterFetchLsa(const ndn::ConstBufferPtr& data, const ndn::Name& interestName);

  void
  emitSegmentValidatedSignal(const ndn::Data& data)
  {
    afterSegmentValidatedSignal(data);
  }

private:
  ndn::time::system_clock::TimePoint
  getLsaExpirationTimePoint();

public:
  static const ndn::Name::Component NAME_COMPONENT;

  ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
  ndn::util::signal::Signal<Lsdb, const ndn::Data&> afterSegmentValidatedSignal;

private:
  ndn::Face& m_face;
  ndn::Scheduler m_scheduler;

  ConfParameter& m_confParam;
  NamePrefixTable& m_namePrefixTable;
  RoutingTable& m_routingTable;

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  SyncLogicHandler m_sync;

private:
  std::list<NameLsa> m_nameLsdb;
  std::list<AdjLsa> m_adjLsdb;
  std::list<CoordinateLsa> m_corLsdb;

  ndn::time::seconds m_lsaRefreshTime;
  std::string m_thisRouterPrefix;

  typedef std::map<ndn::Name, uint64_t> SequenceNumberMap;

  // Maps the name of an LSA to its highest known sequence number from sync;
  // Used to stop NLSR from trying to fetch outdated LSAs
  SequenceNumberMap m_highestSeqNo;

  static const ndn::time::seconds GRACE_PERIOD;
  static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  ndn::time::seconds m_adjLsaBuildInterval;

  SequencingManager m_sequencingManager;

private:
  ndn::util::signal::ScopedConnection m_onNewLsaConnection;

  std::set<std::shared_ptr<ndn::util::SegmentFetcher>> m_fetchers;
  psync::SegmentPublisher m_segmentPublisher;

  bool m_isBuildAdjLsaSheduled;
  int64_t m_adjBuildCount;
  ndn::scheduler::ScopedEventId m_scheduledAdjLsaBuild;

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  ndn::InMemoryStoragePersistent m_lsaStorage;
};

} // namespace nlsr

#endif // NLSR_LSDB_HPP
