/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2021 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "ndn-cxx/mgmt/nfd/status-dataset.hpp"
#include "ndn-cxx/mgmt/nfd/controller.hpp"

#include "tests/test-common.hpp"
#include "tests/unit/mgmt/nfd/controller-fixture.hpp"

namespace ndn {
namespace nfd {
namespace tests {

using namespace ndn::tests;

BOOST_AUTO_TEST_SUITE(Mgmt)
BOOST_AUTO_TEST_SUITE(Nfd)

class ControllerStatusDatasetFixture : public ControllerFixture
{
protected:
  /** \brief send one WireEncodable as Data reply
   *  \param prefix dataset prefix without version and segment
   *  \param payload payload block
   *  \note payload must fit in one Data
   */
  template<typename T>
  void
  sendDataset(const Name& prefix, const T& payload)
  {
    BOOST_CONCEPT_ASSERT((WireEncodable<T>));

    auto data = this->prepareDatasetReply(prefix);
    data->setContent(payload.wireEncode());
    face.receive(*signData(data));
  }

  /** \brief send two WireEncodables as Data reply
   *  \param prefix dataset prefix without version and segment
   *  \param payload1 first vector item
   *  \param payload2 second vector item
   *  \note all payloads must fit in one Data
   */
  template<typename T1, typename T2>
  void
  sendDataset(const Name& prefix, const T1& payload1, const T2& payload2)
  {
    // The test suite allows up to two items, and put them in the same Data packet,
    // because this test suite focuses on Controller::fetch<StatusDataset>,
    // and is not intended to cover SegmentFetcher behavior.

    BOOST_CONCEPT_ASSERT((WireEncodable<T1>));
    BOOST_CONCEPT_ASSERT((WireEncodable<T2>));

    ndn::encoding::EncodingBuffer buffer;
    payload2.wireEncode(buffer);
    payload1.wireEncode(buffer);

    auto data = this->prepareDatasetReply(prefix);
    data->setContent(buffer.buf(), buffer.size());
    face.receive(*signData(data));
  }

private:
  shared_ptr<Data>
  prepareDatasetReply(const Name& prefix)
  {
    Name name = prefix;
    name.appendVersion().appendSegment(0);

    // These warnings assist in debugging a `hasResult` check failure.
    // They usually indicate a misspelled prefix or incorrect timing in the test case.
    if (face.sentInterests.size() < 1) {
      BOOST_WARN_MESSAGE(false, "no Interest expressed");
    }
    else {
      BOOST_WARN_MESSAGE(face.sentInterests.back().getName().isPrefixOf(name),
                         "last Interest " << face.sentInterests.back().getName() <<
                         " cannot be satisfied by this Data " << name);
    }

    auto data = make_shared<Data>(name);
    data->setFreshnessPeriod(1_s);
    data->setFinalBlock(name[-1]);
    return data;
  }
};

BOOST_FIXTURE_TEST_SUITE(TestStatusDataset, ControllerStatusDatasetFixture)

BOOST_AUTO_TEST_SUITE(Failures)

BOOST_AUTO_TEST_CASE(Timeout)
{
  CommandOptions options;
  options.setTimeout(3000_ms);
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback,
    options);
  this->advanceClocks(500_ms);
  BOOST_CHECK_EQUAL(controller.m_fetchers.size(), 1);

  this->advanceClocks(500_ms, 6);
  BOOST_CHECK_EQUAL(controller.m_fetchers.size(), 0);
  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
}

BOOST_AUTO_TEST_CASE(DataHasNoSegment)
{
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  auto data = makeData("/localhost/nfd/faces/list/%FD%00");
  data->setFreshnessPeriod(1_s);
  face.receive(*data);
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
}

BOOST_AUTO_TEST_CASE(ValidationFailure)
{
  this->setValidationResult(false);

  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  FaceStatus payload;
  payload.setFaceId(5744);
  this->sendDataset("/localhost/nfd/faces/list", payload);
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_VALIDATION);
}

BOOST_AUTO_TEST_CASE(Nack)
{
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
  face.receive(lp::Nack(face.sentInterests.back()));
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_NACK);
}

BOOST_AUTO_TEST_CASE(ParseError1)
{
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  Name payload; // Name is not valid FaceStatus
  this->sendDataset("/localhost/nfd/faces/list", payload);
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
}

BOOST_AUTO_TEST_CASE(ParseError2)
{
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  FaceStatus payload1;
  payload1.setFaceId(10930);
  Name payload2; // Name is not valid FaceStatus
  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
  BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_SERVER);
}

BOOST_AUTO_TEST_SUITE_END() // Failures

BOOST_AUTO_TEST_SUITE(NoCallback)

BOOST_AUTO_TEST_CASE(Success)
{
  controller.fetch<FaceDataset>(
    nullptr,
    datasetFailCallback);
  this->advanceClocks(500_ms);
  BOOST_CHECK_EQUAL(controller.m_fetchers.size(), 1);

  FaceStatus payload;
  payload.setFaceId(2577);
  this->sendDataset("/localhost/nfd/faces/list", payload);
  BOOST_CHECK_NO_THROW(this->advanceClocks(500_ms));

  BOOST_CHECK_EQUAL(failCodes.size(), 0);
  BOOST_CHECK_EQUAL(controller.m_fetchers.size(), 0);
}

BOOST_AUTO_TEST_CASE(Failure)
{
  CommandOptions options;
  options.setTimeout(3000_ms);
  controller.fetch<FaceDataset>(
    [] (auto&&) { BOOST_FAIL("fetchDataset should not succeed"); },
    nullptr,
    options);
  BOOST_CHECK_NO_THROW(this->advanceClocks(500_ms, 7));
}

BOOST_AUTO_TEST_SUITE_END() // NoCallback

BOOST_AUTO_TEST_SUITE(Datasets)

BOOST_AUTO_TEST_CASE(StatusGeneral)
{
  bool hasResult = false;
  controller.fetch<ForwarderGeneralStatusDataset>(
    [&hasResult] (const ForwarderStatus& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.getNfdVersion(), "0.4.2");
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  ForwarderStatus payload;
  payload.setNfdVersion("0.4.2");
  this->sendDataset("/localhost/nfd/status/general", payload);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(FaceList)
{
  bool hasResult = false;
  controller.fetch<FaceDataset>(
    [&hasResult] (const std::vector<FaceStatus>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 2);
      BOOST_CHECK_EQUAL(result.front().getFaceId(), 24485);
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  FaceStatus payload1;
  payload1.setFaceId(24485);
  FaceStatus payload2;
  payload2.setFaceId(12987);
  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(FaceQuery)
{
  FaceQueryFilter filter;
  filter.setUriScheme("udp4");
  bool hasResult = false;
  controller.fetch<FaceQueryDataset>(
    filter,
    [&hasResult] (const std::vector<FaceStatus>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 1);
      BOOST_CHECK_EQUAL(result.front().getFaceId(), 8795);
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  Name prefix("/localhost/nfd/faces/query");
  prefix.append(filter.wireEncode().begin(), filter.wireEncode().end());
  FaceStatus payload;
  payload.setFaceId(8795);
  this->sendDataset(prefix, payload);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(FaceQueryWithOptions)
{
  FaceQueryFilter filter;
  filter.setUriScheme("udp4");
  CommandOptions options;
  options.setTimeout(3000_ms);
  bool hasResult = false;
  controller.fetch<FaceQueryDataset>(
    filter,
    [&hasResult] (const std::vector<FaceStatus>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 1);
      BOOST_CHECK_EQUAL(result.front().getFaceId(), 14022);
    },
    datasetFailCallback,
    options);
  this->advanceClocks(500_ms);

  Name prefix("/localhost/nfd/faces/query");
  prefix.append(filter.wireEncode().begin(), filter.wireEncode().end());
  FaceStatus payload;
  payload.setFaceId(14022);
  this->sendDataset(prefix, payload);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(FaceChannels)
{
  bool hasResult = false;
  controller.fetch<ChannelDataset>(
    [&hasResult] (const std::vector<ChannelStatus>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 2);
      BOOST_CHECK_EQUAL(result.front().getLocalUri(), "tcp4://192.0.2.1:6363");
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  ChannelStatus payload1;
  payload1.setLocalUri("tcp4://192.0.2.1:6363");
  ChannelStatus payload2;
  payload2.setLocalUri("udp4://192.0.2.1:6363");
  this->sendDataset("/localhost/nfd/faces/channels", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(FibList)
{
  bool hasResult = false;
  controller.fetch<FibDataset>(
    [&hasResult] (const std::vector<FibEntry>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 2);
      BOOST_CHECK_EQUAL(result.front().getPrefix(), "/wYs7fzYcfG");
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  FibEntry payload1;
  payload1.setPrefix("/wYs7fzYcfG");
  FibEntry payload2;
  payload2.setPrefix("/LKvmnzY5S");
  this->sendDataset("/localhost/nfd/fib/list", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(CsInfo)
{
  using ndn::nfd::CsInfo;

  bool hasResult = false;
  controller.fetch<CsInfoDataset>(
    [&hasResult] (const CsInfo& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.getNHits(), 4539);
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  CsInfo payload;
  payload.setNHits(4539);
  this->sendDataset("/localhost/nfd/cs/info", payload);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(StrategyChoiceList)
{
  bool hasResult = false;
  controller.fetch<StrategyChoiceDataset>(
    [&hasResult] (const std::vector<StrategyChoice>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 2);
      BOOST_CHECK_EQUAL(result.front().getName(), "/8MLz6N3B");
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  StrategyChoice payload1;
  payload1.setName("/8MLz6N3B");
  StrategyChoice payload2;
  payload2.setName("/svqcBu0YwU");
  this->sendDataset("/localhost/nfd/strategy-choice/list", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(RibList)
{
  bool hasResult = false;
  controller.fetch<RibDataset>(
    [&hasResult] (const std::vector<RibEntry>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 2);
      BOOST_CHECK_EQUAL(result.front().getName(), "/zXxBth97ee");
    },
    datasetFailCallback);
  this->advanceClocks(500_ms);

  RibEntry payload1;
  payload1.setName("/zXxBth97ee");
  RibEntry payload2;
  payload2.setName("/rJ8CvUpr4G");
  this->sendDataset("/localhost/nfd/rib/list", payload1, payload2);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_CASE(RibListWithOptions)
{
  CommandOptions options;
  options.setPrefix("/localhop/nfd");
  bool hasResult = false;
  controller.fetch<RibDataset>(
    [&hasResult] (const std::vector<RibEntry>& result) {
      hasResult = true;
      BOOST_CHECK_EQUAL(result.size(), 1);
      BOOST_CHECK_EQUAL(result.front().getName(), "/e6L5K4ascd");
    },
    datasetFailCallback,
    options);
  this->advanceClocks(500_ms);

  RibEntry payload;
  payload.setName("/e6L5K4ascd");
  this->sendDataset("/localhop/nfd/rib/list", payload);
  this->advanceClocks(500_ms);

  BOOST_CHECK(hasResult);
  BOOST_CHECK_EQUAL(failCodes.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // Datasets

BOOST_AUTO_TEST_SUITE_END() // TestStatusDataset
BOOST_AUTO_TEST_SUITE_END() // Nfd
BOOST_AUTO_TEST_SUITE_END() // Mgmt

} // namespace tests
} // namespace nfd
} // namespace ndn
