/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2019,  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 "ndn-autoconfig-server/program.hpp"

#include "tests/test-common.hpp"
#include "tests/key-chain-fixture.hpp"

#include <ndn-cxx/encoding/buffer.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>

namespace ndn {
namespace tools {
namespace autoconfig_server {
namespace tests {

class AutoconfigServerFixture : public ::nfd::tests::KeyChainFixture
{
public:
  AutoconfigServerFixture()
    : face({true, true})
  {
  }

  void
  initialize(const Options& options)
  {
    program = make_unique<Program>(options, face, m_keyChain);
    face.processEvents(500_ms);
    face.sentInterests.clear();
  }

protected:
  util::DummyClientFace face;
  unique_ptr<Program> program;
};

BOOST_AUTO_TEST_SUITE(NdnAutoconfigServer)
BOOST_FIXTURE_TEST_SUITE(TestProgram, AutoconfigServerFixture)

BOOST_AUTO_TEST_CASE(HubData)
{
  Options options;
  options.hubFaceUri = FaceUri("udp4://192.0.2.1:6363");
  this->initialize(options);

  Interest interest("/localhop/ndn-autoconf/hub");
  face.receive(interest);
  face.processEvents(500_ms);

  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
  const Name& dataName = face.sentData[0].getName();
  BOOST_CHECK_EQUAL(dataName.size(), interest.getName().size() + 1);
  BOOST_CHECK(interest.getName().isPrefixOf(dataName));
  BOOST_CHECK(dataName.at(-1).isVersion());

  // interest2 asks for a different version, and should not be responded
  Interest interest2(Name(interest.getName()).appendVersion(dataName.at(-1).toVersion() - 1));
  face.receive(interest2);
  face.processEvents(500_ms);
  BOOST_CHECK_EQUAL(face.sentData.size(), 1);
}

BOOST_AUTO_TEST_CASE(RoutablePrefixesDataset)
{
  Options options;
  options.hubFaceUri = FaceUri("udp4://192.0.2.1:6363");
  const size_t nRoutablePrefixes = 2000;
  for (size_t i = 0; i < nRoutablePrefixes; ++i) {
    options.routablePrefixes.push_back(Name("/PREFIX").appendNumber(i));
  }
  this->initialize(options);

  Interest interest("/localhop/nfd/rib/routable-prefixes");
  face.receive(interest);
  face.processEvents(500_ms);

  BOOST_REQUIRE_EQUAL(face.sentData.size(), 1);
  const Name& dataName0 = face.sentData[0].getName();
  BOOST_CHECK_EQUAL(dataName0.size(), interest.getName().size() + 2);
  BOOST_CHECK(interest.getName().isPrefixOf(dataName0));
  BOOST_CHECK(dataName0.at(-2).isVersion());
  BOOST_CHECK(dataName0.at(-1).isSegment());

  while (face.sentData.back().getFinalBlock() != face.sentData.back().getName().at(-1)) {
    const Name& lastName = face.sentData.back().getName();
    Interest interest2(lastName.getPrefix(-1).appendSegment(lastName.at(-1).toSegment() + 1));
    face.receive(interest2);
    face.processEvents(500_ms);
  }

  auto buffer = make_shared<Buffer>();
  for (const Data& data : face.sentData) {
    const Block& content = data.getContent();
    std::copy(content.value_begin(), content.value_end(), std::back_inserter(*buffer));
  }

  Block payload(tlv::Content, buffer);
  payload.parse();
  BOOST_REQUIRE_EQUAL(payload.elements_size(), nRoutablePrefixes);
  for (size_t i = 0; i < nRoutablePrefixes; ++i) {
    BOOST_CHECK_EQUAL(Name(payload.elements()[i]), options.routablePrefixes[i]);
  }
}

BOOST_AUTO_TEST_CASE(RoutablePrefixesDisabled)
{
  Options options;
  options.hubFaceUri = FaceUri("udp4://192.0.2.1:6363");
  this->initialize(options);

  Interest interest("/localhop/nfd/rib/routable-prefixes");
  face.receive(interest);
  face.processEvents(500_ms);
  BOOST_CHECK_EQUAL(face.sentData.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // TestProgram
BOOST_AUTO_TEST_SUITE_END() // NdnAutoconfigServer

} // namespace tests
} // namespace autoconfig_server
} // namespace tools
} // namespace ndn
