/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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/lsa.hpp"
#include "lsa/name-lsa.hpp"
#include "lsa/coordinate-lsa.hpp"
#include "lsa/adj-lsa.hpp"
#include "sequencing-manager.hpp"
#include "test-access-control.hpp"
#include "communication/sync-logic-handler.hpp"
#include "statistics.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 <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/composite_key.hpp>

#include <PSync/segment-publisher.hpp>

namespace nlsr {

namespace bmi = boost::multi_index;

static constexpr ndn::time::seconds GRACE_PERIOD = 10_s;

enum class LsdbUpdate {
  INSTALLED,
  UPDATED,
  REMOVED
};

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

  ~Lsdb()
  {
    for (const auto& sp : m_fetchers) {
      sp->stop();
    }
  }

  /*! \brief Returns whether the LSDB contains some LSA.
   */
  bool
  doesLsaExist(const ndn::Name& router, Lsa::Type lsaType)
  {
    return m_lsdb.get<byName>().find(std::make_tuple(router, lsaType)) != m_lsdb.end();
  }

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

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

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

  void
  writeLog() const;

  /* \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
  getIsBuildAdjLsaScheduled() const
  {
    return m_isBuildAdjLsaScheduled;
  }

  SyncLogicHandler&
  getSync()
  {
    return m_sync;
  }

  template<typename T>
  std::shared_ptr<T>
  findLsa(const ndn::Name& router) const
  {
    return std::static_pointer_cast<T>(findLsa(router, T::type()));
  }

  struct name_hash {
    int
    operator()(const ndn::Name& name) const {
      return std::hash<ndn::Name>{}(name);
    }
  };

  struct enum_class_hash {
    template<typename T>
    int
    operator()(T t) const {
      return static_cast<int>(t);
    }
  };

  struct byName{};
  struct byType{};

  using LsaContainer = boost::multi_index_container<
    std::shared_ptr<Lsa>,
    bmi::indexed_by<
      bmi::hashed_unique<
        bmi::tag<byName>,
        bmi::composite_key<
          Lsa,
          bmi::const_mem_fun<Lsa, ndn::Name, &Lsa::getOriginRouterCopy>,
          bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>
        >,
        bmi::composite_key_hash<name_hash, enum_class_hash>
      >,
      bmi::hashed_non_unique<
        bmi::tag<byType>,
        bmi::const_mem_fun<Lsa, Lsa::Type, &Lsa::getType>,
        enum_class_hash
      >
    >
  >;

  template<typename T>
  std::pair<LsaContainer::index<Lsdb::byType>::type::iterator,
            LsaContainer::index<Lsdb::byType>::type::iterator>
  getLsdbIterator() const
  {
    return m_lsdb.get<byType>().equal_range(T::type());
  }

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  std::shared_ptr<Lsa>
  findLsa(const ndn::Name& router, Lsa::Type lsaType) const
  {
    auto it = m_lsdb.get<byName>().find(std::make_tuple(router, lsaType));
    return it != m_lsdb.end() ? *it : nullptr;
  }

  void
  incrementDataSentStats(Lsa::Type lsaType) {
    if (lsaType == Lsa::Type::NAME) {
      lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
    }
    else if (lsaType == Lsa::Type::ADJACENCY) {
      lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
    }
    else if (lsaType == Lsa::Type::COORDINATE) {
      lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
    }
  }

  void
  incrementInterestRcvdStats(Lsa::Type lsaType) {
    if (lsaType == Lsa::Type::NAME) {
      lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
    }
    else if (lsaType == Lsa::Type::ADJACENCY) {
      lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
    }
    else if (lsaType == Lsa::Type::COORDINATE) {
      lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
    }
  }

  void
  incrementInterestSentStats(Lsa::Type lsaType) {
    if (lsaType == Lsa::Type::NAME) {
      lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
    }
    else if (lsaType == Lsa::Type::ADJACENCY) {
      lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
    }
    else if (lsaType == Lsa::Type::COORDINATE) {
      lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
    }
  }

  /*! Returns whether a seq. no. from a certain router signals a new LSA.
    \param originRouter The name of the originating router.
    \param lsaType The type of the LSA.
    \param seqNo The sequence number to check.
  */
  bool
  isLsaNew(const ndn::Name& originRouter, const Lsa::Type& lsaType, uint64_t lsSeqNo)
  {
    // Is the name in the LSDB and the supplied seq no is the highest so far
    auto lsaPtr = findLsa(originRouter, lsaType);
    return lsaPtr ? lsaPtr->getSeqNo() < lsSeqNo : true;
  }

  void
  installLsa(std::shared_ptr<Lsa> lsa);

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

    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.
   */
  void
  removeLsa(const ndn::Name& router, Lsa::Type lsaType);

  void
  removeLsa(const LsaContainer::index<Lsdb::byName>::type::iterator& lsaIt);

  /*! \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 Wrapper event to build and install an adj. LSA for this router. */
  void
  buildAndInstallOwnAdjLsa();

  /*! \brief Schedules a refresh/expire event in the scheduler.
    \param lsa The LSA.
    \param expTime How many seconds to wait before triggering the event.
   */
  ndn::scheduler::EventId
  scheduleLsaExpiration(std::shared_ptr<Lsa> lsa, ndn::time::seconds expTime);

  /*! \brief Either allow to expire, or refresh a name LSA.
    \param lsa The LSA.
  */
  void
  expireOrRefreshLsa(std::shared_ptr<Lsa> lsa);

  bool
  processInterestForLsa(const ndn::Interest& interest, const ndn::Name& originRouter,
                        Lsa::Type lsaType, uint64_t seqNo);

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

  /*!
     \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& bufferPtr, const ndn::Name& interestName);

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

  ndn::time::system_clock::TimePoint
  getLsaExpirationTimePoint() const
  {
    return ndn::time::system_clock::now() + ndn::time::seconds(m_confParam.getRouterDeadInterval());
  }

public:
  ndn::util::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
  ndn::util::Signal<Lsdb, ndn::Data> afterSegmentValidatedSignal;
  using AfterLsdbModified = ndn::util::Signal<Lsdb, std::shared_ptr<Lsa>, LsdbUpdate,
                                              std::list<ndn::Name>, std::list<ndn::Name>>;
  AfterLsdbModified onLsdbModified;

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

  ConfParameter& m_confParam;

  SyncLogicHandler m_sync;

  LsaContainer m_lsdb;

  ndn::time::seconds m_lsaRefreshTime;
  ndn::time::seconds m_adjLsaBuildInterval;
  const ndn::Name& m_thisRouterPrefix;

  // Maps the name of an LSA to its highest known sequence number from sync;
  // Used to stop NLSR from trying to fetch outdated LSAs
  std::map<ndn::Name, uint64_t> m_highestSeqNo;

  SequencingManager m_sequencingManager;

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

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

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

  ndn::InMemoryStoragePersistent m_lsaStorage;

  const ndn::Name::Component NAME_COMPONENT = ndn::Name::Component("lsdb");
  static const ndn::time::steady_clock::TimePoint DEFAULT_LSA_RETRIEVAL_DEADLINE;
};

} // namespace nlsr

#endif // NLSR_LSDB_HPP
