/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (C) 2014 Named Data Networking Project
 * See COPYING for copyright and distribution information.
 */

#include "mgmt/fib-manager.hpp"
#include "fw/forwarder.hpp"
#include "table/fib.hpp"
#include "table/fib-nexthop.hpp"
#include "face/face.hpp"
#include "mgmt/internal-face.hpp"
#include "../face/dummy-face.hpp"

#include <algorithm>

#include <ndn-cpp-dev/management/fib-management-options.hpp>
#include <ndn-cpp-dev/management/control-response.hpp>

#include <boost/test/unit_test.hpp>

namespace nfd {

NFD_LOG_INIT("FibManagerTest");

class FibManagerFixture
{
public:

  shared_ptr<Face>
  getFace(FaceId id)
  {
    if (id > 0 && id <= m_faces.size())
      {
        return m_faces[id-1];
      }
    NFD_LOG_DEBUG("No face found returning NULL");
    return shared_ptr<DummyFace>();
  }

  void
  addFace(shared_ptr<Face> face)
  {
    m_faces.push_back(face);
  }

private:
  std::vector<shared_ptr<Face> > m_faces;
};


BOOST_AUTO_TEST_SUITE(MgmtFibManager)

void
validateControlResponse(const Data& response,
                        uint32_t expectedCode,
                        const std::string& expectedText)
{
  Block controlRaw = response.getContent().blockFromValue();

  ndn::ControlResponse control;
  control.wireDecode(controlRaw);

  NFD_LOG_DEBUG("received control response"
                << " Name: " << response.getName()
                << " code: " << control.getCode()
                << " text: " << control.getText());

  BOOST_REQUIRE(control.getCode() == expectedCode);
  BOOST_REQUIRE(control.getText() == expectedText);
}

bool
foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
{
  return id == next.getFace()->getId() && next.getCost() == cost;
}

bool
addedNextHopWithCost(const Fib& fib, const Name& prefix, size_t oldSize, uint32_t cost)
{
  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch(prefix);

  if (entry)
    {
      const fib::NextHopList& hops = entry->getNextHops();
      return hops.size() == oldSize + 1 &&
        std::find_if(hops.begin(), hops.end(), bind(&foundNextHop, -1, cost, _1)) != hops.end();
    }
  return false;
}

BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
{
  FibManagerFixture fixture;
  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);

  face->onReceiveData +=
    bind(&validateControlResponse, _1, 400, "MALFORMED");

  Interest command("/localhost/nfd/fib");
  face->sendInterest(command);
}

BOOST_AUTO_TEST_CASE(MalformedCommmand)
{
  FibManagerFixture fixture;
  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);

  face->onReceiveData +=
    bind(&validateControlResponse, _1, 400, "MALFORMED");

  Interest command("/localhost/nfd/fib");
  manager.onFibRequest(command);
}

BOOST_AUTO_TEST_CASE(UnsupportedVerb)
{
  FibManagerFixture fixture;
  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);

  face->onReceiveData +=
    bind(&validateControlResponse, _1, 404, "UNSUPPORTED");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1);
  options.setCost(1);

  Block encodedOptions(options.wireEncode());

  Name commandName("/localhost/nfd/fib");
  commandName.append("unsupported");
  commandName.append(encodedOptions);

  Interest command(commandName);
  manager.onFibRequest(command);
}

BOOST_AUTO_TEST_CASE(UnsignedCommand)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                     face);
  face->onReceiveData +=
    bind(&validateControlResponse, _1, 200, "OK");
  /// \todo enable once sig checking implement
    // bind(&validateControlResponse, _1, 401, "SIGREG");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1);
  options.setCost(101);

  Block encodedOptions(options.wireEncode());

  Name commandName("/localhost/nfd/fib");
  commandName.append("add-nexthop");
  commandName.append(encodedOptions);

  Interest command(commandName);
  manager.onFibRequest(command);

  BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
}

BOOST_AUTO_TEST_CASE(UnauthorizedCommand)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                     face);
  face->onReceiveData +=
    bind(&validateControlResponse, _1, 200, "OK");
  /// \todo enable once sig checking implement
    // bind(&validateControlResponse, _1, 403, "UNAUTHORIZED");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1);
  options.setCost(101);

  Block encodedOptions(options.wireEncode());

  Name commandName("/localhost/nfd/fib");
  commandName.append("add-nexthop");
  commandName.append(encodedOptions);

  Interest command(commandName);
  manager.onFibRequest(command);

  BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
}

BOOST_AUTO_TEST_CASE(BadOptionParse)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                     face);

  face->onReceiveData +=
    bind(&validateControlResponse, _1, 400, "MALFORMED");

  Name commandName("/localhost/nfd/fib");
  commandName.append("add-nexthop");
  commandName.append("NotReallyOptions");

  Interest command(commandName);
  manager.onFibRequest(command);
}

BOOST_AUTO_TEST_CASE(UnknownFaceId)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                     face);

  face->onReceiveData +=
    bind(&validateControlResponse, _1, 400, "MALFORMED");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1000);
  options.setCost(101);

  Block encodedOptions(options.wireEncode());

  Name commandName("/localhost/nfd/fib");
  commandName.append("add-nexthop");
  commandName.append(encodedOptions);

  Interest command(commandName);
  manager.onFibRequest(command);

  BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101) == false);
}

BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);
  face->onReceiveData +=
    bind(&validateControlResponse, _1, 200, "OK");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1);
  options.setCost(101);

  Block encodedOptions(options.wireEncode());

  Name commandName("/localhost/nfd/fib");
  commandName.append("add-nexthop");
  commandName.append(encodedOptions);

  Interest command(commandName);
  manager.onFibRequest(command);

  BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", 0, 101));
}

BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);
  face->onReceiveData +=
    bind(&validateControlResponse, _1, 200, "OK");

  // Add faces with cost == FaceID for the name /hello
  // This test assumes:
  //   FaceIDs are -1 because we don't add them to a forwarder

  for (int i = 1; i <= 2; i++)
    {
      ndn::FibManagementOptions options;
      options.setName("/hello");
      options.setFaceId(i);
      options.setCost(100 + i);

      Block encodedOptions(options.wireEncode());

      Name commandName("/localhost/nfd/fib");
      commandName.append("add-nexthop");
      commandName.append(encodedOptions);

      Interest command(commandName);
      manager.onFibRequest(command);

      shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");

      if (entry)
        {
          const fib::NextHopList& hops = entry->getNextHops();
          for (int j = 1; j <= i; j++)
            {
              BOOST_REQUIRE(addedNextHopWithCost(fib, "/hello", i - 1, 100 + j));
            }
        }
      else
        {
          BOOST_FAIL("Failed to find expected fib entry");
        }
    }
}

BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
{
  FibManagerFixture fixture;
  fixture.addFace(make_shared<DummyFace>());

  shared_ptr<InternalFace> face(make_shared<InternalFace>());
  Fib fib;
  FibManager manager(fib,
                     bind(&FibManagerFixture::getFace,
                          &fixture, _1),
                          face);
  face->onReceiveData +=
    bind(&validateControlResponse, _1, 200, "OK");

  ndn::FibManagementOptions options;
  options.setName("/hello");
  options.setFaceId(1);

  {
    options.setCost(1);

    Block encodedOptions(options.wireEncode());

    Name commandName("/localhost/nfd/fib");
    commandName.append("add-nexthop");
    commandName.append(encodedOptions);

    Interest command(commandName);
    manager.onFibRequest(command);
  }

  {
    options.setCost(102);

    Block encodedOptions(options.wireEncode());

    Name commandName("/localhost/nfd/fib");
    commandName.append("add-nexthop");
    commandName.append(encodedOptions);

    Interest command(commandName);
    manager.onFibRequest(command);
  }

  shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");

  // Add faces with cost == FaceID for the name /hello
  // This test assumes:
  //   FaceIDs are -1 because we don't add them to a forwarder
  if (entry)
    {
      const fib::NextHopList& hops = entry->getNextHops();
      BOOST_REQUIRE(hops.size() == 1);
      BOOST_REQUIRE(std::find_if(hops.begin(),
                                 hops.end(),
                                 bind(&foundNextHop, -1, 102, _1)) != hops.end());
    }
  else
    {
      BOOST_FAIL("Failed to find expected fib entry");
    }
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace nfd
