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

#include "tests/test-common.hpp"
#include "tests/daemon/global-io-fixture.hpp"

#include <unordered_set>

namespace nfd::tests {

using namespace nfd::name_tree;

BOOST_AUTO_TEST_SUITE(Table)
BOOST_FIXTURE_TEST_SUITE(TestNameTree, GlobalIoFixture)

BOOST_AUTO_TEST_CASE(ComputeHash)
{
  Name root("/");
  root.wireEncode();
  HashValue hashValue = computeHash(root);
  BOOST_CHECK_EQUAL(hashValue, 0);

  Name prefix("/nohello/world/ndn/research");
  prefix.wireEncode();
  HashSequence hashes = computeHashes(prefix);
  BOOST_CHECK_EQUAL(hashes.size(), prefix.size() + 1);

  hashes = computeHashes(prefix, 2);
  BOOST_CHECK_EQUAL(hashes.size(), 3);
}

BOOST_AUTO_TEST_SUITE(Hashtable)

using name_tree::Hashtable;

BOOST_AUTO_TEST_CASE(Modifiers)
{
  Hashtable ht(HashtableOptions(16));

  Name name("/A/B/C/D");
  HashSequence hashes = computeHashes(name);

  BOOST_CHECK_EQUAL(ht.size(), 0);
  BOOST_CHECK(ht.find(name, 2) == nullptr);

  const Node* node = nullptr;
  bool isNew = false;
  std::tie(node, isNew) = ht.insert(name, 2, hashes);
  BOOST_CHECK_EQUAL(isNew, true);
  BOOST_CHECK(node != nullptr);
  BOOST_CHECK_EQUAL(ht.size(), 1);
  BOOST_CHECK_EQUAL(ht.find(name, 2), node);
  BOOST_CHECK_EQUAL(ht.find(name, 2, hashes), node);

  BOOST_CHECK(ht.find(name, 0) == nullptr);
  BOOST_CHECK(ht.find(name, 1) == nullptr);
  BOOST_CHECK(ht.find(name, 3) == nullptr);
  BOOST_CHECK(ht.find(name, 4) == nullptr);

  const Node* node2 = nullptr;
  std::tie(node2, isNew) = ht.insert(name, 2, hashes);
  BOOST_CHECK_EQUAL(isNew, false);
  BOOST_CHECK_EQUAL(node2, node);
  BOOST_CHECK_EQUAL(ht.size(), 1);

  std::tie(node2, isNew) = ht.insert(name, 4, hashes);
  BOOST_CHECK_EQUAL(isNew, true);
  BOOST_CHECK(node2 != nullptr);
  BOOST_CHECK_NE(node2, node);
  BOOST_CHECK_EQUAL(ht.size(), 2);

  ht.erase(const_cast<Node*>(node2));
  BOOST_CHECK_EQUAL(ht.size(), 1);
  BOOST_CHECK(ht.find(name, 4) == nullptr);
  BOOST_CHECK_EQUAL(ht.find(name, 2), node);

  ht.erase(const_cast<Node*>(node));
  BOOST_CHECK_EQUAL(ht.size(), 0);
  BOOST_CHECK(ht.find(name, 2) == nullptr);
  BOOST_CHECK(ht.find(name, 4) == nullptr);
}

BOOST_AUTO_TEST_CASE(Resize)
{
  HashtableOptions options(9);
  BOOST_CHECK_EQUAL(options.initialSize, 9);
  BOOST_CHECK_EQUAL(options.minSize, 9);
  options.minSize = 6;
  options.expandLoadFactor = 0.80;
  options.expandFactor = 5.0;
  options.shrinkLoadFactor = 0.12;
  options.shrinkFactor = 0.3;

  Hashtable ht(options);

  auto addNodes = [&ht] (int min, int max) {
    for (int i = min; i <= max; ++i) {
      Name name;
      name.appendNumber(i);
      HashSequence hashes = computeHashes(name);
      ht.insert(name, name.size(), hashes);
    }
  };

  auto removeNodes = [&ht] (int min, int max) {
    for (int i = min; i <= max; ++i) {
      Name name;
      name.appendNumber(i);
      const Node* node = ht.find(name, name.size());
      BOOST_REQUIRE(node != nullptr);
      ht.erase(const_cast<Node*>(node));
    }
  };

  BOOST_CHECK_EQUAL(ht.size(), 0);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 9);

  addNodes(1, 1);
  BOOST_CHECK_EQUAL(ht.size(), 1);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 9);

  removeNodes(1, 1);
  BOOST_CHECK_EQUAL(ht.size(), 0);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 6);

  addNodes(1, 4);
  BOOST_CHECK_EQUAL(ht.size(), 4);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 6);

  addNodes(5, 5);
  BOOST_CHECK_EQUAL(ht.size(), 5);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 30);

  addNodes(6, 23);
  BOOST_CHECK_EQUAL(ht.size(), 23);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 30);

  addNodes(24, 25);
  BOOST_CHECK_EQUAL(ht.size(), 25);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 150);

  removeNodes(19, 25);
  BOOST_CHECK_EQUAL(ht.size(), 18);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 150);

  removeNodes(17, 18);
  BOOST_CHECK_EQUAL(ht.size(), 16);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 45);

  removeNodes(7, 16);
  BOOST_CHECK_EQUAL(ht.size(), 6);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 45);

  removeNodes(5, 6);
  BOOST_CHECK_EQUAL(ht.size(), 4);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 13);

  removeNodes(1, 4);
  BOOST_CHECK_EQUAL(ht.size(), 0);
  BOOST_CHECK_EQUAL(ht.getNBuckets(), 6);
}

BOOST_AUTO_TEST_SUITE_END() // Hashtable

BOOST_AUTO_TEST_SUITE(TestEntry)

BOOST_AUTO_TEST_CASE(TreeRelation)
{
  Name name("ndn:/named-data/research/abc/def/ghi");
  auto node = make_unique<Node>(0, name);
  Entry& npe = node->entry;
  BOOST_CHECK(npe.getParent() == nullptr);

  Name parentName = name.getPrefix(-1);
  auto parentNode = make_unique<Node>(1, parentName);
  Entry& parent = parentNode->entry;
  BOOST_CHECK_EQUAL(parent.hasChildren(), false);
  BOOST_CHECK_EQUAL(parent.isEmpty(), true);

  npe.setParent(parentNode->entry);
  BOOST_CHECK_EQUAL(npe.getParent(), &parent);
  BOOST_CHECK_EQUAL(parent.hasChildren(), true);
  BOOST_CHECK_EQUAL(parent.isEmpty(), false);
  BOOST_REQUIRE_EQUAL(parent.getChildren().size(), 1);
  BOOST_CHECK_EQUAL(parent.getChildren().front(), &npe);

  npe.unsetParent();
  BOOST_CHECK(npe.getParent() == nullptr);
  BOOST_CHECK_EQUAL(parent.hasChildren(), false);
  BOOST_CHECK_EQUAL(parent.isEmpty(), true);
}

BOOST_AUTO_TEST_CASE(TableEntries)
{
  Name name("ndn:/named-data/research/abc/def/ghi");
  Node node(0, name);
  Entry& npe = node.entry;
  BOOST_CHECK_EQUAL(npe.getName(), name);

  BOOST_CHECK_EQUAL(npe.hasTableEntries(), false);
  BOOST_CHECK_EQUAL(npe.isEmpty(), true);
  BOOST_CHECK(npe.getFibEntry() == nullptr);
  BOOST_CHECK_EQUAL(npe.hasPitEntries(), false);
  BOOST_CHECK_EQUAL(npe.getPitEntries().empty(), true);
  BOOST_CHECK(npe.getMeasurementsEntry() == nullptr);
  BOOST_CHECK(npe.getStrategyChoiceEntry() == nullptr);

  npe.setFibEntry(make_unique<fib::Entry>(name));
  BOOST_REQUIRE(npe.getFibEntry() != nullptr);
  BOOST_CHECK_EQUAL(npe.getFibEntry()->getPrefix(), name);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), true);
  BOOST_CHECK_EQUAL(npe.isEmpty(), false);

  npe.setFibEntry(nullptr);
  BOOST_CHECK(npe.getFibEntry() == nullptr);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), false);
  BOOST_CHECK_EQUAL(npe.isEmpty(), true);

  auto interest1 = makeInterest(name);
  auto pit1 = make_shared<pit::Entry>(*interest1);
  auto interest2 = makeInterest(name);
  interest2->setMustBeFresh(true);
  auto pit2 = make_shared<pit::Entry>(*interest2);

  npe.insertPitEntry(pit1);
  BOOST_CHECK_EQUAL(npe.hasPitEntries(), true);
  BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 1);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), true);
  BOOST_CHECK_EQUAL(npe.isEmpty(), false);

  npe.insertPitEntry(pit2);
  BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 2);

  auto* pit1ptr = pit1.get();
  weak_ptr<pit::Entry> pit1weak(pit1);
  pit1.reset();
  BOOST_CHECK_EQUAL(pit1weak.use_count(), 1); // npe is the sole owner of pit1
  npe.erasePitEntry(pit1ptr);
  BOOST_REQUIRE_EQUAL(npe.getPitEntries().size(), 1);
  BOOST_CHECK(&npe.getPitEntries().front()->getInterest() == interest2.get());

  npe.erasePitEntry(pit2.get());
  BOOST_CHECK_EQUAL(npe.hasPitEntries(), false);
  BOOST_CHECK_EQUAL(npe.getPitEntries().size(), 0);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), false);
  BOOST_CHECK_EQUAL(npe.isEmpty(), true);

  npe.setMeasurementsEntry(make_unique<measurements::Entry>(name));
  BOOST_REQUIRE(npe.getMeasurementsEntry() != nullptr);
  BOOST_CHECK_EQUAL(npe.getMeasurementsEntry()->getName(), name);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), true);
  BOOST_CHECK_EQUAL(npe.isEmpty(), false);

  npe.setMeasurementsEntry(nullptr);
  BOOST_CHECK(npe.getMeasurementsEntry() == nullptr);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), false);
  BOOST_CHECK_EQUAL(npe.isEmpty(), true);

  npe.setStrategyChoiceEntry(make_unique<strategy_choice::Entry>(name));
  BOOST_REQUIRE(npe.getStrategyChoiceEntry() != nullptr);
  BOOST_CHECK_EQUAL(npe.getStrategyChoiceEntry()->getPrefix(), name);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), true);
  BOOST_CHECK_EQUAL(npe.isEmpty(), false);

  npe.setStrategyChoiceEntry(nullptr);
  BOOST_CHECK(npe.getStrategyChoiceEntry() == nullptr);
  BOOST_CHECK_EQUAL(npe.hasTableEntries(), false);
  BOOST_CHECK_EQUAL(npe.isEmpty(), true);
}

BOOST_AUTO_TEST_SUITE_END() // TestEntry

BOOST_AUTO_TEST_CASE(Basic)
{
  size_t nBuckets = 16;
  NameTree nt(nBuckets);

  BOOST_CHECK_EQUAL(nt.size(), 0);
  BOOST_CHECK_EQUAL(nt.getNBuckets(), nBuckets);

  // lookup

  Name nameABC("/a/b/c");
  Entry& npeABC = nt.lookup(nameABC);
  BOOST_CHECK_EQUAL(nt.size(), 4);

  Name nameABD("/a/b/d");
  Entry& npeABD = nt.lookup(nameABD);
  BOOST_CHECK_EQUAL(nt.size(), 5);

  Name nameAE("/a/e/");
  Entry& npeAE = nt.lookup(nameAE);
  BOOST_CHECK_EQUAL(nt.size(), 6);

  Name nameF("/f");
  Entry& npeF = nt.lookup(nameF);
  BOOST_CHECK_EQUAL(nt.size(), 7);

  // getParent and findExactMatch

  Name nameAB("/a/b");
  BOOST_CHECK_EQUAL(npeABC.getParent(), nt.findExactMatch(nameAB));
  BOOST_CHECK_EQUAL(npeABD.getParent(), nt.findExactMatch(nameAB));

  Name nameA("/a");
  BOOST_CHECK_EQUAL(npeAE.getParent(), nt.findExactMatch(nameA));

  Name nameRoot("/");
  BOOST_CHECK_EQUAL(npeF.getParent(), nt.findExactMatch(nameRoot));
  BOOST_CHECK_EQUAL(nt.size(), 7);

  Name name0("/does/not/exist");
  Entry* npe0 = nt.findExactMatch(name0);
  BOOST_CHECK(npe0 == nullptr);

  // findLongestPrefixMatch

  Entry* temp = nullptr;
  Name nameABCLPM("/a/b/c/def/asdf/nlf");
  temp = nt.findLongestPrefixMatch(nameABCLPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABC));

  Name nameABDLPM("/a/b/d/def/asdf/nlf");
  temp = nt.findLongestPrefixMatch(nameABDLPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameABD));

  Name nameABLPM("/a/b/hello/world");
  temp = nt.findLongestPrefixMatch(nameABLPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAB));

  Name nameAELPM("/a/e/hello/world");
  temp = nt.findLongestPrefixMatch(nameAELPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameAE));

  Name nameALPM("/a/hello/world");
  temp = nt.findLongestPrefixMatch(nameALPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameA));

  Name nameFLPM("/f/hello/world");
  temp = nt.findLongestPrefixMatch(nameFLPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameF));

  Name nameRootLPM("/does_not_exist");
  temp = nt.findLongestPrefixMatch(nameRootLPM);
  BOOST_CHECK_EQUAL(temp, nt.findExactMatch(nameRoot));

  bool eraseResult = false;
  temp = nt.findExactMatch(nameABC);
  if (temp != nullptr)
    eraseResult = nt.eraseIfEmpty(temp);
  BOOST_CHECK_EQUAL(nt.size(), 6);
  BOOST_CHECK(nt.findExactMatch(nameABC) == nullptr);
  BOOST_CHECK_EQUAL(eraseResult, true);

  eraseResult = false;
  temp = nt.findExactMatch(nameABCLPM);
  if (temp != nullptr)
    eraseResult = nt.eraseIfEmpty(temp);
  BOOST_CHECK(temp == nullptr);
  BOOST_CHECK_EQUAL(nt.size(), 6);
  BOOST_CHECK_EQUAL(eraseResult, false);

  nt.lookup(nameABC);
  BOOST_CHECK_EQUAL(nt.size(), 7);

  eraseResult = false;
  temp = nt.findExactMatch(nameABC);
  if (temp != nullptr)
    eraseResult = nt.eraseIfEmpty(temp);
  BOOST_CHECK_EQUAL(nt.size(), 6);
  BOOST_CHECK_EQUAL(eraseResult, true);
  BOOST_CHECK(nt.findExactMatch(nameABC) == nullptr);

  BOOST_CHECK_EQUAL(nt.getNBuckets(), 16);

  // should resize now
  Name nameABCD("a/b/c/d");
  nt.lookup(nameABCD);
  Name nameABCDE("a/b/c/d/e");
  nt.lookup(nameABCDE);
  BOOST_CHECK_EQUAL(nt.size(), 9);
  BOOST_CHECK_EQUAL(nt.getNBuckets(), 32);

  // try to erase /a/b/c, should return false
  temp = nt.findExactMatch(nameABC);
  BOOST_CHECK_EQUAL(temp->getName(), nameABC);
  eraseResult = nt.eraseIfEmpty(temp);
  BOOST_CHECK_EQUAL(eraseResult, false);
  temp = nt.findExactMatch(nameABC);
  BOOST_CHECK_EQUAL(temp->getName(), nameABC);

  temp = nt.findExactMatch(nameABD);
  if (temp != nullptr)
    nt.eraseIfEmpty(temp);
  BOOST_CHECK_EQUAL(nt.size(), 8);
}

/** \brief Verify a NameTree enumeration contains expected entries.
 *
 *  Example:
 *  \code
 *  auto& enumerable = ...;
 *  EnumerationVerifier(enumerable)
 *    .expect("/A")
 *    .expect("/B")
 *    .end();
 *  // enumerable must have /A /B and nothing else to pass the test.
 *  \endcode
 */
class EnumerationVerifier : noncopyable
{
public:
  template<typename Enumerable>
  EnumerationVerifier(Enumerable&& enumerable)
  {
    for (const Entry& entry : enumerable) {
      const Name& name = entry.getName();
      BOOST_CHECK_MESSAGE(m_names.insert(name).second, "duplicate Name " << name);
    }
  }

  EnumerationVerifier&
  expect(const Name& name)
  {
    BOOST_CHECK_MESSAGE(m_names.erase(name) == 1, "missing Name " << name);
    return *this;
  }

  void
  end()
  {
    BOOST_CHECK(m_names.empty());
  }

private:
  std::unordered_set<Name> m_names;
};

class EnumerationFixture : public GlobalIoFixture
{
protected:
  EnumerationFixture()
    : nt(N_BUCKETS)
  {
    BOOST_CHECK_EQUAL(nt.size(), 0);
    BOOST_CHECK_EQUAL(nt.getNBuckets(), N_BUCKETS);
  }

  void
  insertAbAc()
  {
    nt.lookup("/a/b");
    nt.lookup("/a/c");
    BOOST_CHECK_EQUAL(nt.size(), 4);
    // /, /a, /a/b, /a/c
  }

  void
  insertAb1Ab2Ac1Ac2()
  {
    nt.lookup("/a/b/1");
    nt.lookup("/a/b/2");
    nt.lookup("/a/c/1");
    nt.lookup("/a/c/2");
    BOOST_CHECK_EQUAL(nt.size(), 8);
    // /, /a, /a/b, /a/b/1, /a/b/2, /a/c, /a/c/1, /a/c/2
  }

protected:
  static constexpr size_t N_BUCKETS = 16;
  NameTree nt;
};

BOOST_FIXTURE_TEST_CASE(IteratorFullEnumerate, EnumerationFixture)
{
  nt.lookup("/a/b/c");
  BOOST_CHECK_EQUAL(nt.size(), 4);

  nt.lookup("/a/b/d");
  BOOST_CHECK_EQUAL(nt.size(), 5);

  nt.lookup("/a/e");
  BOOST_CHECK_EQUAL(nt.size(), 6);

  nt.lookup("/f");
  BOOST_CHECK_EQUAL(nt.size(), 7);

  nt.lookup("/");
  BOOST_CHECK_EQUAL(nt.size(), 7);

  auto&& enumerable = nt.fullEnumerate();
  EnumerationVerifier(enumerable)
    .expect("/")
    .expect("/a")
    .expect("/a/b")
    .expect("/a/b/c")
    .expect("/a/b/d")
    .expect("/a/e")
    .expect("/f")
    .end();
}

BOOST_FIXTURE_TEST_SUITE(IteratorPartialEnumerate, EnumerationFixture)

BOOST_AUTO_TEST_CASE(Empty)
{
  auto&& enumerable = nt.partialEnumerate("/a");

  EnumerationVerifier(enumerable)
    .end();
}

BOOST_AUTO_TEST_CASE(NotIn)
{
  this->insertAbAc();

  // Enumerate on some name that is not in nameTree
  Name name0("/0");
  auto&& enumerable = nt.partialEnumerate("/0");

  EnumerationVerifier(enumerable)
    .end();
}

BOOST_AUTO_TEST_CASE(OnlyA)
{
  this->insertAbAc();

  // Accept "root" nameA only
  auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
    return std::pair(entry.getName() == "/a", true);
  });

  EnumerationVerifier(enumerable)
    .expect("/a")
    .end();
}

BOOST_AUTO_TEST_CASE(ExceptA)
{
  this->insertAbAc();

  // Accept anything except "root" nameA
  auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
    return std::pair(entry.getName() != "/a", true);
  });

  EnumerationVerifier(enumerable)
    .expect("/a/b")
    .expect("/a/c")
    .end();
}

BOOST_AUTO_TEST_CASE(NoNameANoSubTreeAB)
{
  this->insertAb1Ab2Ac1Ac2();

  // No NameA
  // No SubTree from NameAB
  auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
      return std::pair(entry.getName() != "/a", entry.getName() != "/a/b");
    });

  EnumerationVerifier(enumerable)
    .expect("/a/b")
    .expect("/a/c")
    .expect("/a/c/1")
    .expect("/a/c/2")
    .end();
}

BOOST_AUTO_TEST_CASE(NoNameANoSubTreeAC)
{
  this->insertAb1Ab2Ac1Ac2();

  // No NameA
  // No SubTree from NameAC
  auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
      return std::pair(entry.getName() != "/a", entry.getName() != "/a/c");
    });

  EnumerationVerifier(enumerable)
    .expect("/a/b")
    .expect("/a/b/1")
    .expect("/a/b/2")
    .expect("/a/c")
    .end();
}

BOOST_AUTO_TEST_CASE(NoSubTreeA)
{
  this->insertAb1Ab2Ac1Ac2();

  // No Subtree from NameA
  auto&& enumerable = nt.partialEnumerate("/a", [] (const Entry& entry) {
      return std::pair(true, entry.getName() != "/a");
    });

  EnumerationVerifier(enumerable)
    .expect("/a")
    .end();
}

BOOST_AUTO_TEST_CASE(Example)
{
  // Example
  // /
  // /A
  // /A/B x
  // /A/B/C
  // /A/D x
  // /E
  // /F

  nt.lookup("/A");
  nt.lookup("/A/B");
  nt.lookup("/A/B/C");
  nt.lookup("/A/D");
  nt.lookup("/E");
  nt.lookup("/F");

  auto&& enumerable = nt.partialEnumerate("/A", [] (const Entry& entry) {
    bool visitEntry = false;
    bool visitChildren = false;

    const Name& name = entry.getName();
    if (name == "/" || name == "/A/B" || name == "/A/B/C" || name == "/A/D") {
      visitEntry = true;
    }
    if (name == "/" || name == "/A" || name == "/F") {
      visitChildren = true;
    }

    return std::pair(visitEntry, visitChildren);
  });

  EnumerationVerifier(enumerable)
    .expect("/A/B")
    .expect("/A/D")
    .end();
}

BOOST_AUTO_TEST_SUITE_END() // IteratorPartialEnumerate

BOOST_FIXTURE_TEST_CASE(IteratorFindAllMatches, EnumerationFixture)
{
  nt.lookup("/a/b/c/d/e/f");
  nt.lookup("/a/a/c");
  nt.lookup("/a/a/d/1");
  nt.lookup("/a/a/d/2");
  BOOST_CHECK_EQUAL(nt.size(), 12);

  auto&& allMatches = nt.findAllMatches("/a/b/c/d/e");

  EnumerationVerifier(allMatches)
    .expect("/")
    .expect("/a")
    .expect("/a/b")
    .expect("/a/b/c")
    .expect("/a/b/c/d")
    .expect("/a/b/c/d/e")
    .end();
}

BOOST_AUTO_TEST_CASE(HashTableResizeShrink)
{
  size_t nBuckets = 16;
  NameTree nameTree(nBuckets);

  Name prefix("/a/b/c/d/e/f/g/h"); // requires 9 buckets

  Entry& entry = nameTree.lookup(prefix);
  BOOST_CHECK_EQUAL(nameTree.size(), 9);
  BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 32);

  nameTree.eraseIfEmpty(&entry);
  BOOST_CHECK_EQUAL(nameTree.size(), 0);
  BOOST_CHECK_EQUAL(nameTree.getNBuckets(), 16);
}

// .lookup should not invalidate iterator
BOOST_AUTO_TEST_CASE(SurvivedIteratorAfterLookup)
{
  NameTree nt;
  nt.lookup("/A/B/C");
  nt.lookup("/E");

  Name nameB("/A/B");
  std::set<Name> seenNames;
  for (NameTree::const_iterator it = nt.begin(); it != nt.end(); ++it) {
    BOOST_CHECK(seenNames.insert(it->getName()).second);
    if (it->getName() == nameB) {
      nt.lookup("/D");
    }
  }

  BOOST_CHECK_EQUAL(seenNames.count("/"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/B"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/B/C"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/E"), 1);

  seenNames.erase("/D"); // /D may or may not appear
  BOOST_CHECK(seenNames.size() == 5);
}

// .eraseIfEmpty should not invalidate iterator
BOOST_AUTO_TEST_CASE(SurvivedIteratorAfterErase)
{
  NameTree nt;
  nt.lookup("/A/B/C");
  nt.lookup("/A/D/E");
  nt.lookup("/A/F/G");
  nt.lookup("/H");

  Name nameD("/A/D");
  std::set<Name> seenNames;
  for (NameTree::const_iterator it = nt.begin(); it != nt.end(); ++it) {
    BOOST_CHECK(seenNames.insert(it->getName()).second);
    if (it->getName() == nameD) {
      nt.eraseIfEmpty(nt.findExactMatch("/A/F/G")); // /A/F/G and /A/F are erased
    }
  }

  BOOST_CHECK_EQUAL(seenNames.count("/"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/B"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/B/C"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/D"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/A/D/E"), 1);
  BOOST_CHECK_EQUAL(seenNames.count("/H"), 1);

  seenNames.erase("/A/F"); // /A/F may or may not appear
  seenNames.erase("/A/F/G"); // /A/F/G may or may not appear
  BOOST_CHECK(seenNames.size() == 7);
}

BOOST_AUTO_TEST_SUITE_END() // TestNameTree
BOOST_AUTO_TEST_SUITE_END() // Table

} // namespace nfd::tests
