/* -*- 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 "fw/asf-measurements.hpp"
#include "daemon/global.hpp"

#include "tests/test-common.hpp"
#include "tests/daemon/global-io-fixture.hpp"
#include "tests/daemon/face/dummy-face.hpp"

namespace nfd {
namespace fw {
namespace asf {
namespace tests {

using namespace nfd::tests;

BOOST_AUTO_TEST_SUITE(Fw)
BOOST_AUTO_TEST_SUITE(TestAsfMeasurements)

BOOST_AUTO_TEST_SUITE(TestRttStats)

BOOST_FIXTURE_TEST_CASE(Basic, GlobalIoFixture)
{
  RttStats stats;

  BOOST_CHECK_EQUAL(stats.getRtt(), RttStats::RTT_NO_MEASUREMENT);
  BOOST_CHECK_EQUAL(stats.getSrtt(), RttStats::RTT_NO_MEASUREMENT);

  // Receive Data back in 50ms
  RttEstimator::Duration rtt(50_ms);
  stats.addRttMeasurement(rtt);

  BOOST_CHECK_EQUAL(stats.getRtt(), rtt);
  BOOST_CHECK_EQUAL(stats.getSrtt(), rtt);

  // Receive Data back in 50ms
  stats.addRttMeasurement(rtt);

  BOOST_CHECK_EQUAL(stats.getRtt(), rtt);
  BOOST_CHECK_EQUAL(stats.getSrtt(), rtt);

  // Receive Data back with a higher RTT
  RttEstimator::Duration higherRtt(100_ms);
  stats.addRttMeasurement(higherRtt);

  BOOST_CHECK_EQUAL(stats.getRtt(), higherRtt);
  BOOST_CHECK_GT(stats.getSrtt(), rtt);
  BOOST_CHECK_LT(stats.getSrtt(), higherRtt);

  // Simulate timeout
  RttStats::Rtt previousSrtt = stats.getSrtt();

  stats.recordTimeout();

  BOOST_CHECK_EQUAL(stats.getRtt(), RttStats::RTT_TIMEOUT);
  BOOST_CHECK_EQUAL(stats.getSrtt(), previousSrtt);
}

BOOST_AUTO_TEST_SUITE_END() // TestRttStats

BOOST_AUTO_TEST_SUITE(TestFaceInfo)

BOOST_FIXTURE_TEST_CASE(Basic, GlobalIoTimeFixture)
{
  FaceInfo info;

  auto id = getScheduler().schedule(1_s, []{});
  ndn::Name interestName("/ndn/interest");

  // Receive Interest and forward to next hop; should update RTO information
  info.setTimeoutEvent(id, interestName);
  BOOST_CHECK_EQUAL(info.isTimeoutScheduled(), true);

  // If the strategy tries to schedule an RTO when one is already scheduled, throw an exception
  BOOST_CHECK_THROW(info.setTimeoutEvent(id, interestName), FaceInfo::Error);

  // Receive Data
  shared_ptr<Interest> interest = makeInterest(interestName);
  shared_ptr<pit::Entry> pitEntry = make_shared<pit::Entry>(*interest);
  std::shared_ptr<DummyFace> face = make_shared<DummyFace>();

  pitEntry->insertOrUpdateOutRecord(*face, 0, *interest);

  RttEstimator::Duration rtt(50);
  this->advanceClocks(5_ms, rtt);

  info.recordRtt(pitEntry, *face);
  info.cancelTimeoutEvent(interestName);

  BOOST_CHECK_EQUAL(info.getRtt(), rtt);
  BOOST_CHECK_EQUAL(info.getSrtt(), rtt);

  // Send out another Interest which times out
  info.setTimeoutEvent(id, interestName);

  info.recordTimeout(interestName);
  BOOST_CHECK_EQUAL(info.getRtt(), RttStats::RTT_TIMEOUT);
  BOOST_CHECK_EQUAL(info.isTimeoutScheduled(), false);
}

BOOST_AUTO_TEST_SUITE_END() // TestFaceInfo

BOOST_AUTO_TEST_SUITE_END() // TestAsfStrategy
BOOST_AUTO_TEST_SUITE_END() // Fw

} // namespace tests
} // namespace asf
} // namespace fw
} // namespace nfd
