/* -*- 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/security/validator-null.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/segment-fetcher.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");
  interest.setCanBePrefix(true);
  interest.setMustBeFresh(true);
  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));
  interest2.setCanBePrefix(false);
  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);

  util::DummyClientFace clientFace(face.getIoService());
  clientFace.linkTo(face);

  Name baseName("/localhop/nfd/rib/routable-prefixes");
  auto fetcher = util::SegmentFetcher::start(clientFace, Interest(baseName),
                                             security::v2::getAcceptAllValidator());
  fetcher->afterSegmentReceived.connect([baseName] (const Data& data) {
    const Name& dataName = data.getName();
    BOOST_CHECK_EQUAL(dataName.size(), baseName.size() + 2);
    BOOST_CHECK(dataName.at(-2).isVersion());
    BOOST_CHECK(dataName.at(-1).isSegment());
  });
  fetcher->onError.connect([] (uint32_t code, const std::string& msg) {
    BOOST_FAIL(msg);
  });
  bool isComplete = false;
  fetcher->onComplete.connect([&isComplete, nRoutablePrefixes, options] (ConstBufferPtr 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]);
    }
    isComplete = true;
  });

  face.processEvents(100_ms, 2000);
  BOOST_CHECK(isComplete);
}

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");
  interest.setCanBePrefix(true);
  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
