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

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

#include <ndn-cxx/util/dummy-client-face.hpp>

#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>

namespace nfd::tests {

using namespace nfd::rib;

class DummyReadvertisePolicy : public ReadvertisePolicy
{
public:
  std::optional<ReadvertiseAction>
  handleNewRoute(const RibRouteRef&) const override
  {
    return this->decision;
  }

  time::milliseconds
  getRefreshInterval() const override
  {
    return 1_min;
  }

public:
  std::optional<ReadvertiseAction> decision;
};

class DummyReadvertiseDestination : public ReadvertiseDestination
{
public:
  DummyReadvertiseDestination()
  {
    this->setAvailability(true);
  }

  void
  advertise(const ReadvertisedRoute& rr,
            std::function<void()> successCb,
            std::function<void(const std::string&)> failureCb) override
  {
    advertiseHistory.push_back({time::steady_clock::now(), rr.prefix});
    if (shouldSucceed) {
      successCb();
    }
    else {
      failureCb("FAKE-FAILURE");
    }
  }

  void
  withdraw(const ReadvertisedRoute& rr,
           std::function<void()> successCb,
           std::function<void(const std::string&)> failureCb) override
  {
    withdrawHistory.push_back({time::steady_clock::now(), rr.prefix});
    if (shouldSucceed) {
      successCb();
    }
    else {
      failureCb("FAKE-FAILURE");
    }
  }

  void
  setAvailability(bool isAvailable)
  {
    this->ReadvertiseDestination::setAvailability(isAvailable);
  }

public:
  struct HistoryEntry
  {
    time::steady_clock::time_point timestamp;
    Name prefix;
  };

  bool shouldSucceed = true;
  std::vector<HistoryEntry> advertiseHistory;
  std::vector<HistoryEntry> withdrawHistory;
};

class ReadvertiseFixture : public GlobalIoTimeFixture, public KeyChainFixture
{
public:
  ReadvertiseFixture()
    : m_face(g_io, m_keyChain, {false, false})
  {
    auto policyPtr = make_unique<DummyReadvertisePolicy>();
    policy = policyPtr.get();
    auto destinationPtr = make_unique<DummyReadvertiseDestination>();
    destination = destinationPtr.get();
    readvertise = make_unique<Readvertise>(m_rib, std::move(policyPtr), std::move(destinationPtr));
  }

  void
  insertRoute(const Name& prefix, uint64_t faceId, ndn::nfd::RouteOrigin origin)
  {
    Route route;
    route.faceId = faceId;
    route.origin = origin;
    m_rib.insert(prefix, route);
    this->advanceClocks(6_ms);
  }

  void
  eraseRoute(const Name& prefix, uint64_t faceId, ndn::nfd::RouteOrigin origin)
  {
    Route route;
    route.faceId = faceId;
    route.origin = origin;
    m_rib.erase(prefix, route);
    this->advanceClocks(6_ms);
  }

  void
  setDestinationAvailability(bool isAvailable)
  {
    destination->setAvailability(isAvailable);
    this->advanceClocks(6_ms);
  }

protected:
  DummyReadvertisePolicy* policy;
  DummyReadvertiseDestination* destination;
  unique_ptr<Readvertise> readvertise;

private:
  ndn::DummyClientFace m_face;
  Rib m_rib;
};

BOOST_AUTO_TEST_SUITE(Rib)
BOOST_FIXTURE_TEST_SUITE(TestReadvertise, ReadvertiseFixture)

BOOST_AUTO_TEST_CASE(AddRemoveRoute)
{
  policy->decision = ReadvertiseAction{"/A", ndn::security::SigningInfo()};

  // advertising /A
  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 1);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.at(0).prefix, "/A");

  // /A is already advertised
  this->insertRoute("/A/2", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 1);

  // refresh every 60 seconds
  destination->advertiseHistory.clear();
  this->advanceClocks(61_s, 5);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 5);

  // /A is still needed by /A/2 route
  this->eraseRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0);

  // withdrawing /A
  this->eraseRoute("/A/2", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 1);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.at(0).prefix, "/A");
}

BOOST_AUTO_TEST_CASE(NoAdvertise)
{
  policy->decision = std::nullopt;

  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->insertRoute("/A/2", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->eraseRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->eraseRoute("/A/2", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);

  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 0);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0);
}

BOOST_AUTO_TEST_CASE(DestinationAvailability)
{
  this->setDestinationAvailability(false);

  policy->decision = ReadvertiseAction{"/A", ndn::security::SigningInfo()};
  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  policy->decision = ReadvertiseAction{"/B", ndn::security::SigningInfo()};
  this->insertRoute("/B/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 0);

  this->setDestinationAvailability(true);
  std::set<Name> advertisedPrefixes;
  boost::copy(destination->advertiseHistory | boost::adaptors::transformed(
                [] (const auto& he) { return he.prefix; }),
              std::inserter(advertisedPrefixes, advertisedPrefixes.end()));
  const std::set<Name> expectedPrefixes{"/A", "/B"};
  BOOST_TEST(advertisedPrefixes == expectedPrefixes, boost::test_tools::per_element());
  destination->advertiseHistory.clear();

  this->setDestinationAvailability(false);
  this->eraseRoute("/B/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0);

  this->setDestinationAvailability(true);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 1);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.at(0).prefix, "/A");
}

BOOST_AUTO_TEST_CASE(AdvertiseRetryInterval)
{
  destination->shouldSucceed = false;

  policy->decision = ReadvertiseAction{"/A", ndn::security::SigningInfo()};
  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);

  this->advanceClocks(10_s, 1_h);
  BOOST_REQUIRE_GT(destination->advertiseHistory.size(), 2);

  // destination->advertise keeps failing, so interval should increase
  using FloatInterval = time::duration<float, time::steady_clock::duration::period>;
  FloatInterval initialInterval = destination->advertiseHistory[1].timestamp -
                                  destination->advertiseHistory[0].timestamp;
  FloatInterval lastInterval = initialInterval;
  for (size_t i = 2; i < destination->advertiseHistory.size(); ++i) {
    FloatInterval interval = destination->advertiseHistory[i].timestamp -
                             destination->advertiseHistory[i - 1].timestamp;
    BOOST_CHECK_CLOSE(interval.count(), (lastInterval * 2.0).count(), 10.0);
    lastInterval = interval;
  }

  destination->shouldSucceed = true;
  this->advanceClocks(1_h);
  destination->advertiseHistory.clear();

  // destination->advertise has succeeded, retry interval should reset to initial
  destination->shouldSucceed = false;
  this->advanceClocks(10_s, 300_s);
  BOOST_REQUIRE_GE(destination->advertiseHistory.size(), 2);
  FloatInterval restartInterval = destination->advertiseHistory[1].timestamp -
                                  destination->advertiseHistory[0].timestamp;
  BOOST_CHECK_CLOSE(restartInterval.count(), initialInterval.count(), 10.0);
}

BOOST_AUTO_TEST_CASE(ChangeDuringRetry)
{
  destination->shouldSucceed = false;
  policy->decision = ReadvertiseAction{"/A", ndn::security::SigningInfo()};
  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->advanceClocks(10_s, 300_s);
  BOOST_CHECK_GT(destination->advertiseHistory.size(), 0);
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0);

  // destination->advertise has been failing, but we want to withdraw
  destination->advertiseHistory.clear();
  destination->withdrawHistory.clear();
  this->eraseRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->advanceClocks(10_s, 300_s);
  BOOST_CHECK_EQUAL(destination->advertiseHistory.size(), 0); // don't try to advertise
  BOOST_CHECK_GT(destination->withdrawHistory.size(), 0); // try to withdraw

  // destination->withdraw has been failing, but we want to advertise
  destination->advertiseHistory.clear();
  destination->withdrawHistory.clear();
  this->insertRoute("/A/1", 1, ndn::nfd::ROUTE_ORIGIN_CLIENT);
  this->advanceClocks(10_s, 300_s);
  BOOST_CHECK_GT(destination->advertiseHistory.size(), 0); // try to advertise
  BOOST_CHECK_EQUAL(destination->withdrawHistory.size(), 0); // don't try to withdraw
}

BOOST_AUTO_TEST_SUITE_END() // TestReadvertise
BOOST_AUTO_TEST_SUITE_END() // Rib

} // namespace nfd::tests
