/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2016 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 "management/nfd-status-dataset.hpp"
#include "management/nfd-controller.hpp"

#include "nfd-controller-fixture.hpp"
#include "../make-interest-data.hpp"

namespace ndn {
namespace nfd {
namespace tests {

using ndn::util::makeData;
using ndn::util::signData;

BOOST_AUTO_TEST_SUITE(Management)

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->setFinalBlockId(data->getName()[-1]);
    return data;
  }
};

BOOST_FIXTURE_TEST_SUITE(TestNfdStatusDataset, ControllerStatusDatasetFixture)

BOOST_AUTO_TEST_SUITE(Failures)

BOOST_AUTO_TEST_CASE(Timeout)
{
  CommandOptions options;
  options.setTimeout(time::milliseconds(3000));
  controller.fetch<FaceDataset>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback,
    options);
  this->advanceClocks(time::milliseconds(500), 7);

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

BOOST_AUTO_TEST_CASE(DataHasNoSegment)
{
  controller.fetch<FaceDataset>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

  face.receive(*makeData("/localhost/nfd/faces/list/%FD%00"));
  this->advanceClocks(time::milliseconds(500));

  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>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_CASE(Nack)
{
  controller.fetch<FaceDataset>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_CASE(ParseError1)
{
  controller.fetch<FaceDataset>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_CASE(ParseError2)
{
  controller.fetch<FaceDataset>(
    [] (const std::vector<FaceStatus>& result) { BOOST_FAIL("fetchDataset should not succeed"); },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_SUITE_END() // Failures

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");
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

  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);
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

  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);
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_CASE(FaceQueryWithOptions)
{
  FaceQueryFilter filter;
  filter.setUriScheme("udp4");
  CommandOptions options;
  options.setTimeout(time::milliseconds(3000));
  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);
    },
    failCallback,
    options);
  this->advanceClocks(time::milliseconds(500));

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

  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");
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

  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(time::milliseconds(500));

  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");
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

  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");
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

  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");
    },
    failCallback);
  this->advanceClocks(time::milliseconds(500));

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

  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");
    },
    failCallback,
    options);
  this->advanceClocks(time::milliseconds(500));

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

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

BOOST_AUTO_TEST_SUITE_END() // Datasets

BOOST_AUTO_TEST_SUITE_END() // TestNfdStatusDataset
BOOST_AUTO_TEST_SUITE_END() // Management

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