/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2020,  The University of Memphis,
 *                           Regents of the University of California,
 *                           Arizona Board of Regents.
 *
 * This file is part of NLSR (Named-data Link State Routing).
 * See AUTHORS.md for complete list of NLSR authors and contributors.
 *
 * NLSR 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.
 *
 * NLSR 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
 * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "route/nexthop-list.hpp"
#include "route/nexthop.hpp"
#include "tests/boost-test.hpp"

namespace nlsr {
namespace test {

BOOST_AUTO_TEST_SUITE(TestNhl)

BOOST_AUTO_TEST_CASE(NhlAddNextHop)
{
  NextHop np1;

  NexthopList nhl1;

  nhl1.addNextHop(np1);
  BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)1);

  nhl1.removeNextHop(np1);
  BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)0);
}

BOOST_AUTO_TEST_CASE(LinkStateRemoveNextHop)
{
  NextHop hop1;
  hop1.setRouteCost(12.34);

  NexthopList hopList;
  hopList.addNextHop(hop1);

  NextHop hop2;
  hop2.setRouteCost(13.01);

  BOOST_REQUIRE_EQUAL(hopList.size(), 1);

  hopList.removeNextHop(hop2);
  BOOST_CHECK_EQUAL(hopList.size(), 1);

  hopList.removeNextHop(hop1);
  BOOST_CHECK_EQUAL(hopList.size(), 0);
}

BOOST_AUTO_TEST_CASE(HyperbolicRemoveNextHop)
{
  NextHop hop1;
  hop1.setHyperbolic(true);
  hop1.setRouteCost(12.34);

  NexthopList hopList;
  hopList.addNextHop(hop1);

  NextHop hop2;
  hop2.setHyperbolic(true);
  hop2.setRouteCost(12.35);

  BOOST_REQUIRE_EQUAL(hopList.size(), 1);

  hopList.removeNextHop(hop2);
  BOOST_CHECK_EQUAL(hopList.size(), 1);

  hopList.removeNextHop(hop1);
  BOOST_CHECK_EQUAL(hopList.size(), 0);
}

BOOST_AUTO_TEST_CASE(TieBreaker)
{
  // equal-cost hops are sorted lexicographically
  NextHop hopA;
  hopA.setRouteCost(25);
  hopA.setConnectingFaceUri("AAAZZ");

  NextHop hopZ;
  hopZ.setRouteCost(25);
  hopZ.setConnectingFaceUri("ZZA");

  NexthopList list;
  list.addNextHop(hopA);
  list.addNextHop(hopZ);

  NexthopList::iterator it = list.begin();
  BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());

  list.clear();
  list.addNextHop(hopZ);
  list.addNextHop(hopA);

  it = list.begin();
  BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());


  // equal-cost and lexicographically equal hops are sorted by the length of their face uris
  NextHop longUriHop;
  longUriHop.setRouteCost(25);
  longUriHop.setConnectingFaceUri("AAAAAA");

  NextHop shortUriHop;
  shortUriHop.setRouteCost(25);
  shortUriHop.setConnectingFaceUri("AAA");

  list.clear();
  list.addNextHop(longUriHop);
  list.addNextHop(shortUriHop);

  it = list.begin();
  BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), shortUriHop.getConnectingFaceUri());
}

BOOST_AUTO_TEST_CASE(SortOnAddAndRemove)
{
  NexthopList list;

  NextHop hopA("A", 10);
  NextHop hopB("B", 5);
  NextHop hopC("C", 25);

  list.addNextHop(hopA);
  list.addNextHop(hopB);
  list.addNextHop(hopC);

  BOOST_REQUIRE_EQUAL(list.size(), 3);

  double lastCost = 0;
  for (const auto& hop : list) {
    BOOST_CHECK(hop.getRouteCost() > lastCost);
    lastCost = hop.getRouteCost();
  }

  // removing a hop keep the list sorted
  list.removeNextHop(hopA);

  BOOST_REQUIRE_EQUAL(list.size(), 2);

  lastCost = 0;
  for (const auto& hop : list) {
    BOOST_CHECK(hop.getRouteCost() > lastCost);
    lastCost = hop.getRouteCost();
  }
}

/* If there are two NextHops going to the same neighbor, then the list
   should always select the one with the cheaper cost. This would be
   caused by a Name being advertised by two different routers, which
   are reachable through the same neighbor.
 */
BOOST_AUTO_TEST_CASE(UseCheaperNextHop)
{
  NexthopList list;

  NextHop hopA("udp4://10.0.0.1:6363", 10);
  NextHop hopB("udp4://10.0.0.1:6363", 5);

  list.addNextHop(hopA);
  list.addNextHop(hopB);

  BOOST_REQUIRE_EQUAL(list.size(), 1);

  for (const auto& hop : list) {
    BOOST_CHECK_EQUAL(hop, hopB);
  }
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace test
} // namespace nlsr
