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

#include "mgmt/nfd/rib-entry.hpp"

#include "boost-test.hpp"
#include <boost/lexical_cast.hpp>

namespace ndn {
namespace nfd {
namespace tests {

BOOST_AUTO_TEST_SUITE(Mgmt)
BOOST_AUTO_TEST_SUITE(Nfd)
BOOST_AUTO_TEST_SUITE(TestRibEntry)

static Route
makeRoute()
{
  return Route()
      .setFaceId(1)
      .setOrigin(128)
      .setCost(100)
      .setFlags(ndn::nfd::ROUTE_FLAG_CAPTURE);
}

static RibEntry
makeRibEntry()
{
  return RibEntry()
      .setName("/hello/world")
      .addRoute(makeRoute()
                .setExpirationPeriod(time::seconds(10)));
}

BOOST_AUTO_TEST_CASE(RouteEncode)
{
  Route route1 = makeRoute();
  route1.setExpirationPeriod(time::seconds(10));
  const Block& wire = route1.wireEncode();

  static const uint8_t expected[] = {
    0x81, 0x10, 0x69, 0x01, 0x01, 0x6f, 0x01, 0x80, 0x6a, 0x01, 0x64, 0x6c, 0x01, 0x02,
    0x6d, 0x02, 0x27, 0x10
  };
  BOOST_CHECK_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                wire.begin(), wire.end());

  Route route2(wire);
  BOOST_CHECK_EQUAL(route1, route2);
}

BOOST_AUTO_TEST_CASE(RouteNoExpirationPeriodEncode)
{
  Route route1 = makeRoute();
  const Block& wire = route1.wireEncode();

  static const uint8_t expected[] = {
    0x81, 0x0C, 0x69, 0x01, 0x01, 0x6f, 0x01, 0x80, 0x6a, 0x01, 0x64, 0x6c, 0x01, 0x02
  };
  BOOST_CHECK_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                wire.begin(), wire.end());

  Route route2(wire);
  BOOST_CHECK_EQUAL(route1, route2);
}

BOOST_AUTO_TEST_CASE(RouteExpirationPeriod)
{
  Route route;
  BOOST_CHECK_EQUAL(route.hasExpirationPeriod(), false);
  BOOST_CHECK_EQUAL(route.getExpirationPeriod(), time::milliseconds::max());

  route.setExpirationPeriod(time::minutes(1));
  BOOST_CHECK_EQUAL(route.hasExpirationPeriod(), true);
  BOOST_CHECK_EQUAL(route.getExpirationPeriod(), time::minutes(1));

  route.setExpirationPeriod(time::milliseconds::max());
  BOOST_CHECK_EQUAL(route.hasExpirationPeriod(), false);
  BOOST_CHECK_EQUAL(route.getExpirationPeriod(), time::milliseconds::max());

  route.setExpirationPeriod(time::minutes(1));
  BOOST_CHECK_EQUAL(route.hasExpirationPeriod(), true);

  route.unsetExpirationPeriod();
  BOOST_CHECK_EQUAL(route.hasExpirationPeriod(), false);
}

BOOST_AUTO_TEST_CASE(RouteEquality)
{
  Route route1, route2;

  route1 = makeRoute();
  route2 = route1;
  BOOST_CHECK_EQUAL(route1, route2);

  route2.setFaceId(42);
  BOOST_CHECK_NE(route1, route2);

  route2 = route1;
  route2.setExpirationPeriod(time::minutes(1));
  BOOST_CHECK_NE(route1, route2);
}

BOOST_AUTO_TEST_CASE(RibEntryEncode)
{
  RibEntry entry1 = makeRibEntry();
  entry1.addRoute(Route()
                  .setFaceId(2)
                  .setOrigin(0)
                  .setCost(32)
                  .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT)
                  .setExpirationPeriod(time::seconds(5)));
  const Block& wire = entry1.wireEncode();

  static const uint8_t expected[] = {
    0x80, 0x34, 0x07, 0x0e, 0x08, 0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x08, 0x05, 0x77,
    0x6f, 0x72, 0x6c, 0x64, 0x81, 0x10, 0x69, 0x01, 0x01, 0x6f, 0x01, 0x80, 0x6a, 0x01,
    0x64, 0x6c, 0x01, 0x02, 0x6d, 0x02, 0x27, 0x10, 0x81, 0x10, 0x69, 0x01, 0x02, 0x6f,
    0x01, 0x00, 0x6a, 0x01, 0x20, 0x6c, 0x01, 0x01, 0x6d, 0x02, 0x13, 0x88
  };
  BOOST_CHECK_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                wire.begin(), wire.end());

  RibEntry entry2(wire);
  BOOST_CHECK_EQUAL(entry1, entry2);
}

BOOST_AUTO_TEST_CASE(RibEntryClearRoutes)
{
  RibEntry entry;
  entry.setName("/hello/world");
  BOOST_CHECK_EQUAL(entry.getRoutes().size(), 0);

  Route route1;
  route1.setFaceId(42);
  entry.addRoute(route1);
  BOOST_REQUIRE_EQUAL(entry.getRoutes().size(), 1);
  BOOST_CHECK_EQUAL(entry.getRoutes().front(), route1);

  entry.clearRoutes();
  BOOST_CHECK_EQUAL(entry.getRoutes().size(), 0);
}

BOOST_AUTO_TEST_CASE(RibEntryEquality)
{
  RibEntry entry1, entry2;
  BOOST_CHECK_EQUAL(entry1, entry2);

  entry1 = entry2 = makeRibEntry();
  BOOST_CHECK_EQUAL(entry1, entry2);
  BOOST_CHECK_EQUAL(entry2, entry1);

  entry2.setName("/different/name");
  BOOST_CHECK_NE(entry1, entry2);

  entry2 = entry1;
  std::vector<Route> empty;
  entry2.setRoutes(empty.begin(), empty.end());
  BOOST_CHECK_NE(entry1, entry2);
  BOOST_CHECK_NE(entry2, entry1);

  entry2 = entry1;
  auto r1 = Route()
            .setFaceId(1)
            .setCost(1000);
  entry1.addRoute(r1);
  BOOST_CHECK_NE(entry1, entry2);
  BOOST_CHECK_NE(entry2, entry1);

  auto r42 = Route()
             .setFaceId(42)
             .setCost(42);
  entry1.addRoute(r42);
  entry2.addRoute(r42)
      .addRoute(r1);
  BOOST_CHECK_EQUAL(entry1, entry2); // order of Routes is irrelevant
  BOOST_CHECK_EQUAL(entry2, entry1);

  entry1 = entry2 = makeRibEntry();
  entry1.addRoute(r1)
      .addRoute(r42);
  entry2.addRoute(r42)
      .addRoute(r42);
  BOOST_CHECK_NE(entry1, entry2); // match each Route at most once
  BOOST_CHECK_NE(entry2, entry1);
}

BOOST_AUTO_TEST_CASE(Print)
{
  Route route;
  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(route),
                    "Route(FaceId: 0, Origin: 0, Cost: 0, Flags: 0x1, ExpirationPeriod: infinite)");

  RibEntry entry;
  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(entry),
                    "RibEntry(Prefix: /,\n"
                    "         Routes: []\n"
                    "         )");

  entry = makeRibEntry();
  entry.addRoute(Route()
                 .setFaceId(2)
                 .setOrigin(0)
                 .setCost(32)
                 .setFlags(ndn::nfd::ROUTE_FLAG_CHILD_INHERIT));
  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(entry),
                    "RibEntry(Prefix: /hello/world,\n"
                    "         Routes: [Route(FaceId: 1, Origin: 128, Cost: 100, Flags: 0x2, "
                    "ExpirationPeriod: 10000 milliseconds),\n"
                    "                  Route(FaceId: 2, Origin: 0, Cost: 32, Flags: 0x1, "
                    "ExpirationPeriod: infinite)]\n"
                    "         )");
}

BOOST_AUTO_TEST_SUITE_END() // TestRibEntry
BOOST_AUTO_TEST_SUITE_END() // Nfd
BOOST_AUTO_TEST_SUITE_END() // Mgmt

} // namespace tests
} // namespace nfd
} // namespace ndn
