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

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

namespace nfd {
namespace tests {

BOOST_AUTO_TEST_SUITE(Table)
BOOST_FIXTURE_TEST_SUITE(TestCleanup, GlobalIoFixture)

BOOST_AUTO_TEST_SUITE(FaceRemoval)

BOOST_AUTO_TEST_CASE(Basic)
{
  NameTree nameTree(16);
  Fib fib(nameTree);
  Pit pit(nameTree);
  shared_ptr<Face> face1 = make_shared<DummyFace>();

  for (uint64_t i = 0; i < 300; ++i) {
    Name name = Name("/P").appendVersion(i);

    fib::Entry* fibEntry = fib.insert(name).first;
    fib.addOrUpdateNextHop(*fibEntry, *face1, 0);

    shared_ptr<Interest> interest = makeInterest(name);
    shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
    if ((i & 0x01) != 0) {
      pitEntry->insertOrUpdateInRecord(*face1, *interest);
    }
    if ((i & 0x02) != 0) {
      pitEntry->insertOrUpdateOutRecord(*face1, *interest);
    }
  }
  BOOST_CHECK_EQUAL(fib.size(), 300);
  BOOST_CHECK_EQUAL(pit.size(), 300);

  cleanupOnFaceRemoval(nameTree, fib, pit, *face1);
  BOOST_CHECK_EQUAL(fib.size(), 0);
  BOOST_CHECK_EQUAL(pit.size(), 300);
  for (const pit::Entry& pitEntry : pit) {
    BOOST_CHECK_EQUAL(pitEntry.hasInRecords(), false);
    BOOST_CHECK_EQUAL(pitEntry.hasOutRecords(), false);
  }
}

BOOST_AUTO_TEST_CASE(RemoveFibNexthops)
{
  FaceTable faceTable;
  Forwarder forwarder(faceTable);
  NameTree& nameTree = forwarder.getNameTree();
  Fib& fib = forwarder.getFib();

  auto face1 = make_shared<DummyFace>();
  auto face2 = make_shared<DummyFace>();
  faceTable.add(face1);
  faceTable.add(face2);

  // {}
  size_t nNameTreeEntriesBefore = nameTree.size();
  BOOST_CHECK_EQUAL(fib.size(), 0);

  fib::Entry* entryA = fib.insert("/A").first;
  fib.addOrUpdateNextHop(*entryA, *face1, 0);
  fib.addOrUpdateNextHop(*entryA, *face2, 0);
  // {'/A':[1,2]}

  fib::Entry* entryB = fib.insert("/B").first;
  fib.addOrUpdateNextHop(*entryB, *face1, 0);
  // {'/A':[1,2], '/B':[1]}

  fib::Entry* entryC = fib.insert("/C").first;
  fib.addOrUpdateNextHop(*entryC, *face2, 1);
  // {'/A':[1,2], '/B':[1], '/C':[2]}

  fib::Entry* entryB1 = fib.insert("/B/1").first;
  fib.addOrUpdateNextHop(*entryB1, *face1, 0);
  // {'/A':[1,2], '/B':[1], '/B/1':[1], '/C':[2]}

  fib::Entry* entryB12 = fib.insert("/B/1/2").first;
  fib.addOrUpdateNextHop(*entryB12, *face1, 0);
  // {'/A':[1,2], '/B':[1], '/B/1':[1], '/B/1/2':[1], '/C':[2]}

  // ---- close face1 ----
  face1->close();
  BOOST_CHECK_EQUAL(face1->getState(), face::FaceState::CLOSED);
  // {'/A':[2], '/C':[2]}
  BOOST_CHECK_EQUAL(fib.size(), 2);

  const fib::Entry& foundA = fib.findLongestPrefixMatch("/A");
  BOOST_CHECK_EQUAL(foundA.getPrefix(), "/A");
  BOOST_CHECK_EQUAL(foundA.getNextHops().size(), 1);
  BOOST_CHECK_EQUAL(&foundA.getNextHops().begin()->getFace(), face2.get());

  BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch("/B").getPrefix(), "/");

  // ---- close face2 ----
  face2->close();
  BOOST_CHECK_EQUAL(face2->getState(), face::FaceState::CLOSED);
  BOOST_CHECK_EQUAL(fib.size(), 0);
  BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
}

BOOST_AUTO_TEST_CASE(DeletePitInOutRecords)
{
  FaceTable faceTable;
  Forwarder forwarder(faceTable);
  Pit& pit = forwarder.getPit();

  auto face1 = make_shared<DummyFace>();
  auto face2 = make_shared<DummyFace>();
  faceTable.add(face1);
  faceTable.add(face2);

  // {}
  BOOST_CHECK_EQUAL(pit.size(), 0);

  shared_ptr<Interest> interestA = makeInterest("/A");
  shared_ptr<pit::Entry> entryA = pit.insert(*interestA).first;
  entryA->insertOrUpdateInRecord(*face1, *interestA);
  entryA->insertOrUpdateInRecord(*face2, *interestA);
  entryA->insertOrUpdateOutRecord(*face1, *interestA);
  entryA->insertOrUpdateOutRecord(*face2, *interestA);
  // {'/A':[1,2]}

  shared_ptr<Interest> interestB = makeInterest("/B");
  shared_ptr<pit::Entry> entryB = pit.insert(*interestB).first;
  entryB->insertOrUpdateInRecord(*face1, *interestB);
  entryB->insertOrUpdateOutRecord(*face1, *interestB);
  // {'/A':[1,2], '/B':[1]}

  shared_ptr<Interest> interestC = makeInterest("/C");
  shared_ptr<pit::Entry> entryC = pit.insert(*interestC).first;
  entryC->insertOrUpdateInRecord(*face2, *interestC);
  entryC->insertOrUpdateOutRecord(*face2, *interestC);
  // {'/A':[1,2], '/B':[1], '/C':[2]}
  BOOST_CHECK_EQUAL(pit.size(), 3);

  // ---- close face1 ----
  face1->close();
  BOOST_CHECK_EQUAL(face1->getState(), face::FaceState::CLOSED);
  // {'/A':[2], '/B':[], '/C':[2]}
  BOOST_CHECK_EQUAL(pit.size(), 3);

  shared_ptr<pit::Entry> foundA = pit.find(*interestA);
  BOOST_REQUIRE(foundA != nullptr);
  BOOST_REQUIRE_EQUAL(foundA->getInRecords().size(), 1);
  BOOST_CHECK_EQUAL(&foundA->getInRecords().front().getFace(), face2.get());
  BOOST_REQUIRE_EQUAL(foundA->getOutRecords().size(), 1);
  BOOST_CHECK_EQUAL(&foundA->getOutRecords().front().getFace(), face2.get());
}

BOOST_AUTO_TEST_SUITE_END() // FaceRemovalCleanup

BOOST_AUTO_TEST_SUITE_END() // TestCleanup
BOOST_AUTO_TEST_SUITE_END() // Table

} // namespace tests
} // namespace nfd
