/* -*- 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 "mgmt/rib-manager.hpp"
#include "core/fib-max-depth.hpp"
#include "rib/fib-updater.hpp"

#include "tests/manager-common-fixture.hpp"

#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/mgmt/nfd/rib-entry.hpp>

namespace nfd {
namespace tests {

struct ConfigurationStatus
{
  bool isLocalhostConfigured;
  bool isLocalhopConfigured;
};

static ConfigSection
getValidatorConfigSection()
{
  ConfigSection section;
  section.put("trust-anchor.type", "any");
  return section;
}

class RibManagerFixture : public ManagerCommonFixture
{
public:
  explicit
  RibManagerFixture(const ConfigurationStatus& status, bool shouldClearRib)
    : m_commands(m_face.sentInterests)
    , m_status(status)
    , m_scheduler(g_io)
    , m_nfdController(m_face, m_keyChain)
    , m_fibUpdater(m_rib, m_nfdController)
    , m_manager(m_rib, m_face, m_keyChain, m_nfdController, m_dispatcher, m_scheduler)
  {
    m_rib.mockFibResponse = [] (const rib::RibUpdateBatch& batch) {
      BOOST_CHECK(batch.begin() != batch.end());
      return true;
    };
    m_rib.wantMockFibResponseOnce = false;

    if (m_status.isLocalhostConfigured) {
      m_manager.applyLocalhostConfig(getValidatorConfigSection(), "test");
    }
    if (m_status.isLocalhopConfigured) {
      m_manager.enableLocalhop(getValidatorConfigSection(), "test");
    }
    else {
      m_manager.disableLocalhop();
    }

    registerWithNfd();

    if (shouldClearRib) {
      clearRib();
    }
  }

private:
  void
  registerWithNfd()
  {
    m_manager.registerWithNfd();
    advanceClocks(1_ms);

    auto replyFibAddCommand = [this] (const Interest& interest) {
      nfd::ControlParameters params(interest.getName().get(-5).blockFromValue());
      BOOST_CHECK(params.getName() == "/localhost/nfd/rib" || params.getName() == "/localhop/nfd/rib");
      params.setFaceId(1).setCost(0);
      nfd::ControlResponse resp;

      resp.setCode(200).setBody(params.wireEncode());
      shared_ptr<Data> data = make_shared<Data>(interest.getName());
      data->setContent(resp.wireEncode());

      m_keyChain.sign(*data, ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_SHA256));

      m_face.getIoService().post([this, data] { m_face.receive(*data); });
    };

    Name commandPrefix("/localhost/nfd/fib/add-nexthop");
    for (const auto& command : m_commands) {
      if (commandPrefix.isPrefixOf(command.getName())) {
        replyFibAddCommand(command);
        advanceClocks(1_ms);
      }
    }

    // clear commands and responses
    m_responses.clear();
    m_commands.clear();
  }

  void
  clearRib()
  {
    while (!m_rib.empty()) {
      m_rib.erase(m_rib.begin()->first, *m_rib.begin()->second->begin());
    }
  }

public:
  static ControlParameters
  makeRegisterParameters(const Name& name, uint64_t faceId = 0,
                         time::milliseconds expiry = time::milliseconds::max())
  {
    return ControlParameters()
      .setName(name)
      .setFaceId(faceId)
      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR)
      .setCost(10)
      .setFlags(0)
      .setExpirationPeriod(expiry);
  }

  static ControlParameters
  makeUnregisterParameters(const Name& name, uint64_t faceId = 0)
  {
    return ControlParameters()
      .setName(name)
      .setFaceId(faceId)
      .setOrigin(ndn::nfd::ROUTE_ORIGIN_NLSR);
  }

public:
  enum class CheckCommandResult {
    OK,
    OUT_OF_BOUNDARY,
    WRONG_FORMAT,
    WRONG_VERB,
    WRONG_PARAMS_FORMAT,
    WRONG_PARAMS_NAME,
    WRONG_PARAMS_FACE
  };

  CheckCommandResult
  checkCommand(size_t idx, const char* verbStr, const ControlParameters& expectedParams) const
  {
    if (idx > m_commands.size()) {
      return CheckCommandResult::OUT_OF_BOUNDARY;
    }
    const auto& name = m_commands[idx].getName();

    if (!FIB_COMMAND_PREFIX.isPrefixOf(name) || FIB_COMMAND_PREFIX.size() >= name.size()) {
      return CheckCommandResult::WRONG_FORMAT;
    }
    const auto& verb = name[FIB_COMMAND_PREFIX.size()];

    Name::Component expectedVerb(verbStr);
    if (verb != expectedVerb) {
      return CheckCommandResult::WRONG_VERB;
    }

    ControlParameters parameters;
    try {
      Block rawParameters = name[FIB_COMMAND_PREFIX.size() + 1].blockFromValue();
      parameters.wireDecode(rawParameters);
    }
    catch (...) {
      return CheckCommandResult::WRONG_PARAMS_FORMAT;
    }

    if (parameters.getName() != expectedParams.getName()) {
      return CheckCommandResult::WRONG_PARAMS_NAME;
    }

    if (parameters.getFaceId() != expectedParams.getFaceId()) {
      return CheckCommandResult::WRONG_PARAMS_FACE;
    }

    return CheckCommandResult::OK;
  }

protected:
  static const Name FIB_COMMAND_PREFIX;
  std::vector<Interest>& m_commands;
  ConfigurationStatus m_status;

  ndn::util::Scheduler m_scheduler;
  ndn::nfd::Controller m_nfdController;
  rib::Rib m_rib;
  rib::FibUpdater m_fibUpdater;
  RibManager m_manager;
};

const Name RibManagerFixture::FIB_COMMAND_PREFIX("/localhost/nfd/fib");

std::ostream&
operator<<(std::ostream& os, RibManagerFixture::CheckCommandResult result)
{
  switch (result) {
  case RibManagerFixture::CheckCommandResult::OK:
    return os << "OK";
  case RibManagerFixture::CheckCommandResult::OUT_OF_BOUNDARY:
    return os << "OUT_OF_BOUNDARY";
  case RibManagerFixture::CheckCommandResult::WRONG_FORMAT:
    return os << "WRONG_FORMAT";
  case RibManagerFixture::CheckCommandResult::WRONG_VERB:
    return os << "WRONG_VERB";
  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FORMAT:
    return os << "WRONG_PARAMS_FORMAT";
  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_NAME:
    return os << "WRONG_PARAMS_NAME";
  case RibManagerFixture::CheckCommandResult::WRONG_PARAMS_FACE:
    return os << "WRONG_PARAMS_FACE";
  };

  return os << static_cast<int>(result);
}

BOOST_AUTO_TEST_SUITE(Mgmt)
BOOST_AUTO_TEST_SUITE(TestRibManager)

class AddTopPrefixFixture : public RibManagerFixture
{
public:
  AddTopPrefixFixture()
    : RibManagerFixture({true, true}, false)
  {
  }
};

BOOST_FIXTURE_TEST_CASE(AddTopPrefix, AddTopPrefixFixture)
{
  BOOST_CHECK_EQUAL(m_rib.size(), 2);

  std::vector<Name> ribEntryNames;
  for (auto&& entry : m_rib) {
    ribEntryNames.push_back(entry.first);
  }
  BOOST_CHECK_EQUAL(ribEntryNames[0], "/localhop/nfd");
  BOOST_CHECK_EQUAL(ribEntryNames[1], "/localhost/nfd");
}

class UnauthorizedRibManagerFixture : public RibManagerFixture
{
public:
  UnauthorizedRibManagerFixture()
    : RibManagerFixture({false, false}, true)
  {
  }
};

class LocalhostAuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  LocalhostAuthorizedRibManagerFixture()
    : RibManagerFixture({true, false}, true)
  {
  }
};

class LocalhopAuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  LocalhopAuthorizedRibManagerFixture()
    : RibManagerFixture({false, true}, true)
  {
  }
};

class AuthorizedRibManagerFixture : public RibManagerFixture
{
public:
  AuthorizedRibManagerFixture()
    : RibManagerFixture({true, true}, true)
  {
  }
};

using AllFixtures = boost::mpl::vector<
  UnauthorizedRibManagerFixture,
  LocalhostAuthorizedRibManagerFixture,
  LocalhopAuthorizedRibManagerFixture,
  AuthorizedRibManagerFixture
>;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(CommandAuthorization, T, AllFixtures, T)
{
  auto parameters  = this->makeRegisterParameters("/test-authorization", 9527);
  auto commandHost = this->makeControlCommandRequest("/localhost/nfd/rib/register", parameters);
  auto commandHop  = this->makeControlCommandRequest("/localhop/nfd/rib/register", parameters);
  auto successResp = this->makeResponse(200, "Success", parameters);
  auto failureResp = ControlResponse(403, "authorization rejected");

  BOOST_CHECK_EQUAL(this->m_responses.size(), 0);
  this->receiveInterest(commandHost);
  this->receiveInterest(commandHop);

  auto nExpectedResponses = this->m_status.isLocalhopConfigured ? 2 : 1;
  auto expectedLocalhostResponse = this->m_status.isLocalhostConfigured ? successResp : failureResp;
  auto expectedLocalhopResponse = this->m_status.isLocalhopConfigured ? successResp : failureResp;

  BOOST_REQUIRE_EQUAL(this->m_responses.size(), nExpectedResponses);
  BOOST_CHECK_EQUAL(this->checkResponse(0, commandHost.getName(), expectedLocalhostResponse),
                    ManagerCommonFixture::CheckResponseResult::OK);
  if (nExpectedResponses == 2) {
    BOOST_CHECK_EQUAL(this->checkResponse(1, commandHop.getName(), expectedLocalhopResponse),
                      ManagerCommonFixture::CheckResponseResult::OK);
  }
}

BOOST_FIXTURE_TEST_SUITE(RegisterUnregister, LocalhostAuthorizedRibManagerFixture)

BOOST_AUTO_TEST_CASE(Basic)
{
  auto paramsRegister    = makeRegisterParameters("/test-register-unregister", 9527);
  auto paramsUnregister  = makeUnregisterParameters("/test-register-unregister", 9527);

  auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister);
  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));
  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(1234));

  receiveInterest(commandRegister);
  receiveInterest(commandUnregister);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "Success", paramsRegister)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "Success", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
}

BOOST_AUTO_TEST_CASE(SelfOperation)
{
  auto paramsRegister = makeRegisterParameters("/test-self-register-unregister");
  auto paramsUnregister = makeUnregisterParameters("/test-self-register-unregister");
  BOOST_CHECK_EQUAL(paramsRegister.getFaceId(), 0);
  BOOST_CHECK_EQUAL(paramsUnregister.getFaceId(), 0);

  const uint64_t inFaceId = 9527;
  auto commandRegister = makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister);
  commandRegister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));
  auto commandUnregister = makeControlCommandRequest("/localhost/nfd/rib/unregister", paramsUnregister);
  commandUnregister.setTag(make_shared<lp::IncomingFaceIdTag>(inFaceId));

  receiveInterest(commandRegister);
  receiveInterest(commandUnregister);

  paramsRegister.setFaceId(inFaceId);
  paramsUnregister.setFaceId(inFaceId);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 2);
  BOOST_CHECK_EQUAL(checkResponse(0, commandRegister.getName(), makeResponse(200, "Success", paramsRegister)),
                    CheckResponseResult::OK);
  BOOST_CHECK_EQUAL(checkResponse(1, commandUnregister.getName(), makeResponse(200, "Success", paramsUnregister)),
                    CheckResponseResult::OK);

  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);
}

BOOST_AUTO_TEST_CASE(Expiration)
{
  auto paramsRegister = makeRegisterParameters("/test-expiry", 9527, 50_ms);
  auto paramsUnregister = makeRegisterParameters("/test-expiry", 9527);
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));

  advanceClocks(55_ms);
  BOOST_REQUIRE_EQUAL(m_commands.size(), 2); // the registered route has expired
  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
  BOOST_CHECK_EQUAL(checkCommand(1, "remove-nexthop", paramsUnregister), CheckCommandResult::OK);

  m_commands.clear();
  paramsRegister.setExpirationPeriod(100_ms);
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", paramsRegister));

  advanceClocks(55_ms);
  BOOST_REQUIRE_EQUAL(m_commands.size(), 1); // the registered route is still active
  BOOST_CHECK_EQUAL(checkCommand(0, "add-nexthop", paramsRegister), CheckCommandResult::OK);
}

BOOST_AUTO_TEST_CASE(NameTooLong)
{
  Name prefix;
  while (prefix.size() <= FIB_MAX_DEPTH) {
    prefix.append("A");
  }
  auto params = makeRegisterParameters(prefix, 2899);
  auto command = makeControlCommandRequest("/localhost/nfd/rib/register", params);
  receiveInterest(command);

  BOOST_REQUIRE_EQUAL(m_responses.size(), 1);
  BOOST_CHECK_EQUAL(checkResponse(0, command.getName(), ControlResponse(414,
                      "Route prefix cannot exceed " + ndn::to_string(FIB_MAX_DEPTH) +
                      " components")),
                    CheckResponseResult::OK);

  BOOST_CHECK_EQUAL(m_commands.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // RegisterUnregister

BOOST_FIXTURE_TEST_CASE(RibDataset, UnauthorizedRibManagerFixture)
{
  uint64_t faceId = 0;
  auto generateRoute = [&faceId] () -> rib::Route {
    rib::Route route;
    route.faceId = ++faceId;
    route.cost = route.faceId * 10;
    route.expires = nullopt;
    return route;
  };

  const size_t nEntries = 108;
  std::set<Name> actualPrefixes;
  for (size_t i = 0; i < nEntries; ++i) {
    Name prefix = Name("/test-dataset").appendNumber(i);
    actualPrefixes.insert(prefix);
    m_rib.insert(prefix, generateRoute());
    if (i & 0x1) {
      m_rib.insert(prefix, generateRoute());
      m_rib.insert(prefix, generateRoute());
    }
  }

  receiveInterest(Interest("/localhost/nfd/rib/list"));

  Block content = concatenateResponses();
  content.parse();
  BOOST_REQUIRE_EQUAL(content.elements().size(), nEntries);

  std::vector<ndn::nfd::RibEntry> receivedRecords, expectedRecords;
  for (size_t idx = 0; idx < nEntries; ++idx) {
    ndn::nfd::RibEntry decodedEntry(content.elements()[idx]);
    receivedRecords.push_back(decodedEntry);
    actualPrefixes.erase(decodedEntry.getName());

    auto matchedEntryIt = m_rib.find(decodedEntry.getName());
    BOOST_REQUIRE(matchedEntryIt != m_rib.end());

    auto matchedEntry = matchedEntryIt->second;
    BOOST_REQUIRE(matchedEntry != nullptr);

    expectedRecords.emplace_back();
    expectedRecords.back().setName(matchedEntry->getName());
    for (const auto& route : matchedEntry->getRoutes()) {
      expectedRecords.back().addRoute(ndn::nfd::Route()
                                      .setFaceId(route.faceId)
                                      .setOrigin(route.origin)
                                      .setCost(route.cost)
                                      .setFlags(route.flags));
    }
  }

  BOOST_CHECK_EQUAL(actualPrefixes.size(), 0);
  BOOST_CHECK_EQUAL_COLLECTIONS(receivedRecords.begin(), receivedRecords.end(),
                                expectedRecords.begin(), expectedRecords.end());
}

BOOST_FIXTURE_TEST_SUITE(FaceMonitor, LocalhostAuthorizedRibManagerFixture)

BOOST_AUTO_TEST_CASE(FetchActiveFacesEvent)
{
  BOOST_CHECK_EQUAL(m_commands.size(), 0);

  advanceClocks(301_s); // RibManager::ACTIVE_FACE_FETCH_INTERVAL = 300s
  BOOST_REQUIRE_EQUAL(m_commands.size(), 2);
  BOOST_CHECK_EQUAL(m_commands[0].getName(), "/localhost/nfd/faces/events");
  BOOST_CHECK_EQUAL(m_commands[1].getName(), "/localhost/nfd/faces/list");
}

BOOST_AUTO_TEST_CASE(RemoveInvalidFaces)
{
  auto parameters1 = makeRegisterParameters("/test-remove-invalid-faces-1");
  auto parameters2 = makeRegisterParameters("/test-remove-invalid-faces-2");
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(1)));
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1.setFaceId(2)));
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2.setFaceId(2)));
  BOOST_REQUIRE_EQUAL(m_rib.size(), 3);

  ndn::nfd::FaceStatus status;
  status.setFaceId(1);
  std::vector<ndn::nfd::FaceStatus> activeFaces;
  activeFaces.push_back(status);

  m_manager.removeInvalidFaces(activeFaces);
  advanceClocks(100_ms);
  BOOST_REQUIRE_EQUAL(m_rib.size(), 1);

  auto it1 = m_rib.find("/test-remove-invalid-faces-1");
  auto it2 = m_rib.find("/test-remove-invalid-faces-2");
  BOOST_CHECK(it2 == m_rib.end());
  BOOST_REQUIRE(it1 != m_rib.end());
  BOOST_CHECK(it1->second->hasFaceId(1));
  BOOST_CHECK(!it1->second->hasFaceId(2));
}

BOOST_AUTO_TEST_CASE(OnNotification)
{
  auto parameters1 = makeRegisterParameters("/test-face-event-notification-1", 1);
  auto parameters2 = makeRegisterParameters("/test-face-event-notification-2", 1);
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters1));
  receiveInterest(makeControlCommandRequest("/localhost/nfd/rib/register", parameters2));
  BOOST_REQUIRE_EQUAL(m_rib.size(), 2);

  auto makeNotification = [] (ndn::nfd::FaceEventKind kind, uint64_t faceId) {
    return ndn::nfd::FaceEventNotification().setKind(kind).setFaceId(faceId);
  };

  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_DESTROYED, 1));
  advanceClocks(100_ms);
  BOOST_CHECK_EQUAL(m_rib.size(), 0);

  m_manager.onNotification(makeNotification(ndn::nfd::FaceEventKind::FACE_EVENT_CREATED, 2));
  advanceClocks(100_ms);
  BOOST_CHECK_EQUAL(m_rib.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // FaceMonitor

BOOST_AUTO_TEST_SUITE_END() // TestRibManager
BOOST_AUTO_TEST_SUITE_END() // Mgmt

} // namespace tests
} // namespace nfd
