/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2021 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 ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, 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.
 */

#include "ndn-cxx/util/notification-subscriber.hpp"
#include "ndn-cxx/util/dummy-client-face.hpp"

#include "tests/test-common.hpp"
#include "tests/unit/io-key-chain-fixture.hpp"
#include "tests/unit/util/simple-notification.hpp"

namespace ndn {
namespace util {
namespace tests {

using namespace ndn::tests;

class NotificationSubscriberFixture : public IoKeyChainFixture
{
public:
  NotificationSubscriberFixture()
    : streamPrefix("/NotificationSubscriberTest")
    , subscriberFace(m_io, m_keyChain)
    , subscriber(subscriberFace, streamPrefix, 1_s)
    , nextSendNotificationNo(0)
  {
  }

  /** \brief deliver one notification to subscriber
   */
  void
  deliverNotification(const std::string& msg)
  {
    SimpleNotification notification(msg);

    Name dataName = streamPrefix;
    dataName.appendSequenceNumber(nextSendNotificationNo);
    Data data(dataName);
    data.setContent(notification.wireEncode());
    data.setFreshnessPeriod(1_s);
    m_keyChain.sign(data);

    lastDeliveredSeqNum = nextSendNotificationNo;
    lastNotification.setMessage("");
    ++nextSendNotificationNo;
    subscriberFace.receive(data);
  }

  /** \brief deliver a Nack to subscriber
   */
  void
  deliverNack(const Interest& interest, const lp::NackReason& reason)
  {
    subscriberFace.receive(makeNack(interest, reason));
  }

  void
  connectHandlers()
  {
    notificationConn = subscriber.onNotification.connect([this] (const auto& n) { lastNotification = n; });
    nackConn = subscriber.onNack.connect([this] (const auto& nack) { lastNack = nack; });
    subscriber.onTimeout.connect([this] { hasTimeout = true; });
    subscriber.onDecodeError.connect([this] (const auto& data) { lastDecodeErrorData = data; });
  }

  void
  disconnectHandlers()
  {
    notificationConn.disconnect();
    nackConn.disconnect();
  }

  /** \return true if subscriberFace has an initial request (first sent Interest)
   */
  bool
  hasInitialRequest() const
  {
    if (subscriberFace.sentInterests.empty())
      return false;

    const Interest& interest = subscriberFace.sentInterests[0];
    return interest.getName() == streamPrefix &&
           interest.getCanBePrefix() &&
           interest.getMustBeFresh() &&
           interest.getInterestLifetime() == subscriber.getInterestLifetime();
  }

  /** \return sequence number of the continuation request sent from subscriberFace
   *          or 0 if there's no such request as sole sent Interest
   */
  uint64_t
  getRequestSeqNum() const
  {
    if (subscriberFace.sentInterests.size() != 1)
      return 0;

    const Interest& interest = subscriberFace.sentInterests[0];
    const Name& name = interest.getName();
    if (streamPrefix.isPrefixOf(name) &&
        name.size() == streamPrefix.size() + 1 &&
        interest.getInterestLifetime() == subscriber.getInterestLifetime())
      return name[-1].toSequenceNumber();
    else
      return 0;
  }

protected:
  Name streamPrefix;
  DummyClientFace subscriberFace;
  util::NotificationSubscriber<SimpleNotification> subscriber;
  util::signal::Connection notificationConn;
  util::signal::Connection nackConn;
  uint64_t nextSendNotificationNo;
  uint64_t lastDeliveredSeqNum;
  SimpleNotification lastNotification;
  lp::Nack lastNack;
  bool hasTimeout;
  Data lastDecodeErrorData;
};

BOOST_AUTO_TEST_SUITE(Util)
BOOST_FIXTURE_TEST_SUITE(TestNotificationSubscriber, NotificationSubscriberFixture)

BOOST_AUTO_TEST_CASE(StartStop)
{
  BOOST_REQUIRE_EQUAL(subscriber.isRunning(), false);

  // has no effect because onNotification has no handler
  subscriber.start();
  BOOST_REQUIRE_EQUAL(subscriber.isRunning(), false);

  this->connectHandlers();
  subscriber.start();
  BOOST_REQUIRE_EQUAL(subscriber.isRunning(), true);
  advanceClocks(1_ms);
  BOOST_CHECK(this->hasInitialRequest());

  subscriberFace.sentInterests.clear();
  this->disconnectHandlers();
  this->deliverNotification("n1");
  BOOST_REQUIRE_EQUAL(subscriberFace.sentInterests.size(), 0);
}

BOOST_AUTO_TEST_CASE(Notifications)
{
  this->connectHandlers();
  subscriber.start();
  advanceClocks(1_ms);

  // respond to initial request
  subscriberFace.sentInterests.clear();
  this->deliverNotification("n1");
  advanceClocks(1_ms);
  BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n1");
  BOOST_CHECK_EQUAL(this->getRequestSeqNum(), lastDeliveredSeqNum + 1);

  // respond to continuation request
  subscriberFace.sentInterests.clear();
  this->deliverNotification("n2");
  advanceClocks(1_ms);
  BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n2");
  BOOST_CHECK_EQUAL(this->getRequestSeqNum(), lastDeliveredSeqNum + 1);
}

BOOST_AUTO_TEST_CASE(Nack)
{
  this->connectHandlers();
  subscriber.start();
  advanceClocks(1_ms);

  // send the first Nack to initial request
  BOOST_REQUIRE_EQUAL(subscriberFace.sentInterests.size(), 1);
  Interest interest = subscriberFace.sentInterests[0];
  subscriberFace.sentInterests.clear();
  this->deliverNack(interest, lp::NackReason::CONGESTION);
  advanceClocks(1_ms);
  BOOST_CHECK_EQUAL(lastNack.getReason(), lp::NackReason::CONGESTION);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), false);
  advanceClocks(300_ms);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), true);

  // send the second Nack to initial request
  BOOST_REQUIRE_EQUAL(subscriberFace.sentInterests.size(), 1);
  interest = subscriberFace.sentInterests[0];
  subscriberFace.sentInterests.clear();
  this->deliverNack(interest, lp::NackReason::CONGESTION);
  advanceClocks(301_ms);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), false);
  advanceClocks(200_ms);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), true);

  // send a notification to initial request
  subscriberFace.sentInterests.clear();
  this->deliverNotification("n1");
  advanceClocks(1_ms);

  // send a Nack to subsequent request
  BOOST_REQUIRE_EQUAL(subscriberFace.sentInterests.size(), 1);
  interest = subscriberFace.sentInterests[0];
  subscriberFace.sentInterests.clear();
  this->deliverNack(interest, lp::NackReason::CONGESTION);
  advanceClocks(1_ms);
  BOOST_CHECK_EQUAL(lastNack.getReason(), lp::NackReason::CONGESTION);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), false);
  advanceClocks(300_ms);
  BOOST_REQUIRE_EQUAL(this->hasInitialRequest(), true);
}

BOOST_AUTO_TEST_CASE(Timeout)
{
  this->connectHandlers();
  subscriber.start();
  advanceClocks(1_ms);

  subscriberFace.sentInterests.clear();
  lastNotification.setMessage("");
  advanceClocks(subscriber.getInterestLifetime(), 2);
  BOOST_CHECK(lastNotification.getMessage().empty());
  BOOST_CHECK_EQUAL(hasTimeout, true);
  BOOST_CHECK(this->hasInitialRequest());

  subscriberFace.sentInterests.clear();
  this->deliverNotification("n1");
  advanceClocks(1_ms);
  BOOST_CHECK_EQUAL(lastNotification.getMessage(), "n1");
}

BOOST_AUTO_TEST_CASE(SequenceError)
{
  this->connectHandlers();
  subscriber.start();
  advanceClocks(1_ms);

  Name wrongName = streamPrefix;
  wrongName.append("%07%07");
  Data wrongData(wrongName);
  wrongData.setFreshnessPeriod(1_s);
  m_keyChain.sign(wrongData);
  subscriberFace.receive(wrongData);
  subscriberFace.sentInterests.clear();
  lastNotification.setMessage("");
  advanceClocks(1_ms);
  BOOST_CHECK(lastNotification.getMessage().empty());
  BOOST_CHECK_EQUAL(lastDecodeErrorData.getName(), wrongName);
  BOOST_CHECK(this->hasInitialRequest());
}

BOOST_AUTO_TEST_CASE(PayloadError)
{
  this->connectHandlers();
  subscriber.start();
  advanceClocks(1_ms);

  subscriberFace.sentInterests.clear();
  lastNotification.setMessage("");
  this->deliverNotification("\x07n4");
  advanceClocks(1_ms);
  BOOST_CHECK(lastNotification.getMessage().empty());
  BOOST_CHECK(this->hasInitialRequest());
}

BOOST_AUTO_TEST_SUITE_END() // TestNotificationSubscriber
BOOST_AUTO_TEST_SUITE_END() // Util

} // namespace tests
} // namespace util
} // namespace ndn
