/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2016,  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/pipeline-interests.hpp"
#include "tools/chunks/catchunks/data-fetcher.hpp"

#include "tests/test-common.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>

namespace ndn {
namespace chunks {
namespace tests {

using namespace ndn::tests;

class PipelineInterestsFixture : public UnitTestTimeFixture
{
public:
  typedef PipelineInterestsOptions Options;

public:
  PipelineInterestsFixture()
    : face(io)
    , opt(makeOptions())
    , name("/ndn/chunks/test")
    , pipeline(face, opt)
    , nDataSegments(0)
    , nReceivedSegments(0)
    , hasFailed(false)
  {
  }

protected:
  shared_ptr<Data>
  makeDataWithSegment(uint64_t segmentNo, bool setFinalBlockId = true)
  {
    auto data = make_shared<Data>(Name(name).appendVersion(0).appendSegment(segmentNo));
    if (setFinalBlockId)
      data->setFinalBlockId(name::Component::fromSegment(nDataSegments - 1));
    return signData(data);
  }

  void
  runWithData(const Data& data)
  {
    pipeline.runWithExcludedSegment(data,
                                    bind(&PipelineInterestsFixture::onData, this, _1, _2),
                                    bind(&PipelineInterestsFixture::onFailure, this, _1));
  }

private:
  void
  onData(const Interest& interest, const Data& data)
  {
    nReceivedSegments++;
  }

  void
  onFailure(const std::string& reason)
  {
    hasFailed = true;
  }

  static Options
  makeOptions()
  {
    Options options;
    options.isVerbose = false;
    options.interestLifetime = time::seconds(1);
    options.maxRetriesOnTimeoutOrNack = 3;
    options.maxPipelineSize = 5;
    return options;
  }

protected:
  boost::asio::io_service io;
  util::DummyClientFace face;
  Options opt;
  Name name;
  PipelineInterests pipeline;
  uint64_t nDataSegments;
  uint64_t nReceivedSegments;
  bool hasFailed;
};

BOOST_AUTO_TEST_SUITE(Chunks)
BOOST_AUTO_TEST_SUITE(TestPipelineInterests)

BOOST_FIXTURE_TEST_CASE(FewerSegmentsThanPipelineCapacity, PipelineInterestsFixture)
{
  nDataSegments = 3;
  BOOST_ASSERT(nDataSegments <= opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(0));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), nDataSegments - 1);

  for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
    face.receive(*makeDataWithSegment(i));
    advanceClocks(io, time::nanoseconds(1), 1);

    BOOST_CHECK_EQUAL(nReceivedSegments, i);
    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), nDataSegments - 1);
    // check if the interest for the segment i+1 is well formed
    auto sentInterest = face.sentInterests[i];
    BOOST_CHECK_EQUAL(sentInterest.getExclude().size(), 0);
    BOOST_CHECK_EQUAL(sentInterest.getMaxSuffixComponents(), 1);
    BOOST_CHECK_EQUAL(sentInterest.getMustBeFresh(), opt.mustBeFresh);
    BOOST_CHECK_EQUAL(Name(name).isPrefixOf(sentInterest.getName()), true);
    BOOST_CHECK_EQUAL(sentInterest.getName()[-1].toSegment(), i + 1);
  }

  BOOST_CHECK_EQUAL(hasFailed, false);

  advanceClocks(io, ndn::DEFAULT_INTEREST_LIFETIME, opt.maxRetriesOnTimeoutOrNack + 1);
  BOOST_CHECK_EQUAL(hasFailed, true);
}

BOOST_FIXTURE_TEST_CASE(FullPipeline, PipelineInterestsFixture)
{
  nDataSegments = 13;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  for (uint64_t i = 0; i < nDataSegments - 1; ++i) {
    face.receive(*makeDataWithSegment(i));
    advanceClocks(io, time::nanoseconds(1), 1);
    BOOST_CHECK_EQUAL(nReceivedSegments, i + 1);

    if (i < nDataSegments - opt.maxPipelineSize - 1) {
      BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize + i + 1);
      // check if the interest for the segment i+1 is well formed
      auto sentInterest = face.sentInterests[i];
      BOOST_CHECK_EQUAL(sentInterest.getExclude().size(), 0);
      BOOST_CHECK_EQUAL(sentInterest.getMaxSuffixComponents(), 1);
      BOOST_CHECK_EQUAL(sentInterest.getMustBeFresh(), opt.mustBeFresh);
      BOOST_CHECK_EQUAL(Name(name).isPrefixOf(sentInterest.getName()), true);
      BOOST_CHECK_EQUAL(sentInterest.getName()[-1].toSegment(), i);
    }
    else {
      // all the interests have been sent for all the segments
      BOOST_CHECK_EQUAL(face.sentInterests.size(), nDataSegments - 1);
    }
  }

  BOOST_CHECK_EQUAL(hasFailed, false);
}

BOOST_FIXTURE_TEST_CASE(TimeoutAllSegments, PipelineInterestsFixture)
{
  nDataSegments = 13;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  for (int i = 0; i < opt.maxRetriesOnTimeoutOrNack; ++i) {
    advanceClocks(io, opt.interestLifetime, 1);
    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * (i + 2));
    BOOST_CHECK_EQUAL(nReceivedSegments, 0);

    // A single retry for every pipeline element
    for (size_t j = 0; j < opt.maxPipelineSize; ++j) {
      auto interest = face.sentInterests[(opt.maxPipelineSize * (i + 1)) + j];
      BOOST_CHECK_EQUAL(static_cast<size_t>(interest.getName()[-1].toSegment()), j);
    }
  }

  advanceClocks(io, opt.interestLifetime, 1);
  BOOST_CHECK_EQUAL(hasFailed, true);
}

BOOST_FIXTURE_TEST_CASE(TimeoutAfterFinalBlockIdReceived, PipelineInterestsFixture)
{
  // the FinalBlockId is sent with the first segment, after the first segment failure the pipeline
  // should fail

  nDataSegments = 18;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  // send a single segment for each pipeline element but not the first element
  advanceClocks(io, opt.interestLifetime, 1);
  for (uint64_t i = 1; i < opt.maxPipelineSize; ++i) {
    face.receive(*makeDataWithSegment(i));
    advanceClocks(io, time::nanoseconds(1), 1);
  }

  // send a single data packet for each pipeline element
  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack - 1);
  for (uint64_t i = 0; i < opt.maxPipelineSize - 1; ++i) {
    face.receive(*makeDataWithSegment(opt.maxPipelineSize + i));
    advanceClocks(io, time::nanoseconds(1), 1);
  }
  advanceClocks(io, opt.interestLifetime, 1);

  size_t interestAfterFailure = face.sentInterests.size();

  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
  BOOST_CHECK_EQUAL(hasFailed, true);

  // these new segments should not generate new interests
  advanceClocks(io, opt.interestLifetime, 1);
  for (uint64_t i = 0; i < opt.maxPipelineSize - 1; ++i) {
    face.receive(*makeDataWithSegment(opt.maxPipelineSize * 2 + i - 1));
    advanceClocks(io, time::nanoseconds(1), 1);
  }

  // no more interests after a failure
  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack);
  BOOST_CHECK_EQUAL(interestAfterFailure, face.sentInterests.size());
  BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
}

BOOST_FIXTURE_TEST_CASE(TimeoutBeforeFinalBlockIdReceived, PipelineInterestsFixture)
{
  // the FinalBlockId is sent only with the last segment, all segments are sent except for the
  // second one (segment #1); all segments are received correctly until the FinalBlockId is received

  nDataSegments = 22;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1, false));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  advanceClocks(io, opt.interestLifetime, 1);
  for (uint64_t i = 2; i < opt.maxPipelineSize; ++i) {
    face.receive(*makeDataWithSegment(i, false));
    advanceClocks(io, time::nanoseconds(1), 1);

    auto lastInterest = face.sentInterests.back();
    BOOST_CHECK_EQUAL(lastInterest.getName()[-1].toSegment(), opt.maxPipelineSize + i - 2);
  }
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * 3 - 2);

  // nack for the first pipeline element (segment #0)
  auto nack = make_shared<lp::Nack>(face.sentInterests[opt.maxPipelineSize]);
  nack->setReason(lp::NackReason::DUPLICATE);
  face.receive(*nack);

  // all the pipeline elements are two retries near the timeout error, but not the
  // second (segment #1) that is only one retry near the timeout
  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack - 1);
  BOOST_CHECK_EQUAL(hasFailed, false);

  // data for the first pipeline element (segment #0)
  face.receive(*makeDataWithSegment(0, false));
  BOOST_CHECK_EQUAL(hasFailed, false);

  // data for all the pipeline element, but not the second (segment #1)
  for (uint64_t i = opt.maxPipelineSize; i < nDataSegments - 1; ++i) {
    if (i == nDataSegments - 2) {
      face.receive(*makeDataWithSegment(i, true));
    }
    else {
      face.receive(*makeDataWithSegment(i, false));
    }
    advanceClocks(io, time::nanoseconds(1), 1);
  }
  // timeout for the second pipeline element (segment #1), this should trigger an error
  advanceClocks(io, opt.interestLifetime, 1);

  BOOST_CHECK_EQUAL(nReceivedSegments, nDataSegments - 2);
  BOOST_CHECK_EQUAL(hasFailed, true);
}

BOOST_FIXTURE_TEST_CASE(SegmentReceivedAfterTimeout, PipelineInterestsFixture)
{
  // the FinalBlockId is never sent, all the pipeline elements with a segment number greater than
  // segment #0 will fail, after this failure also segment #0 fail and this should trigger an error

  nDataSegments = 22;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1, false));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  advanceClocks(io, opt.interestLifetime, 1);

  // nack for the first pipeline element (segment #0)
  auto nack = make_shared<lp::Nack>(face.sentInterests[opt.maxPipelineSize]);
  nack->setReason(lp::NackReason::DUPLICATE);
  face.receive(*nack);
  BOOST_CHECK_EQUAL(hasFailed, false);

  // timeout for all the pipeline elements, but not the first (segment #0)
  advanceClocks(io, opt.interestLifetime, opt.maxRetriesOnTimeoutOrNack);
  BOOST_CHECK_EQUAL(hasFailed, false);

  // data for the first pipeline element (segment #0), this should trigger an error because the
  // others pipeline elements failed
  face.receive(*makeDataWithSegment(0, false));
  advanceClocks(io, time::nanoseconds(1), 1);

  BOOST_CHECK_EQUAL(nReceivedSegments, 1);
  BOOST_CHECK_EQUAL(hasFailed, true);
}

BOOST_FIXTURE_TEST_CASE(CongestionAllSegments, PipelineInterestsFixture)
{
  nDataSegments = 13;
  BOOST_ASSERT(nDataSegments > opt.maxPipelineSize);

  runWithData(*makeDataWithSegment(nDataSegments - 1));
  advanceClocks(io, time::nanoseconds(1), 1);
  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize);

  // send nack for all the pipeline elements first interest
  for (size_t j = 0; j < opt.maxPipelineSize; j++) {
    auto nack = make_shared<lp::Nack>(face.sentInterests[j]);
    nack->setReason(lp::NackReason::CONGESTION);
    face.receive(*nack);
    advanceClocks(io, time::nanoseconds(1), 1);
  }

  // send nack for all the pipeline elements interests after the first
  for (int i = 1; i <= opt.maxRetriesOnTimeoutOrNack; ++i) {
    time::milliseconds backoffTime(static_cast<uint64_t>(std::pow(2, i)));
    if (backoffTime > DataFetcher::MAX_CONGESTION_BACKOFF_TIME)
      backoffTime = DataFetcher::MAX_CONGESTION_BACKOFF_TIME;

    advanceClocks(io, backoffTime, 1);
    BOOST_REQUIRE_EQUAL(face.sentInterests.size(), opt.maxPipelineSize * (i +1));

    // A single retry for every pipeline element
    for (size_t j = 0; j < opt.maxPipelineSize; ++j) {
      auto interest = face.sentInterests[(opt.maxPipelineSize * i) + j];
      BOOST_CHECK_LT(static_cast<size_t>(interest.getName()[-1].toSegment()), opt.maxPipelineSize);
    }

    for (size_t j = 0; j < opt.maxPipelineSize; j++) {
      auto nack = make_shared<lp::Nack>(face.sentInterests[(opt.maxPipelineSize * i) + j]);
      nack->setReason(lp::NackReason::CONGESTION);
      face.receive(*nack);
      advanceClocks(io, time::nanoseconds(1), 1);
    }
  }

  BOOST_CHECK_EQUAL(hasFailed, true);
}

BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterests
BOOST_AUTO_TEST_SUITE_END() // Chunks

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