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

#include "test-common.hpp"
#include "lsa/lsa.hpp"
#include "name-prefix-list.hpp"

#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>

#include <unistd.h>

namespace nlsr {
namespace test {

class LsdbFixture : public UnitTestTimeFixture
{
public:
  LsdbFixture()
    : face(m_ioService, m_keyChain, {true, true})
    , conf(face, m_keyChain)
    , confProcessor(conf)
    , lsdb(face, m_keyChain, conf)
    , REGISTER_COMMAND_PREFIX("/localhost/nfd/rib")
    , REGISTER_VERB("register")
  {
    addIdentity("/ndn/site/%C1.Router/this-router");

    advanceClocks(10_ms);
    face.sentInterests.clear();
  }

  void
  extractParameters(ndn::Interest& interest, ndn::Name::Component& verb,
                    ndn::nfd::ControlParameters& extractedParameters)
  {
    const ndn::Name& name = interest.getName();
    verb = name[REGISTER_COMMAND_PREFIX.size()];
    const ndn::Name::Component& parameterComponent = name[REGISTER_COMMAND_PREFIX.size() + 1];

    ndn::Block rawParameters = parameterComponent.blockFromValue();
    extractedParameters.wireDecode(rawParameters);
  }

  void
  areNamePrefixListsEqual(NamePrefixList& lhs, NamePrefixList& rhs)
  {

    typedef std::list<ndn::Name> NameList;

    NameList lhsList = lhs.getNames();
    NameList rhsList = rhs.getNames();

    BOOST_REQUIRE_EQUAL(lhsList.size(), rhsList.size());

    NameList::iterator i = lhsList.begin();
    NameList::iterator j = rhsList.begin();

    for (; i != lhsList.end(); ++i, ++j) {
      BOOST_CHECK_EQUAL(*i, *j);
    }
  }

  void
  isFirstNameLsaEqual(const Lsdb& otherLsdb)
  {
    auto selfLsaRange = lsdb.getLsdbIterator<NameLsa>();
    auto otherLsaRange = otherLsdb.getLsdbIterator<NameLsa>();

    if (selfLsaRange.first != selfLsaRange.second && otherLsaRange.first != otherLsaRange.second) {
      auto ownLsa = std::static_pointer_cast<NameLsa>(*selfLsaRange.first);
      auto otherLsa = std::static_pointer_cast<NameLsa>(*otherLsaRange.first);
      BOOST_CHECK_EQUAL(ownLsa->getNpl(), otherLsa->getNpl());
      return;
    }
    BOOST_CHECK(false);
  }

  void
  checkSignalResult(LsdbUpdate updateType,
                    const std::shared_ptr<Lsa>& lsaPtr,
                    const std::list<ndn::Name>& namesToAdd,
                    const std::list<ndn::Name>& namesToRemove)
  {
    BOOST_CHECK(updateHappened);
    BOOST_CHECK_EQUAL(lsaPtrCheck->getOriginRouter(), lsaPtr->getOriginRouter());
    BOOST_CHECK_EQUAL(lsaPtrCheck->getType(), lsaPtr->getType());
    BOOST_CHECK(updateType == updateTypeCheck);
    BOOST_CHECK(namesToAdd == namesToAddCheck);
    BOOST_CHECK(namesToRemove == namesToRemoveCheck);
    updateHappened = false;
  }

  void
  connectSignal()
  {
    lsdb.onLsdbModified.connect(
      [&] (std::shared_ptr<Lsa> lsa, LsdbUpdate updateType,
           const auto& namesToAdd, const auto& namesToRemove) {
        lsaPtrCheck = lsa;
        updateTypeCheck = updateType;
        namesToAddCheck = namesToAdd;
        namesToRemoveCheck = namesToRemove;
        updateHappened = true;
      }
    );
  }

public:
  ndn::util::DummyClientFace face;
  ConfParameter conf;
  DummyConfFileProcessor confProcessor;
  Lsdb lsdb;

  ndn::Name REGISTER_COMMAND_PREFIX;
  ndn::Name::Component REGISTER_VERB;

  LsdbUpdate updateTypeCheck = LsdbUpdate::INSTALLED;
  std::list<ndn::Name> namesToAddCheck;
  std::list<ndn::Name> namesToRemoveCheck;
  std::shared_ptr<Lsa> lsaPtrCheck = nullptr;
  bool updateHappened = false;
};

BOOST_FIXTURE_TEST_SUITE(TestLsdb, LsdbFixture)

BOOST_AUTO_TEST_CASE(LsdbSync)
{
  ndn::Name interestName("/ndn/NLSR/LSA/cs/%C1.Router/router2/name");
  uint64_t oldSeqNo = 82;

  ndn::Name oldInterestName = interestName;
  oldInterestName.appendNumber(oldSeqNo);

  lsdb.expressInterest(oldInterestName, 0);
  advanceClocks(10_ms);

  std::vector<ndn::Interest>& interests = face.sentInterests;

  BOOST_REQUIRE(interests.size() > 0);

  bool didFindInterest = false;
  for (const auto& interest : interests) {
    didFindInterest = didFindInterest || interest.getName() == oldInterestName;
  }

  BOOST_CHECK(didFindInterest);
  interests.clear();

  ndn::time::steady_clock::TimePoint deadline = ndn::time::steady_clock::now() +
    ndn::time::seconds(LSA_REFRESH_TIME_MAX);

  // Simulate an LSA interest timeout
  lsdb.onFetchLsaError(ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT, "Timeout",
                       oldInterestName, 0, deadline, interestName, oldSeqNo);
  advanceClocks(10_ms);

  BOOST_REQUIRE(interests.size() > 0);

  didFindInterest = false;
  for (const auto& interest : interests) {
    didFindInterest = didFindInterest || interest.getName() == oldInterestName;
  }

  BOOST_CHECK(didFindInterest);
  interests.clear();

  uint64_t newSeqNo = 83;

  ndn::Name newInterestName = interestName;
  newInterestName.appendNumber(newSeqNo);

  lsdb.expressInterest(newInterestName, 0);
  advanceClocks(10_ms);

  BOOST_REQUIRE(interests.size() > 0);

  didFindInterest = false;
  for (const auto& interest : interests) {
    didFindInterest = didFindInterest || interest.getName() == newInterestName;
  }

  BOOST_CHECK(didFindInterest);

  interests.clear();

  // Simulate an LSA interest timeout where the sequence number is outdated
  lsdb.onFetchLsaError(ndn::util::SegmentFetcher::ErrorCode::INTEREST_TIMEOUT, "Timeout",
                       oldInterestName, 0, deadline, interestName, oldSeqNo);
  advanceClocks(10_ms);

  // Interest should not be expressed for outdated sequence number
  BOOST_CHECK_EQUAL(interests.size(), 0);
}

BOOST_AUTO_TEST_CASE(LsdbSegmentedData)
{
  // Add a lot of NameLSAs to exceed max packet size
  ndn::Name originRouter("/ndn/site/%C1.Router/this-router");

  auto nameLsa = lsdb.findLsa<NameLsa>(originRouter);
  BOOST_REQUIRE(nameLsa != nullptr);
  uint64_t seqNo = nameLsa->getSeqNo();

  ndn::Name prefix("/ndn/edu/memphis/netlab/research/nlsr/test/prefix/");

  int nPrefixes = 0;
  while (nameLsa->wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE) {
    nameLsa->addName(ndn::Name(prefix).appendNumber(++nPrefixes));
    break;
  }
  lsdb.installLsa(nameLsa);

  // Create another Lsdb and expressInterest
  ndn::util::DummyClientFace face2(m_ioService, m_keyChain, {true, true});
  face.linkTo(face2);

  ConfParameter conf2(face2, m_keyChain);
  std::string config = R"CONF(
              trust-anchor
                {
                  type any
                }
            )CONF";
  conf2.getValidator().load(config, "config-file-from-string");

  Lsdb lsdb2(face2, m_keyChain, conf2);

  advanceClocks(ndn::time::milliseconds(10), 10);

  ndn::Name interestName("/localhop/ndn/nlsr/LSA/site/%C1.Router/this-router/NAME");
  interestName.appendNumber(seqNo);
  lsdb2.expressInterest(interestName, 0/*= timeout count*/);

  advanceClocks(ndn::time::milliseconds(200), 20);

  isFirstNameLsaEqual(lsdb2);
}

BOOST_AUTO_TEST_CASE(SegmentLsaData)
{
  ndn::Name originRouter("/ndn/site/%C1.Router/this-router");

  auto lsa = lsdb.findLsa<NameLsa>(originRouter);
  uint64_t seqNo = lsa->getSeqNo();

  ndn::Name prefix("/ndn/edu/memphis/netlab/research/nlsr/test/prefix/");

  int nPrefixes = 0;
  while (lsa->wireEncode().size() < ndn::MAX_NDN_PACKET_SIZE) {
    lsa->addName(ndn::Name(prefix).appendNumber(++nPrefixes));
  }
  lsdb.installLsa(lsa);

  ndn::Block expectedDataContent = lsa->wireEncode();

  ndn::Name interestName("/localhop/ndn/nlsr/LSA/site/%C1.Router/this-router/NAME/");
  interestName.appendNumber(seqNo);

  ndn::util::DummyClientFace face2(m_ioService, m_keyChain, {true, true});
  face.linkTo(face2);

  auto fetcher = ndn::util::SegmentFetcher::start(face2, ndn::Interest(interestName),
                                                  ndn::security::getAcceptAllValidator());
  fetcher->onComplete.connect([&expectedDataContent] (ndn::ConstBufferPtr bufferPtr) {
                                ndn::Block block(bufferPtr);
                                BOOST_CHECK_EQUAL(expectedDataContent, block);
                              });

  advanceClocks(ndn::time::milliseconds(1), 100);
  fetcher->stop();
}

BOOST_AUTO_TEST_CASE(ReceiveSegmentedLsaData)
{
  ndn::Name router("/ndn/cs/%C1.Router/router1");
  uint64_t seqNo = 12;
  NamePrefixList prefixList;

  NameLsa lsa(router, seqNo, ndn::time::system_clock::now(), prefixList);

  ndn::Name prefix("/prefix/");

  for (int nPrefixes = 0; nPrefixes < 3; ++nPrefixes) {
    lsa.addName(ndn::Name(prefix).appendNumber(nPrefixes));
  }

  ndn::Name interestName("/localhop/ndn/nlsr/LSA/cs/%C1.Router/router1/NAME/");
  interestName.appendNumber(seqNo);

  ndn::Block block = lsa.wireEncode();
  lsdb.afterFetchLsa(block.getBuffer(), interestName);

  auto foundLsa = std::static_pointer_cast<NameLsa>(lsdb.findLsa(lsa.getOriginRouter(), lsa.getType()));
  BOOST_REQUIRE(foundLsa != nullptr);

  BOOST_CHECK_EQUAL(foundLsa->wireEncode(), lsa.wireEncode());
}

BOOST_AUTO_TEST_CASE(LsdbRemoveAndExists)
{
  ndn::time::system_clock::TimePoint testTimePoint =  ndn::time::system_clock::now();
  NamePrefixList npl1;

  std::string s1 = "name1";
  std::string s2 = "name2";
  std::string router1 = "/router1/1";

  npl1.insert(s1);
  npl1.insert(s2);

  // For NameLsa lsType is name.
  // 12 is seqNo, randomly generated.
  // 1800 seconds is the default life time.
  NameLsa nlsa1(router1, 12, testTimePoint, npl1);

  Lsdb& lsdb1(lsdb);

  lsdb1.installLsa(std::make_shared<NameLsa>(nlsa1));

  BOOST_CHECK(lsdb1.doesLsaExist(router1, Lsa::Type::NAME));

  lsdb1.removeLsa(router1, Lsa::Type::NAME);

  BOOST_CHECK_EQUAL(lsdb1.doesLsaExist(router1, Lsa::Type::NAME), false);
}

BOOST_AUTO_TEST_CASE(InstallNameLsa)
{
  // Install lsa with name1 and name2
  ndn::Name name1("/ndn/name1");
  ndn::Name name2("/ndn/name2");

  NamePrefixList prefixes;
  prefixes.insert(name1);
  prefixes.insert(name2);

  std::string otherRouter("/ndn/site/%C1.router/other-router");
  ndn::time::system_clock::TimePoint MAX_TIME = ndn::time::system_clock::TimePoint::max();

  NameLsa lsa(otherRouter, 1, MAX_TIME, prefixes);
  lsdb.installLsa(std::make_shared<NameLsa>(lsa));

  BOOST_REQUIRE_EQUAL(lsdb.doesLsaExist(otherRouter, Lsa::Type::NAME), true);
  NamePrefixList& nameList = std::static_pointer_cast<NameLsa>(lsdb.findLsa(otherRouter, Lsa::Type::NAME))->getNpl();

  BOOST_CHECK_EQUAL(nameList, prefixes);
  //areNamePrefixListsEqual(nameList, prefixes);

  // Add a prefix: name3
  ndn::Name name3("/ndn/name3");
  prefixes.insert(name3);

  NameLsa addLsa(otherRouter, 2, MAX_TIME, prefixes);
  lsdb.installLsa(std::make_shared<NameLsa>(addLsa));

  // Lsa should include name1, name2, and name3
  BOOST_CHECK_EQUAL(nameList, prefixes);

  // Remove a prefix: name2
  prefixes.remove(name2);

  NameLsa removeLsa(otherRouter, 3, MAX_TIME, prefixes);
  lsdb.installLsa(std::make_shared<NameLsa>(removeLsa));

  // Lsa should include name1 and name3
  BOOST_CHECK_EQUAL(nameList, prefixes);

  // Add and remove a prefix: add name2, remove name3
  prefixes.insert(name2);
  prefixes.remove(name3);

  NameLsa addAndRemoveLsa(otherRouter, 4, MAX_TIME, prefixes);
  lsdb.installLsa(std::make_shared<NameLsa>(addAndRemoveLsa));

  // Lsa should include name1 and name2
  BOOST_CHECK_EQUAL(nameList, prefixes);

  // Install a completely new list of prefixes
  ndn::Name name4("/ndn/name4");
  ndn::Name name5("/ndn/name5");

  NamePrefixList newPrefixes;
  newPrefixes.insert(name4);
  newPrefixes.insert(name5);

  NameLsa newLsa(otherRouter, 5, MAX_TIME, newPrefixes);
  lsdb.installLsa(std::make_shared<NameLsa>(newLsa));

  // Lsa should include name4 and name5
  BOOST_CHECK_EQUAL(nameList, newPrefixes);
}

BOOST_AUTO_TEST_CASE(TestIsLsaNew)
{
  ndn::Name originRouter("/ndn/memphis/%C1.Router/other-router");

  // Install Name LSA
  NamePrefixList nameList;
  NameLsa lsa(originRouter, 999, ndn::time::system_clock::TimePoint::max(), nameList);

  lsdb.installLsa(std::make_shared<NameLsa>(lsa));

  // Lower NameLSA sequence number
  uint64_t lowerSeqNo = 998;
  BOOST_CHECK(!lsdb.isLsaNew(originRouter, Lsa::Type::NAME, lowerSeqNo));

  // Same NameLSA sequence number
  uint64_t sameSeqNo = 999;
  BOOST_CHECK(!lsdb.isLsaNew(originRouter, Lsa::Type::NAME, sameSeqNo));

  // Higher NameLSA sequence number
  uint64_t higherSeqNo = 1000;
  BOOST_CHECK(lsdb.isLsaNew(originRouter, Lsa::Type::NAME, higherSeqNo));
}

BOOST_AUTO_TEST_CASE(LsdbSignals)
{
  connectSignal();
  auto testTimePoint = ndn::time::system_clock::now() + 3600_s;
  ndn::Name router2("/router2");
  AdjLsa adjLsa(router2, 12, testTimePoint, 2, conf.getAdjacencyList());
  std::shared_ptr<Lsa> lsaPtr = std::make_shared<AdjLsa>(adjLsa);
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::INSTALLED, lsaPtr, {}, {});

  adjLsa.setSeqNo(13);
  updateHappened = false;
  lsaPtr = std::make_shared<AdjLsa>(adjLsa);
  lsdb.installLsa(lsaPtr);
  BOOST_CHECK(!updateHappened);

  Adjacent adj("Neighbor1");
  adjLsa.setSeqNo(14);
  adjLsa.addAdjacent(adj);
  lsaPtr = std::make_shared<AdjLsa>(adjLsa);
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::UPDATED, lsaPtr, {}, {});

  lsdb.removeLsa(lsaPtrCheck->getOriginRouter(), Lsa::Type::ADJACENCY);
  checkSignalResult(LsdbUpdate::REMOVED, lsaPtr, {}, {});

  // Name LSA
  NamePrefixList npl1{"name1", "name2"};
  NameLsa nameLsa(router2, 12, testTimePoint, npl1);
  lsaPtr = std::make_shared<NameLsa>(nameLsa);
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::INSTALLED, lsaPtr, {}, {});

  nameLsa.setSeqNo(13);
  lsaPtr = std::make_shared<NameLsa>(nameLsa);
  lsdb.installLsa(lsaPtr);
  BOOST_CHECK(!updateHappened);

  NamePrefixList npl2{"name2", "name3"};
  NameLsa nameLsa2(router2, 14, testTimePoint, npl2);
  lsaPtr = std::make_shared<NameLsa>(nameLsa2);
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::UPDATED, lsaPtr, {"name3"}, {"name1"});

  lsdb.removeLsa(lsaPtrCheck->getOriginRouter(), Lsa::Type::NAME);
  checkSignalResult(LsdbUpdate::REMOVED, lsaPtr, {}, {});

  // Coordinate LSA
  lsaPtr = std::make_shared<CoordinateLsa>(CoordinateLsa("router1", 12, testTimePoint, 2.5, {30}));
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::INSTALLED, lsaPtr, {}, {});

  lsaPtr = std::make_shared<CoordinateLsa>(CoordinateLsa("router1", 13, testTimePoint, 2.5, {30}));
  lsdb.installLsa(lsaPtr);
  BOOST_CHECK(!updateHappened);

  lsaPtr = std::make_shared<CoordinateLsa>(CoordinateLsa("router1", 14, testTimePoint, 2.5, {40}));
  lsdb.installLsa(lsaPtr);
  checkSignalResult(LsdbUpdate::UPDATED, lsaPtr, {}, {});

  lsdb.removeLsa(lsaPtrCheck->getOriginRouter(), Lsa::Type::COORDINATE);
  checkSignalResult(LsdbUpdate::REMOVED, lsaPtr, {}, {});
}

BOOST_AUTO_TEST_SUITE_END() // TestLsdb

} // namespace test
} // namespace nlsr
