/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022 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
