/* -*- 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/measurements-accessor.hpp"
#include "fw/strategy.hpp"

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

namespace nfd::tests {

class MeasurementsAccessorTestStrategy : public DummyStrategy
{
public:
  static void
  registerAs(const Name& strategyName)
  {
    registerAsImpl<MeasurementsAccessorTestStrategy>(strategyName);
  }

  MeasurementsAccessorTestStrategy(Forwarder& forwarder, const Name& name)
    : DummyStrategy(forwarder, name)
  {
  }

  MeasurementsAccessor&
  getMeasurementsAccessor()
  {
    return this->getMeasurements();
  }
};

class MeasurementsAccessorFixture : public GlobalIoFixture
{
protected:
  MeasurementsAccessorFixture()
  {
    const auto strategyP = Name("/measurements-accessor-test-strategy-P").appendVersion(1);
    const auto strategyQ = Name("/measurements-accessor-test-strategy-Q").appendVersion(1);
    MeasurementsAccessorTestStrategy::registerAs(strategyP);
    MeasurementsAccessorTestStrategy::registerAs(strategyQ);

    accessor1 = &choose<MeasurementsAccessorTestStrategy>(forwarder, "/", strategyP)
                  .getMeasurementsAccessor();
    accessor2 = &choose<MeasurementsAccessorTestStrategy>(forwarder, "/A", strategyQ)
                  .getMeasurementsAccessor();
    accessor3 = &choose<MeasurementsAccessorTestStrategy>(forwarder, "/A/B", strategyP)
                  .getMeasurementsAccessor();

    // Despite accessor1 and accessor3 are associated with the same strategy name,
    // they are different strategy instances and thus cannot access each other's measurements.
  }

protected:
  FaceTable faceTable;
  Forwarder forwarder{faceTable};
  Measurements& measurements{forwarder.getMeasurements()};
  MeasurementsAccessor* accessor1;
  MeasurementsAccessor* accessor2;
  MeasurementsAccessor* accessor3;
};

BOOST_AUTO_TEST_SUITE(Table)
BOOST_FIXTURE_TEST_SUITE(TestMeasurementsAccessor, MeasurementsAccessorFixture)

BOOST_AUTO_TEST_CASE(Get)
{
  BOOST_CHECK(accessor1->get("/"     ) != nullptr);
  BOOST_CHECK(accessor1->get("/A"    ) == nullptr);
  BOOST_CHECK(accessor1->get("/A/B"  ) == nullptr);
  BOOST_CHECK(accessor1->get("/A/B/C") == nullptr);
  BOOST_CHECK(accessor1->get("/A/D"  ) == nullptr);

  BOOST_CHECK(accessor2->get("/"     ) == nullptr);
  BOOST_CHECK(accessor2->get("/A"    ) != nullptr);
  BOOST_CHECK(accessor2->get("/A/B"  ) == nullptr);
  BOOST_CHECK(accessor2->get("/A/B/C") == nullptr);
  BOOST_CHECK(accessor2->get("/A/D"  ) != nullptr);

  BOOST_CHECK(accessor3->get("/"     ) == nullptr);
  BOOST_CHECK(accessor3->get("/A"    ) == nullptr);
  BOOST_CHECK(accessor3->get("/A/B"  ) != nullptr);
  BOOST_CHECK(accessor3->get("/A/B/C") != nullptr);
  BOOST_CHECK(accessor3->get("/A/D"  ) == nullptr);
}

BOOST_AUTO_TEST_CASE(GetParent)
{
  auto& entryRoot = measurements.get("/");
  BOOST_CHECK(accessor1->getParent(entryRoot) == nullptr);
  BOOST_CHECK(accessor2->getParent(entryRoot) == nullptr);

  auto& entryA = measurements.get("/A");
  BOOST_CHECK(accessor2->getParent(entryA) == nullptr);
  auto& entryAD = measurements.get("/A/D");
  BOOST_CHECK(accessor2->getParent(entryAD) != nullptr);
  // whether accessor1 and accessor3 can getParent(entryA) and getParent(entryAD) is undefined,
  // because they shouldn't have obtained those entries in the first place
}

BOOST_AUTO_TEST_CASE(FindLongestPrefixMatch)
{
  shared_ptr<Interest> interest = makeInterest("/A/B/C");
  shared_ptr<pit::Entry> pitEntry = forwarder.getPit().insert(*interest).first;

  measurements.get("/");
  BOOST_CHECK(accessor1->findLongestPrefixMatch("/A/B") != nullptr);
  BOOST_CHECK(accessor1->findLongestPrefixMatch(*pitEntry) != nullptr);

  measurements.get("/A");
  BOOST_CHECK(accessor1->findLongestPrefixMatch("/A/B") == nullptr);
  BOOST_CHECK(accessor1->findLongestPrefixMatch(*pitEntry) == nullptr);
}

BOOST_AUTO_TEST_CASE(FindExactMatch)
{
  measurements.get("/");
  measurements.get("/A");
  measurements.get("/A/B");
  measurements.get("/A/B/C");
  measurements.get("/A/D");

  BOOST_CHECK(accessor1->findExactMatch("/"     ) != nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/A"    ) == nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/A/B"  ) == nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/A/B/C") == nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/A/D"  ) == nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/A/E"  ) == nullptr);
  BOOST_CHECK(accessor1->findExactMatch("/F"    ) == nullptr);

  BOOST_CHECK(accessor2->findExactMatch("/"     ) == nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/A"    ) != nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/A/B"  ) == nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/A/B/C") == nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/A/D"  ) != nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/A/E"  ) == nullptr);
  BOOST_CHECK(accessor2->findExactMatch("/F"    ) == nullptr);

  BOOST_CHECK(accessor3->findExactMatch("/"     ) == nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/A"    ) == nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/A/B"  ) != nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/A/B/C") != nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/A/D"  ) == nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/A/E"  ) == nullptr);
  BOOST_CHECK(accessor3->findExactMatch("/F"    ) == nullptr);
}

BOOST_AUTO_TEST_SUITE_END() // TestMeasurementsAccessor
BOOST_AUTO_TEST_SUITE_END() // Table

} // namespace nfd::tests
