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

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

#include <ndn-cxx/util/concepts.hpp>

namespace nfd::tests {

NDN_CXX_ASSERT_FORWARD_ITERATOR(StrategyChoice::const_iterator);

class StrategyChoiceFixture : public GlobalIoFixture
{
protected:
  StrategyChoiceFixture()
  {
    DummyStrategy::registerAs(strategyNameP);
    DummyStrategy::registerAs(strategyNameQ);
  }

  /** \brief Insert StrategyChoice entry at \p prefix for \p instanceName.
   *  \return constructed instance name
   */
  Name
  insertAndGet(const Name& prefix, const Name& instanceName)
  {
    BOOST_REQUIRE(sc.insert(prefix, instanceName));
    auto [isFound, foundName] = sc.get(prefix);
    BOOST_REQUIRE(isFound);
    return foundName;
  }

  /** \brief Determine whether the effective strategy type at \p prefix is \p S.
   *  \tparam S expected strategy type
   */
  template<typename S>
  bool
  isStrategyType(const Name& prefix)
  {
    auto& effectiveStrategy = sc.findEffectiveStrategy(prefix);
    return dynamic_cast<S*>(&effectiveStrategy) != nullptr;
  }

  template<typename Q>
  Name
  findInstanceName(const Q& query)
  {
    return sc.findEffectiveStrategy(query).getInstanceName();
  }

protected:
  FaceTable faceTable;
  Forwarder forwarder{faceTable};
  StrategyChoice& sc{forwarder.getStrategyChoice()};

  const Name strategyNameP = Name("/strategy-choice-P").appendVersion(0);
  const Name strategyNameQ = Name("/strategy-choice-Q").appendVersion(0);
};

BOOST_AUTO_TEST_SUITE(Table)
BOOST_FIXTURE_TEST_SUITE(TestStrategyChoice, StrategyChoiceFixture)

BOOST_AUTO_TEST_CASE(Versioning)
{
  const auto strategyNameV = Name("/strategy-choice-V");
  const auto strategyNameV0 = Name("/strategy-choice-V").appendVersion(0);
  const auto strategyNameV1 = Name("/strategy-choice-V").appendVersion(1);
  const auto strategyNameV2 = Name("/strategy-choice-V").appendVersion(2);
  const auto strategyNameV3 = Name("/strategy-choice-V").appendVersion(3);
  const auto strategyNameV4 = Name("/strategy-choice-V").appendVersion(4);
  const auto strategyNameV5 = Name("/strategy-choice-V").appendVersion(5);

  VersionedDummyStrategy<1>::registerAs(strategyNameV1);
  VersionedDummyStrategy<3>::registerAs(strategyNameV3);
  VersionedDummyStrategy<4>::registerAs(strategyNameV4);

  // unversioned: choose latest version
  BOOST_CHECK_EQUAL(this->insertAndGet("/A", strategyNameV), strategyNameV4);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<4>>("/A"));

  // exact version: choose same version
  BOOST_CHECK_EQUAL(this->insertAndGet("/B", strategyNameV1), strategyNameV1);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<1>>("/B"));
  BOOST_CHECK_EQUAL(this->insertAndGet("/C", strategyNameV3), strategyNameV3);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<3>>("/C"));
  BOOST_CHECK_EQUAL(this->insertAndGet("/D", strategyNameV4), strategyNameV4);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<4>>("/D"));

  // lower version: choose next higher version
  BOOST_CHECK_EQUAL(this->insertAndGet("/E", strategyNameV0), strategyNameV0);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<1>>("/E"));
  BOOST_CHECK_EQUAL(this->insertAndGet("/F", strategyNameV2), strategyNameV2);
  BOOST_CHECK(this->isStrategyType<VersionedDummyStrategy<3>>("/F"));

  // higher version: failure
  StrategyChoice::InsertResult res5 = sc.insert("/G", strategyNameV5);
  BOOST_CHECK(!res5);
  BOOST_CHECK(!res5.isRegistered());
}

BOOST_AUTO_TEST_CASE(Parameters)
{
  // no parameters
  BOOST_CHECK_EQUAL(this->insertAndGet("/A", strategyNameP), strategyNameP);

  // one parameter
  Name oneParamName = Name(strategyNameP).append("param");
  BOOST_CHECK_EQUAL(this->insertAndGet("/B", oneParamName), oneParamName);

  // two parameters
  Name twoParamName = Name(strategyNameP).append("x").append("y");
  BOOST_CHECK_EQUAL(this->insertAndGet("/C", twoParamName), twoParamName);

  // parameter without version is disallowed
  Name oneParamUnversioned = strategyNameP.getPrefix(-1).append("param");
  BOOST_CHECK(!sc.insert("/D", oneParamUnversioned));
}

BOOST_AUTO_TEST_CASE(InsertLongName)
{
  Name n1;
  while (n1.size() < NameTree::getMaxDepth()) {
    n1.append("A");
  }
  Name n2 = n1;
  while (n2.size() < NameTree::getMaxDepth() * 2) {
    n2.append("B");
  }

  BOOST_CHECK(sc.insert(n1, strategyNameP));
  BOOST_CHECK(!sc.insert(n2, strategyNameP));
}

BOOST_AUTO_TEST_CASE(Get)
{
  BOOST_CHECK(sc.insert("/", strategyNameP));
  // { '/'=>P }

  auto getRoot = sc.get("/");
  BOOST_CHECK_EQUAL(getRoot.first, true);
  BOOST_CHECK_EQUAL(getRoot.second, strategyNameP);

  auto getA = sc.get("/A");
  BOOST_CHECK_EQUAL(getA.first, false);
}

BOOST_AUTO_TEST_CASE(FindEffectiveStrategy)
{
  const auto strategyNameZ = Name("/strategy-choice-Z").appendVersion(0); // unregistered strategyName

  BOOST_CHECK(sc.insert("/", strategyNameP));
  // { '/'=>P }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameP);

  BOOST_CHECK(sc.insert("/A/B", strategyNameP));
  // { '/'=>P, '/A/B'=>P }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameP);
  // same entry, same instance
  BOOST_CHECK_EQUAL(&sc.findEffectiveStrategy("/"), &sc.findEffectiveStrategy("/A"));
  // different entries, distinct instances
  BOOST_CHECK_NE(&sc.findEffectiveStrategy("/"), &sc.findEffectiveStrategy("/A/B"));

  sc.erase("/A"); // no effect
  // { '/'=>P, '/A/B'=>P }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameP);

  BOOST_CHECK(sc.insert("/A", strategyNameQ));
  // { '/'=>P, '/A/B'=>P, '/A'=>Q }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameQ);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameP);

  sc.erase("/A/B");
  // { '/'=>P, '/A'=>Q }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameQ);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameQ);

  BOOST_CHECK(!sc.insert("/", strategyNameZ)); // non existent strategy

  BOOST_CHECK(sc.insert("/", strategyNameQ));
  BOOST_CHECK(sc.insert("/A", strategyNameP));
  // { '/'=>Q, '/A'=>P }

  BOOST_CHECK_EQUAL(this->findInstanceName("/"), strategyNameQ);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/A/B"), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName("/D"), strategyNameQ);
}

BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithPitEntry)
{
  shared_ptr<Data> dataABC = makeData("/A/B/C");
  Name fullName = dataABC->getFullName();

  BOOST_CHECK(sc.insert("/A", strategyNameP));
  BOOST_CHECK(sc.insert(fullName, strategyNameQ));

  Pit& pit = forwarder.getPit();
  shared_ptr<Interest> interestAB = makeInterest("/A/B");
  shared_ptr<pit::Entry> pitAB = pit.insert(*interestAB).first;
  shared_ptr<Interest> interestFull = makeInterest(fullName);
  shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;

  BOOST_CHECK_EQUAL(this->findInstanceName(*pitAB), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName(*pitFull), strategyNameQ);
}

BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithMeasurementsEntry)
{
  BOOST_CHECK(sc.insert("/A", strategyNameP));
  BOOST_CHECK(sc.insert("/A/B/C", strategyNameQ));

  Measurements& measurements = forwarder.getMeasurements();
  measurements::Entry& mAB = measurements.get("/A/B");
  measurements::Entry& mABCD = measurements.get("/A/B/C/D");

  BOOST_CHECK_EQUAL(this->findInstanceName(mAB), strategyNameP);
  BOOST_CHECK_EQUAL(this->findInstanceName(mABCD), strategyNameQ);
}

BOOST_AUTO_TEST_CASE(Erase)
{
  NameTree& nameTree = forwarder.getNameTree();

  sc.insert("/", strategyNameP);

  size_t nNameTreeEntriesBefore = nameTree.size();

  sc.insert("/A/B", strategyNameQ);
  sc.erase("/A/B");
  BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
}

BOOST_AUTO_TEST_CASE(Enumerate)
{
  sc.insert("/",      strategyNameP);
  sc.insert("/A/B",   strategyNameQ);
  sc.insert("/A/B/C", strategyNameP);
  sc.insert("/D",     strategyNameP);
  sc.insert("/E",     strategyNameQ);

  BOOST_CHECK_EQUAL(sc.size(), 5);

  std::map<Name, Name> map; // namespace=>strategyName
  for (StrategyChoice::const_iterator it = sc.begin(); it != sc.end(); ++it) {
    map[it->getPrefix()] = it->getStrategyInstanceName();
  }

  BOOST_CHECK_EQUAL(map.at("/"),      strategyNameP);
  BOOST_CHECK_EQUAL(map.at("/A/B"),   strategyNameQ);
  BOOST_CHECK_EQUAL(map.at("/A/B/C"), strategyNameP);
  BOOST_CHECK_EQUAL(map.at("/D"),     strategyNameP);
  BOOST_CHECK_EQUAL(map.at("/E"),     strategyNameQ);
  BOOST_CHECK_EQUAL(map.size(), 5);
}

class PStrategyInfo : public fw::StrategyInfo
{
public:
  static constexpr int
  getTypeId()
  {
    return 10;
  }
};

BOOST_AUTO_TEST_CASE(ClearStrategyInfo)
{
  Measurements& measurements = forwarder.getMeasurements();

  BOOST_CHECK(sc.insert("/", strategyNameP));
  // { '/'=>P }
  measurements.get("/").insertStrategyInfo<PStrategyInfo>();
  measurements.get("/A").insertStrategyInfo<PStrategyInfo>();
  measurements.get("/A/B").insertStrategyInfo<PStrategyInfo>();
  measurements.get("/A/C").insertStrategyInfo<PStrategyInfo>();

  BOOST_CHECK(sc.insert("/A/B", strategyNameP));
  // { '/'=>P, '/A/B'=>P }
  BOOST_CHECK(measurements.get("/").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A/C").getStrategyInfo<PStrategyInfo>() != nullptr);

  BOOST_CHECK(sc.insert("/A", strategyNameQ));
  // { '/'=>P, '/A/B'=>P, '/A'=>Q }
  BOOST_CHECK(measurements.get("/").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A").getStrategyInfo<PStrategyInfo>() == nullptr);
  BOOST_CHECK(measurements.get("/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A/C").getStrategyInfo<PStrategyInfo>() == nullptr);

  sc.erase("/A/B");
  // { '/'=>P, '/A'=>Q }
  BOOST_CHECK(measurements.get("/").getStrategyInfo<PStrategyInfo>() != nullptr);
  BOOST_CHECK(measurements.get("/A").getStrategyInfo<PStrategyInfo>() == nullptr);
  BOOST_CHECK(measurements.get("/A/B").getStrategyInfo<PStrategyInfo>() == nullptr);
  BOOST_CHECK(measurements.get("/A/C").getStrategyInfo<PStrategyInfo>() == nullptr);
}

BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoice
BOOST_AUTO_TEST_SUITE_END() // Table

} // namespace nfd::tests
