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

#include "mgmt/rib-manager.hpp"

#include "manager-common-fixture.hpp"
#include "tests/daemon/rib/fib-updates-common.hpp"

#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>

#include <boost/mp11/algorithm.hpp>
#include <boost/property_tree/info_parser.hpp>

namespace nfd::tests {

struct ConfigurationStatus
{
  bool isLocalhostConfigured;
  bool isLocalhopConfigured;
};

static ConfigSection
getValidatorConfigSection()
{
  ConfigSection section;
  section.put("trust-anchor.type", "any");
  return section;
}

static ConfigSection
makeSection(const std::string& config)
{
  std::istringstream inputStream(config);
  ConfigSection section;
  boost::property_tree::read_info(inputStream, section);
  return section;
}

static ConfigSection
getLocalhopValidatorConfigSection()
{
  std::string config = R"CONF(
    rule
    {
      id rule-id1
      for interest
      filter
      {
        type name
        name /localhop/nfd/rib
        relation is-prefix-of
      }
      checker
      {
        type customized
        sig-type ecdsa-sha256
        key-locator
        {
          type name
          name /TrustAnchor-identity/Derived-identity
          relation is-prefix-of
        }
      }
    }
    rule
    {
      id rule-id2
      for data
      filter
      {
        type name
        name /TrustAnchor-identity/Derived-identity/KEY
        relation is-prefix-of
      }
      checker
      {
        type customized
        sig-type ecdsa-sha256
        key-locator
        {
          type name
          name /TrustAnchor-identity
          relation is-prefix-of
        }
      }
    }
    trust-anchor
    {
      type file
      file-name signer.ndncert
    }
  )CONF";
  return makeSection(config);
}

static ConfigSection
getPaValidatorConfigSection()
{
  ConfigSection section;
  section.put("trust-anchor.type", "any");
  return section;
}

class RibManagerFixture : public ManagerCommonFixture
{
public:
  RibManagerFixture(const ConfigurationStatus& status, bool shouldClearRib)
    : m_status(status)
    , m_anchorId("/TrustAnchor-identity")
    , m_derivedId("/TrustAnchor-identity/Derived-identity")
    , m_nfdController(m_face, m_keyChain)
    , m_fibUpdater(m_rib, m_nfdController)
    , m_manager(m_rib, m_face, m_keyChain, m_nfdController, m_dispatcher)
  {
    auto anchorIdentity = m_keyChain.createIdentity(m_anchorId);
    saveIdentityCert(m_anchorId, "signer.ndncert", true);

    auto derivedKey = m_keyChain.createIdentity(m_derivedId).getDefaultKey();
    auto derivedSelfSigned = derivedKey.getDefaultCertificate();
    ndn::security::MakeCertificateOptions opts;
    opts.validity = derivedSelfSigned.getValidityPeriod();
    auto derivedCert = m_keyChain.makeCertificate(derivedSelfSigned,
                                                  ndn::security::signingByIdentity(anchorIdentity),
                                                  opts);
    m_keyChain.setDefaultCertificate(derivedKey, derivedCert);

    if (m_status.isLocalhostConfigured) {
      m_manager.applyLocalhostConfig(getValidatorConfigSection(), "test");
    }

    if (m_status.isLocalhopConfigured) {
      m_manager.enableLocalhop(getLocalhopValidatorConfigSection(), "test");
    }
    else {
      m_manager.disableLocalhop();
    }

    m_manager.applyPaConfig(getPaValidatorConfigSection(), "testPa");

    registerWithNfd();

    if (shouldClearRib) {
      clearRib();
    }

    m_face.onSendInterest.connect([=] (const Interest& interest) {
      if (interest.matchesData(derivedCert) &&
          m_status.isLocalhopConfigured &&
          interest.getTag<lp::NextHopFaceIdTag>() != nullptr) {
        m_face.put(derivedCert);
      }
    });
  }

private:
  void
  registerWithNfd()
  {
    m_manager.registerWithNfd();
    advanceClocks(1_ms);

    auto replyFibAddCommand = [this] (const Interest& interest) {
      ControlParameters params(interest.getName().at(4).blockFromValue());
      BOOST_CHECK(params.getName() == "/localhost/nfd/rib" || params.getName() == "/localhop/nfd/rib");
      params.setFaceId(1).setCost(0);
      ControlResponse resp = makeResponse(200, "OK", params);

      auto data = make_shared<Data>(interest.getName());
      data->setContent(resp.wireEncode());
      m_keyChain.sign(*data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));

      boost::asio::post(m_face.getIoContext(), [this, data] { m_face.receive(*data); });
    };

    const Name commandPrefix = Name("/localhost/nfd").append(ndn::nfd::FibAddNextHopCommand::getName());
    for (const auto& command : m_face.sentInterests) {
      if (commandPrefix.isPrefixOf(command.getName())) {
        replyFibAddCommand(command);
        advanceClocks(1_ms);
      }
    }

    // clear commands and responses
    m_responses.clear();
    m_face.sentInterests.clear();
  }

  void
  clearRib()
  {
    while (!m_rib.empty()) {
      m_rib.erase(m_rib.begin()->first, *m_rib.begin()->second->begin());
    }
  }

public:
  static ControlParameters
  makeRegisterParameters(const Name& name, uint64_t faceId = 0,
                         time::milliseconds expiry = time::milliseconds::max())
  {
    return ControlParameters()
      .setName(name)
      .setFaceId(faceId)
      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR)
      .setCost(10)
      .setFlags(0)
      .setExpirationPeriod(expiry);
  }

  static ControlParameters
  makeUnregisterParameters(const Name& name, uint64_t faceId = 0)
  {
    return ControlParameters()
      .setName(name)
      .setFaceId(faceId)
      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR);
  }

protected:
  static inline const Name REG_REQUEST = Name("/localhost/nfd").append(ndn::nfd::RibRegisterCommand::getName());
  static inline const Name UNREG_REQUEST = Name("/localhost/nfd").append(ndn::nfd::RibUnregisterCommand::getName());
  static inline const Name ANNOUNCE_REQUEST = Name("/localhost/nfd").append(ndn::nfd::RibAnnounceCommand::getName());

  ConfigurationStatus m_status;
  Name m_anchorId;
  Name m_derivedId;

  ndn::nfd::Controller m_nfdController;
  rib::Rib m_rib;
  MockFibUpdater m_fibUpdater;
  RibManager m_manager;
};

BOOST_AUTO_TEST_SUITE(Mgmt)
BOOST_AUTO_TEST_SUITE(TestRibManager)

class AddTopPrefixFixture : public RibManagerFixture
{
public:
  AddTopPrefixFixture()
    : RibManagerFixture({true, true}, false)
  {
  }
};

BOOST_FIXTURE_TEST_CASE(AddTopPrefix, AddTopPrefixFixture)
{
  BOOST_REQUIRE_EQUAL(m_rib.size(), 2);

  std::vector<Name> ribEntryNames;
  for (auto&& entry : m_rib) {
    ribEntryNames.push_back(entry.first);
  }
  BOOST_CHECK_EQUAL(ribEntryNames[0], "/localhop/nfd");
  BOOST_CHECK_EQUAL(ribEntryNames[1], "/localhost/nfd");
}

class UnauthorizedRibManagerFixture : public RibManagerFixture
{
public:
  UnauthorizedRibManagerFixture()
    : RibManagerFixture({false, false}, true)
  {
  }
};

class LocalhostAuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  LocalhostAuthorizedRibManagerFixture()
    : RibManagerFixture({true, false}, true)
  {
  }
};

class LocalhopAuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  LocalhopAuthorizedRibManagerFixture()
    : RibManagerFixture({false, true}, true)
  {
  }
};

class AuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  AuthorizedRibManagerFixture()
    : RibManagerFixture({true, true}, true)
  {
  }
};

template<typename Fixture, typename Format>
struct FixtureWithFormat : public Fixture
{
  static constexpr ndn::security::SignedInterestFormat signedInterestFmt = Format::value;
};

using AllFixtures = boost::mp11::mp_product<
  FixtureWithFormat,
  boost::mp11::mp_list<UnauthorizedRibManagerFixture,
                       LocalhostAuthorizedRibManagerFixture,
                       LocalhopAuthorizedRibManagerFixture,
                       AuthorizedRibManagerFixture>,
  boost::mp11::mp_list_c<ndn::security::SignedInterestFormat,
                         ndn::security::SignedInterestFormat::V02,
                         ndn::security::SignedInterestFormat::V03>
>;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(CommandAuthorization, T, AllFixtures, T)
{
  auto parameters  = this->makeRegisterParameters("/test-authorization", 9527);
  auto commandHost = this->makeControlCommandRequest(this->REG_REQUEST, parameters, T::signedInterestFmt);
  auto commandHop  = this->makeControlCommandRequest(
                       Name("/localhop/nfd").append(ndn::nfd::RibRegisterCommand::getName()),
                       parameters, T::signedInterestFmt, this->m_derivedId);
  if (this->m_status.isLocalhopConfigured) {
    commandHop.setTag(std::make_shared<lp::IncomingFaceIdTag>(123));
  }
  auto successResp = this->makeResponse(200, "OK", parameters);
  auto failureResp = ControlResponse(403, "authorization rejected");

  BOOST_CHECK_EQUAL(this->m_responses.size(), 0);
  this->receiveInterest(commandHost);
  this->receiveInterest(commandHop);

  auto nExpectedResponses = this->m_status.isLocalhopConfigured ? 2 : 1;
  auto expectedLocalhostResponse = this->m_status.isLocalhostConfigured ? successResp : failureResp;
  auto expectedLocalhopResponse = this->m_status.isLocalhopConfigured ? successResp : failureResp;

  BOOST_REQUIRE_EQUAL(this->m_responses.size(), nExpectedResponses);
  BOOST_CHECK_EQUAL(this->checkResponse(0, commandHost.getName(), expectedLocalhostResponse),
                    ManagerCommonFixture::CheckResponseResult::OK);
  if (nExpectedResponses == 2) {
    BOOST_CHECK_EQUAL(this->checkResponse(1, commandHop.getName(), expectedLocalhopResponse),
                      ManagerCommonFixture::CheckResponseResult::OK);
  }
}

BOOST_FIXTURE_TEST_SUITE(RegisterUnregister, LocalhostAuthorizedRibManagerFixture)

BOOST_AUTO_TEST_CASE(Basic)
{
  auto paramsRegister    = makeRegisterParameters("/test-register-unregister", 9527);
  auto paramsUnregister  = makeUnregisterParameters("/test-register-unregister", 9527);

  auto commandRegister = makeControlCommandRequest(REG_REQUEST, paramsRegister);
  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));
  auto commandUnregister = makeControlCommandRequest(UNREG_REQUEST, paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));

  receiveInterest(commandRegister);
  receiveInterest(commandUnregister);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "OK", paramsRegister)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "OK", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 2);
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-register-unregister", 9527, 10));
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.back(),
                    rib::FibUpdate::createRemoveUpdate("/test-register-unregister", 9527));
}

BOOST_AUTO_TEST_CASE(SelfOperation)
{
  auto paramsRegister = makeRegisterParameters("/test-self-register-unregister");
  auto paramsUnregister = makeUnregisterParameters("/test-self-register-unregister");
  BOOST_CHECK_EQUAL(paramsRegister.getFaceId(), 0);
  BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);

  const uint64_t inFaceId = 9527;
  auto commandRegister = makeControlCommandRequest(REG_REQUEST, paramsRegister);
  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
  auto commandUnregister = makeControlCommandRequest(UNREG_REQUEST, paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));

  receiveInterest(commandRegister);
  receiveInterest(commandUnregister);

  paramsRegister.setFaceId(inFaceId);
  paramsUnregister.setFaceId(inFaceId);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "OK", paramsRegister)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "OK", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 2);
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-self-register-unregister", 9527, 10));
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.back(),
                    rib::FibUpdate::createRemoveUpdate("/test-self-register-unregister", 9527));
}

BOOST_AUTO_TEST_CASE(Expiration)
{
  auto paramsRegister = makeRegisterParameters("/test-expiry", 9527, 50_ms);
  auto paramsUnregister = makeRegisterParameters("/test-expiry", 9527);
  receiveInterest(makeControlCommandRequest(REG_REQUEST, paramsRegister));

  advanceClocks(55_ms);
  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 2); // the registered route has expired
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-expiry", 9527, 10));
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.back(),
                    rib::FibUpdate::createRemoveUpdate("/test-expiry", 9527));

  m_fibUpdater.updates.clear();
  paramsRegister.setExpirationPeriod(100_ms);
  receiveInterest(makeControlCommandRequest(REG_REQUEST, paramsRegister));

  advanceClocks(55_ms);
  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 1); // the registered route is still active
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-expiry", 9527, 10));
}

BOOST_AUTO_TEST_CASE(NameTooLong)
{
  Name prefix;
  while (prefix.size() <= Fib::getMaxDepth()) {
    prefix.append("A");
  }
  auto params = makeRegisterParameters(prefix, 2899);
  auto command = makeControlCommandRequest(REG_REQUEST, params);

  receiveInterest(command);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, command.getName(),
                                  ControlResponse(414, "Route prefix cannot exceed " +
                                                  std::to_string(Fib::getMaxDepth()) + " components")),
                    CheckResponseResult::OK);

  BOOST_CHECK_EQUAL(m_fibUpdater.updates.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // RegisterUnregister

BOOST_FIXTURE_TEST_SUITE(PrefixAnnounce, LocalhostAuthorizedRibManagerFixture)

BOOST_AUTO_TEST_CASE(Basic)
{
  const uint64_t announceFaceId = 1234;

  ndn::PrefixAnnouncement pa = signPrefixAnn(makePrefixAnn("/test-prefix-announce", 10_s), m_keyChain);
  auto commandAnnounce = makeControlCommandRequest(ANNOUNCE_REQUEST, pa);
  commandAnnounce.setTag(make_shared<lp::IncomingFaceIdTag>(announceFaceId));

  auto paramsUnregister = makeUnregisterParameters("/test-prefix-announce");
  paramsUnregister.setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN);
  BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);
  auto commandUnregister = makeControlCommandRequest(UNREG_REQUEST, paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(announceFaceId)); // same incoming face

  receiveInterest(commandAnnounce);
  receiveInterest(commandUnregister);

  ControlParameters paramsAnnounceResponse;
  paramsAnnounceResponse.setName("/test-prefix-announce")
    .setFaceId(announceFaceId)
    .setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN)
    .setCost(rib::Route::PA_ROUTE_COST)
    .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
    .setExpirationPeriod(10_s);
  paramsUnregister.setFaceId(announceFaceId);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandAnnounce.getName(), makeResponse(200, "OK", paramsAnnounceResponse)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "OK", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 2);
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-prefix-announce", announceFaceId,
                                                    rib::Route::PA_ROUTE_COST));
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.back(),
                    rib::FibUpdate::createRemoveUpdate("/test-prefix-announce", announceFaceId));
}

BOOST_AUTO_TEST_CASE(UnregisterFromDifferentFace)
{
  const uint64_t announceFaceId = 1234;

  ndn::PrefixAnnouncement pa = signPrefixAnn(makePrefixAnn("/test-prefix-announce", 10_s), m_keyChain);
  auto commandAnnounce = makeControlCommandRequest(ANNOUNCE_REQUEST, pa);
  commandAnnounce.setTag(make_shared<lp::IncomingFaceIdTag>(announceFaceId));

  auto paramsUnregister = makeUnregisterParameters("/test-prefix-announce", announceFaceId);
  paramsUnregister.setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN);
  auto commandUnregister = makeControlCommandRequest(UNREG_REQUEST, paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(999)); // unregister from different face

  receiveInterest(commandAnnounce);
  receiveInterest(commandUnregister);

  ControlParameters paramsAnnounceResponse;
  paramsAnnounceResponse.setName("/test-prefix-announce")
    .setFaceId(announceFaceId)
    .setOrigin(ndn::nfd::ROUTE_ORIGIN_PREFIXANN)
    .setCost(rib::Route::PA_ROUTE_COST)
    .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
    .setExpirationPeriod(10_s);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandAnnounce.getName(), makeResponse(200, "OK", paramsAnnounceResponse)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "OK", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_fibUpdater.updates.size(), 2);
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.front(),
                    rib::FibUpdate::createAddUpdate("/test-prefix-announce", announceFaceId,
                                                    rib::Route::PA_ROUTE_COST));
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.back(),
                    rib::FibUpdate::createRemoveUpdate("/test-prefix-announce", announceFaceId));
}

BOOST_AUTO_TEST_CASE(NameTooLong)
{
  Name prefix;
  while (prefix.size() <= Fib::getMaxDepth()) {
    prefix.append("A");
  }
  ndn::PrefixAnnouncement pa = signPrefixAnn(makePrefixAnn(prefix, 10_s), m_keyChain);
  auto command = makeControlCommandRequest(ANNOUNCE_REQUEST, pa);
  command.setTag(make_shared<lp::IncomingFaceIdTag>(333));

  receiveInterest(command);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, command.getName(),
                                  ControlResponse(414, "Route prefix cannot exceed " +
                                                  std::to_string(Fib::getMaxDepth()) + " components")),
                    CheckResponseResult::OK);

  BOOST_CHECK_EQUAL(m_fibUpdater.updates.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // PrefixAnnounce

BOOST_FIXTURE_TEST_CASE(RibDataset, UnauthorizedRibManagerFixture)
{
  uint64_t faceId = 0;
  auto generateRoute = [&faceId] () -> rib::Route {
    rib::Route route;
    route.faceId = ++faceId;
    route.cost = route.faceId * 10;
    route.expires = std::nullopt;
    return route;
  };

  const size_t nEntries = 108;
  std::set<Name> actualPrefixes;
  for (size_t i = 0; i < nEntries; ++i) {
    Name prefix = Name("/test-dataset").appendNumber(i);
    actualPrefixes.insert(prefix);
    m_rib.insert(prefix, generateRoute());
    if (i & 0x1) {
      m_rib.insert(prefix, generateRoute());
      m_rib.insert(prefix, generateRoute());
    }
  }

  receiveInterest(*makeInterest("/localhost/nfd/rib/list", true));

  Block content = concatenateResponses();
  content.parse();
  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);

  std::vector<ndn::nfd::RibEntry> receivedRecords, expectedRecords;
  for (const auto& el : content.elements()) {
    ndn::nfd::RibEntry decodedEntry(el);
    BOOST_TEST_INFO_SCOPE(decodedEntry);
    receivedRecords.push_back(decodedEntry);
    actualPrefixes.erase(decodedEntry.getName());

    auto matchedEntryIt = m_rib.find(decodedEntry.getName());
    BOOST_REQUIRE(matchedEntryIt != m_rib.end());

    auto matchedEntry = matchedEntryIt->second;
    BOOST_TEST_REQUIRE(matchedEntry != nullptr);

    expectedRecords.emplace_back();
    expectedRecords.back().setName(matchedEntry->getName());
    for (const auto& route : matchedEntry->getRoutes()) {
      expectedRecords.back().addRoute(ndn::nfd::Route()
                                      .setFaceId(route.faceId)
                                      .setOrigin(route.origin)
                                      .setCost(route.cost)
                                      .setFlags(route.flags));
    }
  }

  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
  BOOST_TEST(receivedRecords == expectedRecords, boost::test_tools::per_element());
}

BOOST_FIXTURE_TEST_SUITE(FaceMonitor, LocalhostAuthorizedRibManagerFixture)

BOOST_AUTO_TEST_CASE(FetchActiveFacesEvent)
{
  BOOST_CHECK_EQUAL(m_fibUpdater.updates.size(), 0);

  advanceClocks(301_s); // RibManager::ACTIVE_FACE_FETCH_INTERVAL = 300s
  BOOST_REQUIRE_EQUAL(m_face.sentInterests.size(), 2);
  BOOST_CHECK_EQUAL(m_face.sentInterests[0].getName(), "/localhost/nfd/faces/events");
  BOOST_CHECK_EQUAL(m_face.sentInterests[1].getName(), "/localhost/nfd/faces/list");
}

BOOST_AUTO_TEST_CASE(RemoveInvalidFaces)
{
  auto parameters1 = makeRegisterParameters("/test-remove-invalid-faces-1");
  auto parameters2 = makeRegisterParameters("/test-remove-invalid-faces-2");
  receiveInterest(makeControlCommandRequest(REG_REQUEST, parameters1.setFaceId(1)));
  receiveInterest(makeControlCommandRequest(REG_REQUEST, parameters1.setFaceId(2)));
  receiveInterest(makeControlCommandRequest(REG_REQUEST, parameters2.setFaceId(2)));
  BOOST_REQUIRE_EQUAL(m_rib.size(), 3);

  ndn::nfd::FaceStatus status;
  status.setFaceId(1);
  std::vector<ndn::nfd::FaceStatus> activeFaces;
  activeFaces.push_back(status);

  m_manager.removeInvalidFaces(activeFaces);
  advanceClocks(100_ms);
  BOOST_REQUIRE_EQUAL(m_rib.size(), 1);

  auto it1 = m_rib.find("/test-remove-invalid-faces-1");
  auto it2 = m_rib.find("/test-remove-invalid-faces-2");
  BOOST_CHECK(it2 == m_rib.end());
  BOOST_REQUIRE(it1 != m_rib.end());
  BOOST_TEST(it1->second->hasFaceId(1));
  BOOST_TEST(!it1->second->hasFaceId(2));
}

BOOST_AUTO_TEST_CASE(OnNotification)
{
  auto parameters1 = makeRegisterParameters("/test-face-event-notification-1", 1);
  auto parameters2 = makeRegisterParameters("/test-face-event-notification-2", 1);
  receiveInterest(makeControlCommandRequest(REG_REQUEST, parameters1));
  receiveInterest(makeControlCommandRequest(REG_REQUEST, parameters2));
  BOOST_REQUIRE_EQUAL(m_rib.size(), 2);

  auto makeNotification = [] (ndn::nfd::FaceEventKind kind, uint64_t faceId) {
    return ndn::nfd::FaceEventNotification().setKind(kind).setFaceId(faceId);
  };

  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_DESTROYED, 1));
  advanceClocks(100_ms);
  BOOST_CHECK_EQUAL(m_rib.size(), 0);

  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_CREATED, 2));
  advanceClocks(100_ms);
  BOOST_CHECK_EQUAL(m_rib.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // FaceMonitor

BOOST_AUTO_TEST_SUITE_END() // TestRibManager
BOOST_AUTO_TEST_SUITE_END() // Mgmt

} // namespace nfd::tests
