/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2023 Regents of the University of California.
 *
 * 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.
 */

#define BOOST_TEST_MODULE ndn-cxx Integration (Face)
#include "tests/boost-test.hpp"

#include "ndn-cxx/face.hpp"
#include "ndn-cxx/transport/tcp-transport.hpp"
#include "ndn-cxx/transport/unix-transport.hpp"
#include "ndn-cxx/util/scheduler.hpp"

#include "tests/key-chain-fixture.hpp"
#include "tests/test-common.hpp"

#include <stdio.h>
#include <condition_variable>
#include <mutex>
#include <thread>

#include <boost/mpl/vector.hpp>

namespace ndn::tests {

static Name
makeVeryLongName(Name prefix = Name())
{
  for (size_t i = 0; i <= MAX_NDN_PACKET_SIZE / 10; i++) {
    prefix.append("0123456789");
  }
  return prefix;
}

static std::string
executeCommand(const std::string& cmd)
{
  std::string output;
  char buf[256];
  FILE* pipe = popen(cmd.data(), "r");
  BOOST_REQUIRE_MESSAGE(pipe != nullptr, "popen(" << cmd << ")");
  while (fgets(buf, sizeof(buf), pipe) != nullptr) {
    output += buf;
  }
  pclose(pipe);
  return output;
}

template<typename TransportType>
class FaceFixture : public KeyChainFixture
{
protected:
  FaceFixture()
    : face(TransportType::create(""), m_keyChain)
    , sched(face.getIoService())
  {
  }

  /** \brief Send an Interest from a secondary face
   *  \param delay scheduling delay before sending Interest
   *  \param interest the Interest
   *  \param[out] outcome the response, initially '?', 'D' for Data, 'N' for Nack, 'T' for timeout
   *  \return scheduled event id
   */
  scheduler::EventId
  sendInterest(time::nanoseconds delay, const Interest& interest, char& outcome)
  {
    if (face2 == nullptr) {
      face2 = make_unique<Face>(TransportType::create(""), face.getIoService(), m_keyChain);
    }

    outcome = '?';
    return sched.schedule(delay, [this, interest, &outcome] {
      face2->expressInterest(interest,
        [&] (const Interest&, const Data&) { outcome = 'D'; },
        [&] (const Interest&, const lp::Nack&) { outcome = 'N'; },
        [&] (const Interest&) { outcome = 'T'; });
    });
  }

  scheduler::EventId
  sendInterest(time::nanoseconds delay, const Interest& interest)
  {
    static char ignoredOutcome;
    return sendInterest(delay, interest, ignoredOutcome);
  }

  /** \brief Stop io_service after a delay
   *  \return scheduled event id
   */
  scheduler::EventId
  terminateAfter(time::nanoseconds delay)
  {
    return sched.schedule(delay, [this] { face.getIoService().stop(); });
  }

protected:
  Face face;
  unique_ptr<Face> face2;
  Scheduler sched;
};

using Transports = boost::mpl::vector<UnixTransport, TcpTransport>;

BOOST_AUTO_TEST_SUITE(Consumer)

BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestData, TransportType, Transports, FaceFixture<TransportType>)
{
  int nData = 0;
  this->face.expressInterest(*makeInterest("/localhost", true),
    [&] (const Interest&, const Data&) { ++nData; },
    [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
    [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });

  this->face.processEvents();
  BOOST_CHECK_EQUAL(nData, 1);
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestNack, TransportType, Transports, FaceFixture<TransportType>)
{
  int nNacks = 0;
  this->face.expressInterest(*makeInterest("/localhost/non-existent-should-nack"),
    [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
    [&] (const Interest&, const lp::Nack&) { ++nNacks; },
    [] (const Interest&) { BOOST_ERROR("unexpected timeout"); });

  this->face.processEvents();
  BOOST_CHECK_EQUAL(nNacks, 1);
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(ExpressInterestTimeout, TransportType, Transports, FaceFixture<TransportType>)
{
  // add route toward null face so Interest would timeout instead of getting Nacked
  executeCommand("nfdc route add /localhost/non-existent-should-timeout null://");
  std::this_thread::sleep_for(std::chrono::milliseconds(200)); // wait for FIB update to take effect

  int nTimeouts = 0;
  this->face.expressInterest(*makeInterest("/localhost/non-existent-should-timeout", false, 1_s),
    [] (const Interest&, const Data&) { BOOST_ERROR("unexpected Data"); },
    [] (const Interest&, const lp::Nack&) { BOOST_ERROR("unexpected Nack"); },
    [&] (const Interest&) { ++nTimeouts; });

  this->face.processEvents();
  BOOST_CHECK_EQUAL(nTimeouts, 1);
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedInterest, TransportType, Transports, FaceFixture<TransportType>)
{
  BOOST_CHECK_THROW(do {
    this->face.expressInterest(*makeInterest(makeVeryLongName()), nullptr, nullptr, nullptr);
    this->face.processEvents();
  } while (false), Face::OversizedPacketError);
}

BOOST_AUTO_TEST_SUITE_END() // Consumer

BOOST_AUTO_TEST_SUITE(Producer)

BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegisterUnregisterPrefix, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(4_s);

  int nRegSuccess = 0, nUnregSuccess = 0;
  auto handle = this->face.registerPrefix("/Hello/World",
    [&] (const Name&) { ++nRegSuccess; },
    [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });

  this->sched.schedule(1_s, [&nRegSuccess] {
    BOOST_CHECK_EQUAL(nRegSuccess, 1);
    std::string output = executeCommand("nfdc route list | grep /Hello/World");
    BOOST_CHECK(!output.empty());
  });

  this->sched.schedule(2_s, [&] {
    handle.unregister(
      [&] { ++nUnregSuccess; },
      [] (const auto& msg) { BOOST_ERROR("unexpected unregister prefix failure: " << msg); });
  });

  this->sched.schedule(3_s, [&nUnregSuccess] {
    BOOST_CHECK_EQUAL(nUnregSuccess, 1);

    // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
    std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
    BOOST_CHECK(output.empty());
  });

  this->face.processEvents();
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegularFilter, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(2_s);

  int nInterests1 = 0, nRegSuccess1 = 0, nRegSuccess2 = 0;
  this->face.setInterestFilter("/Hello/World",
    [&] (const InterestFilter&, const Interest&) { ++nInterests1; },
    [&] (const Name&) { ++nRegSuccess1; },
    [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });
  this->face.setInterestFilter("/Los/Angeles/Lakers",
    [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); },
    [&] (const Name&) { ++nRegSuccess2; },
    [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });

  this->sched.schedule(500_ms, [] {
    std::string output = executeCommand("nfdc route list | grep /Hello/World");
    BOOST_CHECK(!output.empty());
  });

  char interestOutcome;
  this->sendInterest(1_s, *makeInterest("/Hello/World/regular", false, 50_ms), interestOutcome);

  this->face.processEvents();
  BOOST_CHECK_EQUAL(interestOutcome, 'T');
  BOOST_CHECK_EQUAL(nInterests1, 1);
  BOOST_CHECK_EQUAL(nRegSuccess1, 1);
  BOOST_CHECK_EQUAL(nRegSuccess2, 1);
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilter, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(2_s);

  int nRegSuccess = 0;
  std::set<Name> receivedInterests;
  this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
    [&] (auto&&, const auto& interest) { receivedInterests.insert(interest.getName()); },
    [&] (auto&&) { ++nRegSuccess; },
    [] (auto&&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });

  this->sched.schedule(700_ms, [] {
    std::string output = executeCommand("nfdc route list | grep /Hello/World");
    BOOST_CHECK(!output.empty());
  });

  this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
  this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
  this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
  this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));

  this->face.processEvents();
  BOOST_CHECK_EQUAL(nRegSuccess, 1);
  std::set<Name> expectedInterests{"/Hello/World/a/b", "/Hello/World/a/b/c"};
  BOOST_TEST(receivedInterests == expectedInterests, boost::test_tools::per_element());
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(RegexFilterNoRegister, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(2_s);

  // no Interest shall arrive because prefix isn't registered in forwarder
  this->face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
    [&] (const InterestFilter&, const Interest&) { BOOST_ERROR("unexpected Interest"); });

  this->sched.schedule(700_ms, [] {
    // Boost.Test would fail if a child process exits with non-zero. http://stackoverflow.com/q/5325202
    std::string output = executeCommand("nfdc route list | grep /Hello/World || true");
    BOOST_CHECK(output.empty());
  });

  this->sendInterest(200_ms, *makeInterest("/Hello/World/a", false, 50_ms));
  this->sendInterest(300_ms, *makeInterest("/Hello/World/a/b", false, 50_ms));
  this->sendInterest(400_ms, *makeInterest("/Hello/World/a/b/c", false, 50_ms));
  this->sendInterest(500_ms, *makeInterest("/Hello/World/a/b/d", false, 50_ms));

  this->face.processEvents();
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(PutDataNack, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(2_s);

  this->face.setInterestFilter("/Hello/World",
    [&] (const InterestFilter&, const Interest& interest) {
      if (interest.getName().at(2) == name::Component("nack")) {
        this->face.put(makeNack(interest, lp::NackReason::NO_ROUTE));
      }
      else {
        this->face.put(*makeData(interest.getName()));
      }
    },
    nullptr,
    [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });

  char outcome1, outcome2;
  this->sendInterest(700_ms, *makeInterest("/Hello/World/data", false, 50_ms), outcome1);
  this->sendInterest(800_ms, *makeInterest("/Hello/World/nack", false, 50_ms), outcome2);

  this->face.processEvents();
  BOOST_CHECK_EQUAL(outcome1, 'D');
  BOOST_CHECK_EQUAL(outcome2, 'N');
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(OversizedData, TransportType, Transports, FaceFixture<TransportType>)
{
  this->terminateAfter(2_s);

  this->face.setInterestFilter("/Hello/World",
    [&] (const InterestFilter&, const Interest& interest) {
      this->face.put(*makeData(makeVeryLongName(interest.getName())));
    },
    nullptr,
    [] (const Name&, const auto& msg) { BOOST_ERROR("unexpected register prefix failure: " << msg); });

  this->sendInterest(1_s, *makeInterest("/Hello/World/oversized", true, 50_ms));

  BOOST_CHECK_THROW(this->face.processEvents(), Face::OversizedPacketError);
}

BOOST_AUTO_TEST_SUITE_END() // Producer

BOOST_FIXTURE_TEST_SUITE(IoRoutine, FaceFixture<UnixTransport>)

BOOST_AUTO_TEST_CASE(ShutdownWhileSendInProgress) // Bug #3136
{
  this->face.expressInterest(*makeInterest("/Hello/World"), nullptr, nullptr, nullptr);
  this->face.processEvents(1_s);

  this->face.expressInterest(*makeInterest("/Bye/World/1"), nullptr, nullptr, nullptr);
  this->face.expressInterest(*makeInterest("/Bye/World/2"), nullptr, nullptr, nullptr);
  this->face.expressInterest(*makeInterest("/Bye/World/3"), nullptr, nullptr, nullptr);
  this->face.shutdown();

  this->face.processEvents(1_s); // should not segfault
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE(LargeDelayBetweenFaceConstructorAndProcessEvents) // Bug #2742
{
  std::this_thread::sleep_for(std::chrono::seconds(5)); // simulate setup workload
  this->face.processEvents(1_s); // should not throw
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE(ProcessEventsBlocksForeverWhenNothingScheduled) // Bug #3957
{
  std::mutex m;
  std::condition_variable cv;
  bool processEventsFinished = false;

  std::thread faceThread([&] {
    this->face.processEvents();

    processEventsFinished = true;
    std::lock_guard<std::mutex> lk(m);
    cv.notify_one();
  });

  {
    std::unique_lock<std::mutex> lk(m);
    cv.wait_for(lk, std::chrono::seconds(5), [&] { return processEventsFinished; });
  }

  BOOST_CHECK_EQUAL(processEventsFinished, true);
  if (!processEventsFinished) {
    this->face.shutdown();
  }
  faceThread.join();
}

BOOST_AUTO_TEST_SUITE_END() // IoRoutine

} // namespace ndn::tests
