/* -*- 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/strategy-choice.hpp"

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

namespace nfd::tests {

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
