/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2016-2017, Regents of the University of California,
 *                          Colorado State University,
 *                          University Pierre & Marie Curie, Sorbonne University.
 *
 * This file is part of ndn-tools (Named Data Networking Essential Tools).
 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
 *
 * ndn-tools 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.
 *
 * ndn-tools 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
 * ndn-tools, 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.
 *
 * @author Andrea Tosatto
 */

#include "tools/chunks/catchunks/consumer.hpp"
#include "tools/chunks/catchunks/discover-version.hpp"
#include "tools/chunks/catchunks/pipeline-interests.hpp"

#include "tests/test-common.hpp"

#include <boost/test/output_test_stream.hpp>
#include <ndn-cxx/security/validator-null.hpp>
#include <ndn-cxx/util/dummy-client-face.hpp>

namespace ndn {
namespace chunks {
namespace tests {

using namespace ndn::tests;
using boost::test_tools::output_test_stream;

BOOST_AUTO_TEST_SUITE(Chunks)
BOOST_AUTO_TEST_SUITE(TestConsumer)

BOOST_AUTO_TEST_CASE(OutputDataSequential)
{
  // Test sequential segments in the right order
  // Segment order: 0 1 2

  std::string name("/ndn/chunks/test");

  std::vector<std::string> testStrings {
      "",

      "a1b2c3%^&(#$&%^$$/><",

      "123456789123456789123456789123456789123456789123456789123456789"
      "123456789123456789123456789123456789123456789123456789123456789",

      "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "
      "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur "
      "ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla "
      "consequat massa Donec pede justo,"
  };

  util::DummyClientFace face;
  output_test_stream output("");
  Consumer cons(security::v2::getAcceptAllValidator(), false, output);

  auto interest = makeInterest(name);

  for (size_t i = 0; i < testStrings.size(); ++i) {
    output.flush();

    auto data = makeData(Name(name).appendVersion(1).appendSegment(i));
    data->setContent(reinterpret_cast<const uint8_t*>(testStrings[i].data()),
                     testStrings[i].size());

    cons.m_bufferedData[i] = data;
    cons.writeInOrderData();

    BOOST_CHECK(output.is_equal(testStrings[i]));
  }
}

BOOST_AUTO_TEST_CASE(OutputDataUnordered)
{
  // Test unordered segments
  // Segment order: 1 0 2

  std::string name("/ndn/chunks/test");

  std::vector<std::string> testStrings {
      "a1b2c3%^&(#$&%^$$/><",

      "123456789123456789123456789123456789123456789123456789123456789"
      "123456789123456789123456789123456789123456789123456789123456789",

      "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. "
      "Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur "
      "ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla "
      "consequat massa Donec pede justo,"
  };;

  util::DummyClientFace face;
  output_test_stream output("");
  Consumer cons(security::v2::getAcceptAllValidator(), false, output);

  auto interest = makeInterest(name);
  std::vector<shared_ptr<Data>> dataStore;

  for (size_t i = 0; i < testStrings.size(); ++i) {
    auto data = makeData(Name(name).appendVersion(1).appendSegment(i));
    data->setContent(reinterpret_cast<const uint8_t*>(testStrings[i].data()),
                     testStrings[i].size());

    dataStore.push_back(data);
  }

  output.flush();
  cons.m_bufferedData[1] = dataStore[1];
  cons.writeInOrderData();
  BOOST_CHECK(output.is_equal(""));

  output.flush();
  cons.m_bufferedData[0] = dataStore[0];
  cons.writeInOrderData();
  BOOST_CHECK(output.is_equal(testStrings[0] + testStrings[1]));

  output.flush();
  cons.m_bufferedData[2] = dataStore[2];
  cons.writeInOrderData();
  BOOST_CHECK(output.is_equal(testStrings[2]));
}

class DiscoverVersionDummy : public DiscoverVersion
{
public:
  DiscoverVersionDummy(const Name& prefix, Face& face, const Options& options)
    : Options(options)
    , DiscoverVersion(prefix, face)
    , isDiscoverRunning(false)
    , m_prefix(prefix)
  {
  }

  void
  run() final
  {
    isDiscoverRunning = true;

    auto interest = makeInterest(m_prefix);
    expressInterest(*interest, 1, 1);
  }

private:
  void
  handleData(const Interest& interest, const Data& data) final
  {
    this->emitSignal(onDiscoverySuccess, data);
  }

public:
  bool isDiscoverRunning;

private:
  Name m_prefix;
};

class PipelineInterestsDummy : public PipelineInterests
{
public:
  PipelineInterestsDummy(Face& face)
    : PipelineInterests(face)
    , isPipelineRunning(false)
  {
  }

private:
  void
  doRun() final
  {
    isPipelineRunning = true;
  }

  void
  doCancel() final
  {
  }

public:
  bool isPipelineRunning;
};

BOOST_FIXTURE_TEST_CASE(RunBasic, UnitTestTimeFixture)
{
  boost::asio::io_service io;
  util::DummyClientFace face(io);
  Consumer consumer(security::v2::getAcceptAllValidator(), false);

  Name prefix("/ndn/chunks/test");
  auto discover = make_unique<DiscoverVersionDummy>(prefix, face, Options());
  auto pipeline = make_unique<PipelineInterestsDummy>(face);
  auto discoverPtr = discover.get();
  auto pipelinePtr = pipeline.get();

  consumer.run(std::move(discover), std::move(pipeline));
  BOOST_CHECK_EQUAL(discoverPtr->isDiscoverRunning, true);

  this->advanceClocks(io, time::nanoseconds(1));
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);

  auto data = makeData(prefix.appendSegment(0));
  face.receive(*data);

  this->advanceClocks(io, time::nanoseconds(1));
  BOOST_CHECK_EQUAL(pipelinePtr->isPipelineRunning, true);
}

BOOST_AUTO_TEST_SUITE_END() // TestConsumer
BOOST_AUTO_TEST_SUITE_END() // Chunks

} // namespace tests
} // namespace chunks
} // namespace ndn
