/* -*- 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/>.
 **/

#include "nlsr.hpp"
#include "adjacent.hpp"
#include "logger.hpp"

#include <cstdlib>
#include <string>
#include <sstream>
#include <cstdio>
#include <unistd.h>
#include <vector>

#include <ndn-cxx/net/face-uri.hpp>
#include <ndn-cxx/signature.hpp>

namespace nlsr {

INIT_LOGGER(Nlsr);

const ndn::Name Nlsr::LOCALHOST_PREFIX = ndn::Name("/localhost/nlsr");

Nlsr::Nlsr(ndn::Face& face, ndn::KeyChain& keyChain, ConfParameter& confParam)
  : m_face(face)
  , m_scheduler(face.getIoService())
  , m_keyChain(keyChain)
  , m_confParam(confParam)
  , m_adjacencyList(confParam.getAdjacencyList())
  , m_namePrefixList(confParam.getNamePrefixList())
  , m_validator(m_confParam.getValidator())
  , m_fib(m_face, m_scheduler, m_adjacencyList, m_confParam, m_keyChain)
  , m_routingTable(m_scheduler, m_fib, m_lsdb, m_namePrefixTable, m_confParam)
  , m_namePrefixTable(m_fib, m_routingTable, m_routingTable.afterRoutingChange)
  , m_lsdb(m_face, m_keyChain, m_confParam, m_namePrefixTable, m_routingTable)
  , m_helloProtocol(m_face, m_keyChain, confParam, m_routingTable, m_lsdb)
  , m_onNewLsaConnection(m_lsdb.getSync().onNewLsa->connect(
      [this] (const ndn::Name& updateName, uint64_t sequenceNumber,
              const ndn::Name& originRouter) {
        registerStrategyForCerts(originRouter);
      }))
  , m_onPrefixRegistrationSuccess(m_fib.onPrefixRegistrationSuccess.connect(
      [this] (const ndn::Name& name) {
        m_helloProtocol.sendHelloInterest(name);
      }))
  , m_onHelloDataValidated(m_helloProtocol.onHelloDataValidated.connect(
      [this] (const ndn::Name& neighbor) {
        auto it = m_adjacencyList.findAdjacent(neighbor);
        if (it != m_adjacencyList.end()) {
          m_fib.registerPrefix(m_confParam.getSyncPrefix(), it->getFaceUri(), it->getLinkCost(),
                               ndn::time::milliseconds::max(), ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
        }
      }))
  , m_dispatcher(m_face, m_keyChain)
  , m_datasetHandler(m_dispatcher, m_lsdb, m_routingTable)
  , m_controller(m_face, m_keyChain)
  , m_faceDatasetController(m_face, m_keyChain)
  , m_prefixUpdateProcessor(m_dispatcher,
      m_confParam.getPrefixUpdateValidator(),
      m_namePrefixList,
      m_lsdb,
      m_confParam.getConfFileNameDynamic())
  , m_nfdRibCommandProcessor(m_dispatcher,
      m_namePrefixList,
      m_lsdb)
  , m_statsCollector(m_lsdb, m_helloProtocol)
  , m_faceMonitor(m_face)
{
  NLSR_LOG_DEBUG("Initializing Nlsr");

  m_faceMonitor.onNotification.connect(std::bind(&Nlsr::onFaceEventNotification, this, _1));
  m_faceMonitor.start();

  // Do key initialization and registrations first, then initialize faces
  // which will create routes to neighbor

  setStrategies();

  NLSR_LOG_DEBUG("Default NLSR identity: " << m_confParam.getSigningInfo().getSignerName());

  // Can be moved to HelloProtocol and Lsdb ctor if initializeKey is set
  // earlier in the Nlsr constructor so as to set m_signingInfo
  setInfoInterestFilter();
  setLsaInterestFilter();

  // Add top-level prefixes: router and localhost prefix
  addDispatcherTopPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"));
  addDispatcherTopPrefix(LOCALHOST_PREFIX);

  enableIncomingFaceIdIndication();

  registerLocalhostPrefix();
  registerRouterPrefix();

  initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
                  std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));

  // Could be moved into ctor, but unit tests need to be modified
  initialize();
}

void
Nlsr::registerStrategyForCerts(const ndn::Name& originRouter)
{
  for (const ndn::Name& router : m_strategySetOnRouters) {
    if (router == originRouter) {
      // Have already set strategy for this router's certs once
      return;
    }
  }

  m_strategySetOnRouters.push_back(originRouter);

  ndn::Name routerKey(originRouter);
  routerKey.append("KEY");
  ndn::Name instanceKey(originRouter);
  instanceKey.append("nlsr").append("KEY");

  m_fib.setStrategy(routerKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);
  m_fib.setStrategy(instanceKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);

  ndn::Name siteKey;
  for (size_t i = 0; i < originRouter.size(); ++i) {
    if (originRouter[i].toUri() == "%C1.Router") {
      break;
    }
    siteKey.append(originRouter[i]);
  }
  ndn::Name opPrefix(siteKey);
  siteKey.append("KEY");
  m_fib.setStrategy(siteKey, Fib::BEST_ROUTE_V2_STRATEGY, 0);

  opPrefix.append(std::string("%C1.Operator"));
  m_fib.setStrategy(opPrefix, Fib::BEST_ROUTE_V2_STRATEGY, 0);
}

void
Nlsr::registrationFailed(const ndn::Name& name)
{
  NLSR_LOG_ERROR("ERROR: Failed to register prefix " << name << " in local hub's daemon");
  BOOST_THROW_EXCEPTION(Error("Error: Prefix registration failed"));
}

void
Nlsr::onRegistrationSuccess(const ndn::Name& name)
{
  NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
}

void
Nlsr::setInfoInterestFilter()
{
  ndn::Name name(m_confParam.getRouterPrefix());
  name.append("nlsr");
  name.append("INFO");

  NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);

  m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
                           std::bind(&HelloProtocol::processInterest, &m_helloProtocol, _1, _2),
                           std::bind(&Nlsr::onRegistrationSuccess, this, _1),
                           std::bind(&Nlsr::registrationFailed, this, _1),
                           m_confParam.getSigningInfo(), ndn::nfd::ROUTE_FLAG_CAPTURE);
}

void
Nlsr::setLsaInterestFilter()
{
  ndn::Name name = m_confParam.getLsaPrefix();

  NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);

  m_face.setInterestFilter(ndn::InterestFilter(name).allowLoopback(false),
                           std::bind(&Lsdb::processInterest, &m_lsdb, _1, _2),
                           std::bind(&Nlsr::onRegistrationSuccess, this, _1),
                           std::bind(&Nlsr::registrationFailed, this, _1),
                           m_confParam.getSigningInfo(), ndn::nfd::ROUTE_FLAG_CAPTURE);
}

void
Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
{
  try {
    // false since we want to have control over the registration process
    m_dispatcher.addTopPrefix(topPrefix, false, m_confParam.getSigningInfo());
  }
  catch (const std::exception& e) {
    NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
  }
}

void
Nlsr::setStrategies()
{
  m_fib.setStrategy(m_confParam.getLsaPrefix(), Fib::MULTICAST_STRATEGY, 0);
  m_fib.setStrategy(m_confParam.getSyncPrefix(), Fib::MULTICAST_STRATEGY, 0);
}

void
Nlsr::initialize()
{
  // Logging start
  m_adjacencyList.writeLog();
  NLSR_LOG_DEBUG(m_namePrefixList);

  m_lsdb.buildAndInstallOwnNameLsa();

  // Install coordinate LSAs if using HR or dry-run HR.
  if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
    m_lsdb.buildAndInstallOwnCoordinateLsa();
  }

  // Need to set direct neighbors' costs to 0 for hyperbolic routing
  if (m_confParam.getHyperbolicState() == HYPERBOLIC_STATE_ON) {
    for (auto&& neighbor : m_adjacencyList.getAdjList()) {
      neighbor.setLinkCost(0);
    }
  }
}

void
Nlsr::registerLocalhostPrefix()
{
  m_face.registerPrefix(LOCALHOST_PREFIX,
                        std::bind(&Nlsr::onRegistrationSuccess, this, _1),
                        std::bind(&Nlsr::registrationFailed, this, _1));
}

void
Nlsr::registerRouterPrefix()
{
  m_face.registerPrefix(ndn::Name(m_confParam.getRouterPrefix()).append("nlsr"),
                        std::bind(&Nlsr::onRegistrationSuccess, this, _1),
                        std::bind(&Nlsr::registrationFailed, this, _1));
}

void
Nlsr::onFaceEventNotification(const ndn::nfd::FaceEventNotification& faceEventNotification)
{
  NLSR_LOG_TRACE("Nlsr::onFaceEventNotification called");

  switch (faceEventNotification.getKind()) {
    case ndn::nfd::FACE_EVENT_DESTROYED: {
      uint64_t faceId = faceEventNotification.getFaceId();

      auto adjacent = m_adjacencyList.findAdjacent(faceId);

      if (adjacent != m_adjacencyList.end()) {
        NLSR_LOG_DEBUG("Face to " << adjacent->getName() << " with face id: " << faceId << " destroyed");

        adjacent->setFaceId(0);

        // Only trigger an Adjacency LSA build if this node is changing
        // from ACTIVE to INACTIVE since this rebuild will effectively
        // cancel the previous Adjacency LSA refresh event and schedule
        // a new one further in the future.
        //
        // Continuously scheduling the refresh in the future will block
        // the router from refreshing its Adjacency LSA. Since other
        // routers' Name prefixes' expiration times are updated when
        // this router refreshes its Adjacency LSA, the other routers'
        // prefixes will expire and be removed from the RIB.
        //
        // This check is required to fix Bug #2733 for now. This check
        // would be unnecessary to fix Bug #2733 when Issue #2732 is
        // completed, but the check also helps with optimization so it
        // can remain even when Issue #2732 is implemented.
        if (adjacent->getStatus() == Adjacent::STATUS_ACTIVE) {
          adjacent->setStatus(Adjacent::STATUS_INACTIVE);

          // A new adjacency LSA cannot be built until the neighbor is marked INACTIVE and
          // has met the HELLO retry threshold
          adjacent->setInterestTimedOutNo(m_confParam.getInterestRetryNumber());

          if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
            m_routingTable.scheduleRoutingTableCalculation();
          }
          else {
            m_lsdb.scheduleAdjLsaBuild();
          }
        }
      }
      break;
    }
    case ndn::nfd::FACE_EVENT_CREATED: {
      // Find the neighbor in our adjacency list
      ndn::FaceUri faceUri;
      try {
        faceUri = ndn::FaceUri(faceEventNotification.getRemoteUri());
      }
      catch (const std::exception& e) {
        NLSR_LOG_WARN(e.what());
        return;
      }
      auto adjacent = m_adjacencyList.findAdjacent(faceUri);
      uint64_t faceId = faceEventNotification.getFaceId();

      // If we have a neighbor by that FaceUri and it has no FaceId or
      // the FaceId is different from ours, we have a match.
      if (adjacent != m_adjacencyList.end() &&
          (adjacent->getFaceId() == 0 || adjacent->getFaceId() != faceId))
      {
        NLSR_LOG_DEBUG("Face creation event matches neighbor: " << adjacent->getName()
                        << ". New Face ID: " << faceId << ". Registering prefixes.");
        adjacent->setFaceId(faceId);

        registerAdjacencyPrefixes(*adjacent, ndn::time::milliseconds::max());

        if (m_confParam.getHyperbolicState() != HYPERBOLIC_STATE_OFF) {
          m_routingTable.scheduleRoutingTableCalculation();
        }
        else {
         m_lsdb.scheduleAdjLsaBuild();
        }
      }
      break;
    }
    default:
      break;
  }
}

void
Nlsr::initializeFaces(const FetchDatasetCallback& onFetchSuccess,
                      const FetchDatasetTimeoutCallback& onFetchFailure)
{
  NLSR_LOG_TRACE("Initializing Faces...");

  m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(onFetchSuccess, onFetchFailure);

}

void
Nlsr::processFaceDataset(const std::vector<ndn::nfd::FaceStatus>& faces)
{
  NLSR_LOG_DEBUG("Processing face dataset");

  // Iterate over each neighbor listed in nlsr.conf
  for (auto&& adjacent : m_adjacencyList.getAdjList()) {

    const std::string& faceUriString = adjacent.getFaceUri().toString();
    // Check the list of FaceStatus objects we got for a match
    for (const auto& faceStatus : faces) {
      // Set the adjacency FaceID if we find a URI match and it was
      // previously unset. Change the boolean to true.
      if (adjacent.getFaceId() == 0 && faceUriString == faceStatus.getRemoteUri()) {
        NLSR_LOG_DEBUG("FaceUri: " << faceStatus.getRemoteUri() <<
                   " FaceId: "<< faceStatus.getFaceId());
        adjacent.setFaceId(faceStatus.getFaceId());
        // Register the prefixes for each neighbor
        this->registerAdjacencyPrefixes(adjacent, ndn::time::milliseconds::max());
      }
    }
    // If this adjacency has no information in this dataset, then one
    // of two things is happening: 1. NFD is starting slowly and this
    // Face wasn't ready yet, or 2. NFD is configured
    // incorrectly and this Face isn't available.
    if (adjacent.getFaceId() == 0) {
      NLSR_LOG_WARN("The adjacency " << adjacent.getName() <<
                " has no Face information in this dataset.");
    }
  }

  scheduleDatasetFetch();
}

void
Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
                                const ndn::time::milliseconds& timeout)
{
  ndn::FaceUri faceUri = adj.getFaceUri();
  double linkCost = adj.getLinkCost();
  const ndn::Name& adjName = adj.getName();

  m_fib.registerPrefix(adjName, faceUri, linkCost,
                       timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);

  m_fib.registerPrefix(m_confParam.getLsaPrefix(),
                       faceUri, linkCost, timeout,
                       ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
}

void
Nlsr::onFaceDatasetFetchTimeout(uint32_t code,
                                const std::string& msg,
                                uint32_t nRetriesSoFar)
{
  NLSR_LOG_DEBUG("onFaceDatasetFetchTimeout");
  // If we have exceeded the maximum attempt count, do not try again.
  if (nRetriesSoFar++ < m_confParam.getFaceDatasetFetchTries()) {
    NLSR_LOG_DEBUG("Failed to fetch dataset: " << msg << ". Attempting retry #" << nRetriesSoFar);
    m_faceDatasetController.fetch<ndn::nfd::FaceDataset>(std::bind(&Nlsr::processFaceDataset,
                                                        this, _1),
                                              std::bind(&Nlsr::onFaceDatasetFetchTimeout,
                                                        this, _1, _2, nRetriesSoFar));
  }
  else {
    NLSR_LOG_ERROR("Failed to fetch dataset: " << msg << ". Exceeded limit of " <<
               m_confParam.getFaceDatasetFetchTries() << ", so not trying again this time.");
    // If we fail to fetch it, just do nothing until the next
    // interval.  Since this is a backup mechanism, we aren't as
    // concerned with retrying.
    scheduleDatasetFetch();
  }
}

void
Nlsr::scheduleDatasetFetch()
{
  NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());

  m_scheduler.schedule(m_confParam.getFaceDatasetFetchInterval(),
    [this] {
      this->initializeFaces(
        [this] (const std::vector<ndn::nfd::FaceStatus>& faces) {
         this->processFaceDataset(faces);
        },
        [this] (uint32_t code, const std::string& msg) {
         this->onFaceDatasetFetchTimeout(code, msg, 0);
        });
  });
}

void
Nlsr::enableIncomingFaceIdIndication()
{
  NLSR_LOG_DEBUG("Enabling incoming face id indication for local face.");

  m_controller.start<ndn::nfd::FaceUpdateCommand>(
    ndn::nfd::ControlParameters()
      .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
    bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
    bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
}

void
Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
{
  NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
                 << "for face id " << cp.getFaceId());
}

void
Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
{
  std::ostringstream os;
  os << "Failed to enable incoming face id indication feature: " <<
        "(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";

  NLSR_LOG_DEBUG(os.str());
}

} // namespace nlsr
