/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2020,  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 "fw/forwarder.hpp"
#include "common/global.hpp"

#include "tests/test-common.hpp"
#include "tests/daemon/global-io-fixture.hpp"
#include "tests/daemon/face/dummy-face.hpp"
#include "choose-strategy.hpp"
#include "dummy-strategy.hpp"

#include <ndn-cxx/lp/tags.hpp>

namespace nfd {
namespace tests {

class ForwarderFixture : public GlobalIoTimeFixture
{
protected:
  template<typename ...Args>
  shared_ptr<DummyFace>
  addFace(Args&&... args)
  {
    auto face = make_shared<DummyFace>(std::forward<Args>(args)...);
    faceTable.add(face);
    return face;
  }

protected:
  FaceTable faceTable;
  Forwarder forwarder{faceTable};
};

BOOST_AUTO_TEST_SUITE(Fw)
BOOST_FIXTURE_TEST_SUITE(TestForwarder, ForwarderFixture)

BOOST_AUTO_TEST_CASE(SimpleExchange)
{
  auto face1 = addFace();
  auto face2 = addFace();

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entry, *face2, 0);

  BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
  face1->receiveInterest(*makeInterest("/A/B"), 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentInterests[0].getName(), "/A/B");
  BOOST_REQUIRE(face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
  BOOST_CHECK_EQUAL(*face2->sentInterests[0].getTag<lp::IncomingFaceIdTag>(), face1->getId());
  BOOST_CHECK_EQUAL(forwarder.getCounters().nInInterests, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutInterests, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 0);

  BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 0);
  face2->receiveData(*makeData("/A/B"), 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
  BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
  BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
  BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face2->getId());
  BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nInNacks, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutNacks, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nSatisfiedInterests, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
}

BOOST_AUTO_TEST_CASE(CsMatched)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace();

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entry, *face2, 0);

  Pit& pit = forwarder.getPit();
  BOOST_CHECK_EQUAL(pit.size(), 0);

  auto data = makeData("/A/B");
  data->setTag(make_shared<lp::IncomingFaceIdTag>(face3->getId()));
  forwarder.getCs().insert(*data);

  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);
  face1->receiveInterest(*makeInterest("/A", true), 0);
  this->advanceClocks(1_ms, 5_ms);
  // Interest matching ContentStore should not be forwarded
  BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 0);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsHits, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nCsMisses, 0);

  BOOST_REQUIRE_EQUAL(face1->sentData.size(), 1);
  // IncomingFaceId field should be reset to represent CS
  BOOST_CHECK_EQUAL(face1->sentData[0].getName(), "/A/B");
  BOOST_REQUIRE(face1->sentData[0].getTag<lp::IncomingFaceIdTag>() != nullptr);
  BOOST_CHECK_EQUAL(*face1->sentData[0].getTag<lp::IncomingFaceIdTag>(), face::FACEID_CONTENT_STORE);

  this->advanceClocks(100_ms, 500_ms);
  // PIT entry should not be left behind
  BOOST_CHECK_EQUAL(pit.size(), 0);
}

BOOST_AUTO_TEST_CASE(InterestWithoutNonce)
{
  auto face1 = addFace();
  auto face2 = addFace();

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entry, *face2, 0);

  auto interest = makeInterest("/A");
  BOOST_CHECK_EQUAL(interest->hasNonce(), false);
  face1->receiveInterest(*interest, 0);

  // Ensure Nonce added if incoming packet did not have Nonce
  BOOST_REQUIRE_EQUAL(face2->getCounters().nOutInterests, 1);
  BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentInterests.back().hasNonce(), true);
}

BOOST_AUTO_TEST_CASE(OutgoingInterest)
{
  auto face1 = addFace();
  auto face2 = addFace();

  Pit& pit = forwarder.getPit();
  auto interestA1 = makeInterest("/A", false, nullopt, 8378);
  shared_ptr<pit::Entry> pitA = pit.insert(*interestA1).first;
  pitA->insertOrUpdateInRecord(*face1, *interestA1);

  auto interestA2 = makeInterest("/A", false, nullopt, 1698);
  forwarder.onOutgoingInterest(pitA, FaceEndpoint(*face2, 0), *interestA2);

  auto outA2 = pitA->getOutRecord(*face2);
  BOOST_REQUIRE(outA2 != pitA->out_end());
  BOOST_CHECK_EQUAL(outA2->getLastNonce(), 1698);

  BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentInterests.back().getNonce(), 1698);
}

BOOST_AUTO_TEST_CASE(NextHopFaceId)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace();

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entry, *face3, 0);

  auto interest = makeInterest("/A/B");
  interest->setTag(make_shared<lp::NextHopFaceIdTag>(face2->getId()));

  face1->receiveInterest(*interest, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(face3->sentInterests.size(), 0);
  BOOST_REQUIRE_EQUAL(face2->sentInterests.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentInterests.front().getName(), "/A/B");
}

BOOST_AUTO_TEST_CASE(HopLimit)
{
  auto faceIn = addFace();
  auto faceRemote = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_NON_LOCAL);
  auto faceLocal = addFace("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
  Fib& fib = forwarder.getFib();
  fib::Entry* entryRemote = fib.insert("/remote").first;
  fib.addOrUpdateNextHop(*entryRemote, *faceRemote, 0);
  fib::Entry* entryLocal = fib.insert("/local").first;
  fib.addOrUpdateNextHop(*entryLocal, *faceLocal, 0);

  // Incoming interest w/o HopLimit will not be dropped on send or receive paths
  auto interestNoHopLimit = makeInterest("/remote/abcdefgh");
  faceIn->receiveInterest(*interestNoHopLimit, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 1);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
  BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 1);
  BOOST_CHECK(!faceRemote->sentInterests.back().getHopLimit());

  // Incoming interest w/ HopLimit > 1 will not be dropped on send/receive
  auto interestHopLimit2 = makeInterest("/remote/ijklmnop");
  interestHopLimit2->setHopLimit(2);
  faceIn->receiveInterest(*interestHopLimit2, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 0);
  BOOST_REQUIRE_EQUAL(faceRemote->sentInterests.size(), 2);
  BOOST_REQUIRE(faceRemote->sentInterests.back().getHopLimit());
  BOOST_CHECK_EQUAL(*faceRemote->sentInterests.back().getHopLimit(), 1);

  // Incoming interest w/ HopLimit == 1 will be dropped on send path if going out on remote face
  auto interestHopLimit1Remote = makeInterest("/remote/qrstuvwx");
  interestHopLimit1Remote->setHopLimit(1);
  faceIn->receiveInterest(*interestHopLimit1Remote, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nInHopLimitZero, 0);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
  BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);

  // Incoming interest w/ HopLimit == 1 will not be dropped on send path if going out on local face
  auto interestHopLimit1Local = makeInterest("/local/abcdefgh");
  interestHopLimit1Local->setHopLimit(1);
  faceIn->receiveInterest(*interestHopLimit1Local, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutInterests, 1);
  BOOST_CHECK_EQUAL(faceLocal->getCounters().nInHopLimitZero, 0);
  BOOST_CHECK_EQUAL(faceLocal->getCounters().nOutHopLimitZero, 0);
  BOOST_REQUIRE_EQUAL(faceLocal->sentInterests.size(), 1);
  BOOST_REQUIRE(faceLocal->sentInterests.back().getHopLimit());
  BOOST_CHECK_EQUAL(*faceLocal->sentInterests.back().getHopLimit(), 0);

  // Interest w/ HopLimit == 0 will be dropped on receive path
  auto interestHopLimit0 = makeInterest("/remote/yzabcdef");
  interestHopLimit0->setHopLimit(0);
  faceIn->receiveInterest(*interestHopLimit0, 0);
  this->advanceClocks(100_ms, 1_s);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutInterests, 2);
  BOOST_CHECK_EQUAL(faceIn->getCounters().nInHopLimitZero, 1);
  BOOST_CHECK_EQUAL(faceRemote->getCounters().nOutHopLimitZero, 1);
  BOOST_CHECK_EQUAL(faceRemote->sentInterests.size(), 2);
}

class ScopeLocalhostIncomingTestForwarder : public Forwarder
{
public:
  using Forwarder::Forwarder;

protected:
  void
  dispatchToStrategy(pit::Entry&, std::function<void(fw::Strategy&)>) final
  {
    ++dispatchToStrategy_count;
  }

public:
  int dispatchToStrategy_count = 0;
};

BOOST_FIXTURE_TEST_CASE(ScopeLocalhostIncoming, GlobalIoTimeFixture)
{
  FaceTable faceTable;
  ScopeLocalhostIncomingTestForwarder forwarder(faceTable);

  auto face1 = make_shared<DummyFace>("dummy://", "dummy://", ndn::nfd::FACE_SCOPE_LOCAL);
  auto face2 = make_shared<DummyFace>();
  faceTable.add(face1);
  faceTable.add(face2);

  // local face, /localhost: OK
  forwarder.dispatchToStrategy_count = 0;
  auto i1 = makeInterest("/localhost/A1");
  forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i1);
  BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);

  // non-local face, /localhost: violate
  forwarder.dispatchToStrategy_count = 0;
  auto i2 = makeInterest("/localhost/A2");
  forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i2);
  BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 0);

  // local face, non-/localhost: OK
  forwarder.dispatchToStrategy_count = 0;
  auto i3 = makeInterest("/A3");
  forwarder.onIncomingInterest(FaceEndpoint(*face1, 0), *i3);
  BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);

  // non-local face, non-/localhost: OK
  forwarder.dispatchToStrategy_count = 0;
  auto i4 = makeInterest("/A4");
  forwarder.onIncomingInterest(FaceEndpoint(*face2, 0), *i4);
  BOOST_CHECK_EQUAL(forwarder.dispatchToStrategy_count, 1);

  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);

  // local face, /localhost: OK
  auto d1 = makeData("/localhost/B1");
  forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);

  // non-local face, /localhost: OK
  auto d2 = makeData("/localhost/B2");
  forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d2);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);

  // local face, non-/localhost: OK
  auto d3 = makeData("/B3");
  forwarder.onIncomingData(FaceEndpoint(*face1, 0), *d3);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 2);

  // non-local face, non-/localhost: OK
  auto d4 = makeData("/B4");
  forwarder.onIncomingData(FaceEndpoint(*face2, 0), *d4);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 3);
}

BOOST_AUTO_TEST_CASE(IncomingInterestStrategyDispatch)
{
  auto face1 = addFace();
  auto face2 = addFace();

  DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
  DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());

  auto interest1 = makeInterest("/A/1");
  strategyA.afterReceiveInterest_count = 0;
  strategyA.interestOutFace = face2;
  forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest1);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveInterest_count, 1);

  auto interest2 = makeInterest("/B/2", true);
  strategyB.afterReceiveInterest_count = 0;
  strategyB.interestOutFace = face2;
  forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest2);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveInterest_count, 1);

  this->advanceClocks(1_ms, 5_ms);

  auto data1 = makeData("/A/1");
  strategyA.beforeSatisfyInterest_count = 0;
  forwarder.startProcessData(FaceEndpoint(*face2, 0), *data1);
  BOOST_CHECK_EQUAL(strategyA.beforeSatisfyInterest_count, 1);

  auto data2 = makeData("/B/2/b");
  strategyB.beforeSatisfyInterest_count = 0;
  forwarder.startProcessData(FaceEndpoint(*face2, 0), *data2);
  BOOST_CHECK_EQUAL(strategyB.beforeSatisfyInterest_count, 1);

  auto interest3 = makeInterest("/A/3", false, 30_ms);
  forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest3);
  auto interest4 = makeInterest("/B/4", false, 5_s);
  forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest4);
}

BOOST_AUTO_TEST_CASE(IncomingData)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace();
  auto face4 = addFace();

  Pit& pit = forwarder.getPit();
  auto interestD = makeInterest("/A/B/C/D");
  shared_ptr<pit::Entry> pitD = pit.insert(*interestD).first;
  pitD->insertOrUpdateInRecord(*face1, *interestD);
  auto interestA = makeInterest("/A", true);
  shared_ptr<pit::Entry> pitA = pit.insert(*interestA).first;
  pitA->insertOrUpdateInRecord(*face2, *interestA);
  pitA->insertOrUpdateInRecord(*face3, *interestA);
  auto interestC = makeInterest("/A/B/C", true);
  shared_ptr<pit::Entry> pitC = pit.insert(*interestC).first;
  pitC->insertOrUpdateInRecord(*face3, *interestC);
  pitC->insertOrUpdateInRecord(*face4, *interestC);

  auto dataD = makeData("/A/B/C/D");
  forwarder.onIncomingData(FaceEndpoint(*face3, 0), *dataD);
  this->advanceClocks(1_ms, 5_ms);

  BOOST_CHECK_EQUAL(face1->sentData.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentData.size(), 1);
  BOOST_CHECK_EQUAL(face3->sentData.size(), 0);
  BOOST_CHECK_EQUAL(face4->sentData.size(), 1);

  BOOST_CHECK_EQUAL(forwarder.getCounters().nInData, 1);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nOutData, 3);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
}

BOOST_AUTO_TEST_CASE(IncomingNack)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace("dummy://", "dummy://",
                       ndn::nfd::FACE_SCOPE_NON_LOCAL,
                       ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                       ndn::nfd::LINK_TYPE_MULTI_ACCESS);

  DummyStrategy& strategyA = choose<DummyStrategy>(forwarder, "/", DummyStrategy::getStrategyName());
  DummyStrategy& strategyB = choose<DummyStrategy>(forwarder, "/B", DummyStrategy::getStrategyName());

  Pit& pit = forwarder.getPit();

  // dispatch to the correct strategy
  auto interest1 = makeInterest("/A/AYJqayrzF", false, nullopt, 562);
  shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
  pit1->insertOrUpdateOutRecord(*face1, *interest1);
  auto interest2 = makeInterest("/B/EVyP73ru", false, nullopt, 221);
  shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
  pit2->insertOrUpdateOutRecord(*face1, *interest2);

  lp::Nack nack1 = makeNack(*interest1, lp::NackReason::CONGESTION);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack1);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 1);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);

  lp::Nack nack2 = makeNack(*interest2, lp::NackReason::CONGESTION);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack2);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 1);

  // record Nack on PIT out-record
  auto outRecord1 = pit1->getOutRecord(*face1);
  BOOST_REQUIRE(outRecord1 != pit1->out_end());
  BOOST_REQUIRE(outRecord1->getIncomingNack() != nullptr);
  BOOST_CHECK_EQUAL(outRecord1->getIncomingNack()->getReason(), lp::NackReason::CONGESTION);

  // drop if no PIT entry
  lp::Nack nack3 = makeNack(*makeInterest("/yEcw5HhdM", false, nullopt, 243), lp::NackReason::CONGESTION);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack3);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);

  // drop if no out-record
  auto interest4 = makeInterest("/Etab4KpY", false, nullopt, 157);
  shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
  pit4->insertOrUpdateOutRecord(*face1, *interest4);

  lp::Nack nack4a = makeNack(*interest4, lp::NackReason::CONGESTION);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face2, 0), nack4a);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);

  // drop if Nonce does not match out-record
  lp::Nack nack4b = makeNack(*makeInterest("/Etab4KpY", false, nullopt, 294), lp::NackReason::CONGESTION);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face1, 0), nack4b);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);

  // drop if inFace is multi-access
  pit4->insertOrUpdateOutRecord(*face3, *interest4);
  strategyA.afterReceiveNack_count = 0;
  strategyB.afterReceiveNack_count = 0;
  forwarder.onIncomingNack(FaceEndpoint(*face3, 0), nack4a);
  BOOST_CHECK_EQUAL(strategyA.afterReceiveNack_count, 0);
  BOOST_CHECK_EQUAL(strategyB.afterReceiveNack_count, 0);
}

BOOST_AUTO_TEST_CASE(OutgoingNack)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace("dummy://", "dummy://",
                       ndn::nfd::FACE_SCOPE_NON_LOCAL,
                       ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                       ndn::nfd::LINK_TYPE_MULTI_ACCESS);

  Pit& pit = forwarder.getPit();

  lp::NackHeader nackHeader;
  nackHeader.setReason(lp::NackReason::CONGESTION);

  // don't send Nack if there's no in-record
  auto interest1 = makeInterest("/fM5IVEtC", false, nullopt, 719);
  shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
  pit1->insertOrUpdateInRecord(*face1, *interest1);

  face2->sentNacks.clear();
  forwarder.onOutgoingNack(pit1, FaceEndpoint(*face2, 0), nackHeader);
  BOOST_CHECK_EQUAL(face2->sentNacks.size(), 0);

  // send Nack with correct Nonce
  auto interest2a = makeInterest("/Vi8tRm9MG3", false, nullopt, 152);
  shared_ptr<pit::Entry> pit2 = pit.insert(*interest2a).first;
  pit2->insertOrUpdateInRecord(*face1, *interest2a);
  auto interest2b = makeInterest("/Vi8tRm9MG3", false, nullopt, 808);
  pit2->insertOrUpdateInRecord(*face2, *interest2b);

  face1->sentNacks.clear();
  forwarder.onOutgoingNack(pit2, FaceEndpoint(*face1, 0), nackHeader);
  BOOST_REQUIRE_EQUAL(face1->sentNacks.size(), 1);
  BOOST_CHECK_EQUAL(face1->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
  BOOST_CHECK_EQUAL(face1->sentNacks.back().getInterest().getNonce(), 152);

  // erase in-record
  auto inRecord2a = pit2->getInRecord(*face1);
  BOOST_CHECK(inRecord2a == pit2->in_end());

  // send Nack with correct Nonce
  face2->sentNacks.clear();
  forwarder.onOutgoingNack(pit2, FaceEndpoint(*face2, 0), nackHeader);
  BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::CONGESTION);
  BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().getNonce(), 808);

  // erase in-record
  auto inRecord2b = pit2->getInRecord(*face1);
  BOOST_CHECK(inRecord2b == pit2->in_end());

  // don't send Nack to multi-access face
  auto interest2c = makeInterest("/Vi8tRm9MG3", false, nullopt, 228);
  pit2->insertOrUpdateInRecord(*face3, *interest2c);

  face3->sentNacks.clear();
  forwarder.onOutgoingNack(pit1, FaceEndpoint(*face3, 0), nackHeader);
  BOOST_CHECK_EQUAL(face3->sentNacks.size(), 0);
}

BOOST_AUTO_TEST_CASE(InterestLoopNack)
{
  auto face1 = addFace();
  auto face2 = addFace();
  auto face3 = addFace("dummy://", "dummy://",
                       ndn::nfd::FACE_SCOPE_NON_LOCAL,
                       ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                       ndn::nfd::LINK_TYPE_MULTI_ACCESS);
  auto face4 = addFace();

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/zT4XwK0Hnx").first;
  fib.addOrUpdateNextHop(*entry, *face4, 0);

  // receive Interest on face1
  face1->sentNacks.clear();
  auto interest1a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
  face1->receiveInterest(*interest1a, 0);
  BOOST_CHECK(face1->sentNacks.empty());

  // receive Interest with duplicate Nonce on face1: legit retransmission
  face1->sentNacks.clear();
  auto interest1b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
  face1->receiveInterest(*interest1b, 0);
  BOOST_CHECK(face1->sentNacks.empty());

  // receive Interest with duplicate Nonce on face2
  face2->sentNacks.clear();
  auto interest2a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
  face2->receiveInterest(*interest2a, 0);
  BOOST_REQUIRE_EQUAL(face2->sentNacks.size(), 1);
  BOOST_CHECK_EQUAL(face2->sentNacks.back().getInterest().wireEncode(), interest2a->wireEncode());
  BOOST_CHECK_EQUAL(face2->sentNacks.back().getReason(), lp::NackReason::DUPLICATE);

  // receive Interest with new Nonce on face2
  face2->sentNacks.clear();
  auto interest2b = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 944);
  face2->receiveInterest(*interest2b, 0);
  BOOST_CHECK(face2->sentNacks.empty());

  // receive Interest with duplicate Nonce on face3, don't send Nack to multi-access face
  face3->sentNacks.clear();
  auto interest3a = makeInterest("/zT4XwK0Hnx/28JBUvbEzc", false, nullopt, 732);
  face3->receiveInterest(*interest3a, 0);
  BOOST_CHECK(face3->sentNacks.empty());
}

BOOST_AUTO_TEST_CASE(InterestLoopWithShortLifetime) // Bug 1953
{
  auto face1 = addFace();
  auto face2 = addFace();

  // cause an Interest sent out of face2 to loop back into face1 after a delay
  face2->afterSend.connect([face1, face2] (uint32_t pktType) {
    if (pktType == tlv::Interest) {
      auto interest = make_shared<Interest>(face2->sentInterests.back());
      getScheduler().schedule(170_ms, [face1, interest] { face1->receiveInterest(*interest, 0); });
    }
  });

  Fib& fib = forwarder.getFib();
  fib::Entry* entry = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entry, *face2, 0);

  // receive an Interest
  auto interest = makeInterest("/A/1", false, 50_ms, 82101183);
  face1->receiveInterest(*interest, 0);

  // interest should be forwarded only once, as long as Nonce is in Dead Nonce List
  BOOST_ASSERT(25_ms * 40 < forwarder.getDeadNonceList().getLifetime());
  this->advanceClocks(25_ms, 40);

  BOOST_CHECK_EQUAL(face2->sentInterests.size(), 1);

  // It's unnecessary to check that Interest with duplicate Nonce can be forwarded again
  // after it's gone from Dead Nonce List, because the entry lifetime of Dead Nonce List
  // is an implementation decision. NDN protocol requires Name+Nonce to be unique,
  // without specifying when Name+Nonce could repeat. Forwarder is permitted to suppress
  // an Interest if its Name+Nonce has appeared any point in the past.
}

BOOST_AUTO_TEST_CASE(PitLeak) // Bug 3484
{
  auto face1 = addFace();
  auto interest = makeInterest("/hcLSAsQ9A", false, 2_s, 61883075);

  DeadNonceList& dnl = forwarder.getDeadNonceList();
  dnl.add(interest->getName(), interest->getNonce());
  Pit& pit = forwarder.getPit();
  BOOST_REQUIRE_EQUAL(pit.size(), 0);

  forwarder.startProcessInterest(FaceEndpoint(*face1, 0), *interest);
  this->advanceClocks(100_ms, 20_s);
  BOOST_CHECK_EQUAL(pit.size(), 0);
}

BOOST_AUTO_TEST_CASE(UnsolicitedData)
{
  auto face1 = addFace();
  auto data = makeData("/A");

  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 0);
  forwarder.onIncomingData(FaceEndpoint(*face1, 0), *data);
  this->advanceClocks(1_ms, 10_ms);
  BOOST_CHECK_EQUAL(forwarder.getCounters().nUnsolicitedData, 1);
}

BOOST_AUTO_TEST_SUITE_END() // TestForwarder
BOOST_AUTO_TEST_SUITE_END() // Fw

} // namespace tests
} // namespace nfd
