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

#include "face-system-fixture.hpp"
#include "factory-test-common.hpp"

#include <boost/algorithm/string/replace.hpp>

namespace nfd::tests {

namespace ip = boost::asio::ip;
using face::UdpChannel;
using face::UdpFactory;
using ndn::net::NetworkInterface;

class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
{
protected:
  shared_ptr<UdpChannel>
  createChannel(const std::string& localIp, uint16_t localPort)
  {
    udp::Endpoint endpoint(ip::make_address(localIp), localPort);
    return factory.createChannel(endpoint, 5_min);
  }
};

class UdpFactoryMcastFixture : public UdpFactoryFixture
{
protected:
  UdpFactoryMcastFixture()
  {
    for (const auto& netif : collectNetworkInterfaces()) {
      // similar filtering logic to UdpFactory::applyMcastConfigToNetif()
      if (netif->isUp() && !netif->isLoopback() && netif->canMulticast()) {
        bool hasValidIpAddress = false;
        if (hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
          hasValidIpAddress = true;
          netifsV4.push_back(netif);
        }
        if (hasAddressFamily(*netif, ndn::net::AddressFamily::V6)) {
          hasValidIpAddress = true;
          netifsV6.push_back(netif);
        }
        if (hasValidIpAddress) {
          netifs.push_back(netif);
        }
      }
    }
  }

  std::vector<const Face*>
  listUdp4McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
  {
    return listFacesByScheme("udp4", linkType);
  }

  std::vector<const Face*>
  listUdp6McastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
  {
    return listFacesByScheme("udp6", linkType);
  }

  shared_ptr<NetworkInterface>
  makeFakeNetif(bool addNetworkAddresses = true)
  {
    using namespace ndn::net;

    static int counter = 0;
    ++counter;

    auto netif = netmon->makeNetworkInterface();
    netif->setIndex(1000 + counter);
    netif->setName("ethdummy" + std::to_string(counter));
    netif->setType(InterfaceType::ETHERNET);
    netif->setFlags(IFF_MULTICAST | IFF_UP);
    netif->setState(InterfaceState::RUNNING);
    netif->setMtu(1500);
    netif->setEthernetAddress(ethernet::Address{0x3e, 0x15, 0xc2, 0x8b, 0x65, 0x00});
    if (addNetworkAddresses) {
      netif->addNetworkAddress(NetworkAddress(AddressFamily::V4,
                                              ip::make_address_v4("192.168.2.1"),
                                              ip::make_address_v4("192.168.2.255"),
                                              24, AddressScope::GLOBAL, 0));
      netif->addNetworkAddress(NetworkAddress(AddressFamily::V6,
                                              ip::make_address_v6("2001:db8:2::1"),
                                              ip::make_address_v6("2001:db8:2::ffff:ffff:ffff:ffff"),
                                              64, AddressScope::GLOBAL, 0));
    }
    return netif;
  }

  /**
   * \brief Determine whether \p netif has at least one IP address of the given family.
   */
  static bool
  hasAddressFamily(const NetworkInterface& netif, ndn::net::AddressFamily af)
  {
    return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
                       [af] (const auto& a) { return a.getFamily() == af; });
  }

  /**
   * \brief Determine whether a UDP multicast face is created on \p netif.
   */
  static bool
  isFaceOnNetif(const Face& face, const NetworkInterface& netif)
  {
    auto faceIp = ip::make_address(face.getLocalUri().getHost());
    return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
                       [faceIp] (const auto& a) { return a.getIp() == faceIp; });
  }

protected:
  /** \brief MulticastUdpTransport-capable network interfaces (IPv4 + IPv6).
   *
   *  This should be used in test cases that do not depend on a specific address family
   */
  std::vector<shared_ptr<const NetworkInterface>> netifs;

  /** \brief MulticastUdpTransport-capable network interfaces (IPv4 only).
   */
  std::vector<shared_ptr<const NetworkInterface>> netifsV4;

  /** \brief MulticastUdpTransport-capable network interfaces (IPv6 only).
   */
  std::vector<shared_ptr<const NetworkInterface>> netifsV6;
};

class UdpFactoryMcastFixtureWithRealNetifs : public UdpFactoryMcastFixture
{
protected:
  UdpFactoryMcastFixtureWithRealNetifs()
  {
    copyRealNetifsToNetmon();
  }

  shared_ptr<Face>
  createMulticastFace(const std::string& localIp, const std::string& mcastIp, uint16_t mcastPort)
  {
    auto localAddress = ip::make_address(localIp);
    udp::Endpoint mcastEndpoint(ip::make_address(mcastIp), mcastPort);

    if (localAddress.is_v4()) {
      BOOST_ASSERT(!netifsV4.empty());
      return factory.createMulticastFace(*netifsV4.front(), localAddress, mcastEndpoint);
    }
    else {
      BOOST_ASSERT(!netifsV6.empty());
      return factory.createMulticastFace(*netifsV6.front(), localAddress, mcastEndpoint);
    }
  }

  /**
   * \brief Returns a non-loopback IP address suitable for the creation of a UDP multicast face.
   */
  ip::address
  findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily af) const
  {
    const auto& netifList = af == ndn::net::AddressFamily::V4 ? netifsV4 : netifsV6;
    for (const auto& netif : netifList) {
      for (const auto& a : netif->getNetworkAddresses()) {
        if (a.getFamily() == af && !a.getIp().is_loopback())
          return a.getIp();
      }
    }
    return {};
  }
};

#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
  do { \
    if (this->netifs.size() < (n)) { \
      BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
                                " or more MulticastUdpTransport-capable network interfaces"); \
      return; \
    } \
  } while (false)

#define SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(n) \
  do { \
    if (this->netifsV4.size() < (n)) { \
      BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
                                " or more IPv4 MulticastUdpTransport-capable network interfaces"); \
      return; \
    } \
  } while (false)

#define SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(n) \
  do { \
    if (this->netifsV6.size() < (n)) { \
      BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
                                " or more IPv6 MulticastUdpTransport-capable network interfaces"); \
      return; \
    } \
  } while (false)

BOOST_AUTO_TEST_SUITE(Face)
BOOST_AUTO_TEST_SUITE(TestUdpFactory)

BOOST_FIXTURE_TEST_SUITE(ProcessConfig, UdpFactoryFixture)

BOOST_AUTO_TEST_CASE(Defaults)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
    }
  )CONFIG";

  parseConfig(CONFIG, true);
  parseConfig(CONFIG, false);

  checkChannelListEqual(factory, {"udp4://0.0.0.0:6363", "udp6://[::]:6363"});
  for (const auto& ch : factory.getChannels()) {
    BOOST_CHECK(ch->isListening());
    BOOST_CHECK_EQUAL(ch->getDefaultMtu(), ndn::MAX_NDN_PACKET_SIZE);
  }
}

BOOST_AUTO_TEST_CASE(DisableListen)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        listen no
        port 7001
        mcast no
      }
    }
  )CONFIG";

  parseConfig(CONFIG, true);
  parseConfig(CONFIG, false);

  checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
  for (const auto& ch : factory.getChannels()) {
    BOOST_CHECK(!ch->isListening());
  }
}

BOOST_AUTO_TEST_CASE(DisableV4)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        port 7001
        enable_v4 no
        enable_v6 yes
        unicast_mtu 1452
        mcast no
      }
    }
  )CONFIG";

  parseConfig(CONFIG, true);
  parseConfig(CONFIG, false);

  checkChannelListEqual(factory, {"udp6://[::]:7001"});
  for (const auto& ch : factory.getChannels()) {
    BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
  }
}

BOOST_AUTO_TEST_CASE(DisableV6)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        port 7001
        enable_v4 yes
        enable_v6 no
        unicast_mtu 1452
        mcast no
      }
    }
  )CONFIG";

  parseConfig(CONFIG, true);
  parseConfig(CONFIG, false);

  checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
  for (const auto& ch : factory.getChannels()) {
    BOOST_CHECK_EQUAL(ch->getDefaultMtu(), 1452);
  }
}

BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpFactoryMcastFixtureWithRealNetifs)
{
  const std::string CONFIG_WITH_MCAST = R"CONFIG(
    face_system
    {
      udp
      {
        mcast yes
      }
    }
  )CONFIG";
  const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
    face_system
    {
      udp
      {
        mcast no
      }
    }
  )CONFIG";

  parseConfig(CONFIG_WITHOUT_MCAST, false);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__

  parseConfig(CONFIG_WITH_MCAST, false);
  g_io.poll();
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), netifsV4.size());
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), netifsV6.size());

  BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
  for (const auto* face : this->listUdp4McastFaces()) {
    BOOST_REQUIRE(face->getChannel().lock());
    BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp4");
  }

  for (const auto* face : this->listUdp6McastFaces()) {
    BOOST_REQUIRE(face->getChannel().lock());
    BOOST_CHECK_EQUAL(face->getChannel().lock()->getUri().getScheme(), "udp6");
  }

  parseConfig(CONFIG_WITHOUT_MCAST, false);
  g_io.poll();
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
}

BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);

  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_ad_hoc yes
      }
    }
  )CONFIG";

  parseConfig(CONFIG, false);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV4.size());
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces(ndn::nfd::LINK_TYPE_AD_HOC).size(), netifsV6.size());
}

BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV4, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);

  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group 239.66.30.1
        mcast_port 7011
      }
    }
  )CONFIG";
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group 239.66.30.2
        mcast_port 7012
      }
    }
  )CONFIG";

  parseConfig(CONFIG1, false);
  g_io.poll();
  auto udpMcastFaces = this->listUdp4McastFaces();
  BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
  BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.1:7011"));

  parseConfig(CONFIG2, false);
  g_io.poll();
  udpMcastFaces = this->listUdp4McastFaces();
  BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV4.size());
  BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(), FaceUri("udp4://239.66.30.2:7012"));
}

BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpointV6, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);

  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group_v6 ff02::1101
        mcast_port_v6 7011
      }
    }
  )CONFIG";
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group_v6 ff02::1102
        mcast_port_v6 7012
      }
    }
  )CONFIG";

  parseConfig(CONFIG1, false);
  g_io.poll();
  auto udpMcastFaces = this->listUdp6McastFaces();
  BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
  auto uri = udpMcastFaces.front()->getRemoteUri();
  BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
  // check the address ignoring the scope id
  auto addr = ip::make_address_v6(uri.getHost());
  addr.scope_id(0);
  BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1101"));
  BOOST_CHECK_EQUAL(uri.getPort(), "7011");

  parseConfig(CONFIG2, false);
  g_io.poll();
  udpMcastFaces = this->listUdp6McastFaces();
  BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifsV6.size());
  uri = udpMcastFaces.front()->getRemoteUri();
  BOOST_CHECK_EQUAL(uri.getScheme(), "udp6");
  // check the address ignoring the scope id
  addr = ip::make_address_v6(uri.getHost());
  addr.scope_id(0);
  BOOST_CHECK_EQUAL(addr, ip::make_address_v6("ff02::1102"));
  BOOST_CHECK_EQUAL(uri.getPort(), "7012");
}

BOOST_FIXTURE_TEST_CASE(Whitelist, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);

  std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        whitelist
        {
          ifname %ifname
        }
      }
    }
  )CONFIG";
  boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());

  parseConfig(CONFIG, false);

  auto udpMcastFaces = this->listUdp4McastFaces();
  BOOST_CHECK_LE(udpMcastFaces.size(), 1);
  auto udpMcastFacesV6 = this->listUdp6McastFaces();
  BOOST_CHECK_LE(udpMcastFacesV6.size(), 1);
  udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
  BOOST_CHECK_GE(udpMcastFaces.size(), 1);
  BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
                          [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
}

BOOST_FIXTURE_TEST_CASE(Blacklist, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);

  std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        blacklist
        {
          ifname %ifname
        }
      }
    }
  )CONFIG";
  boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());

  parseConfig(CONFIG, false);

  auto udpMcastFaces = this->listUdp4McastFaces();
  if (!netifsV4.empty())
    BOOST_CHECK_GE(udpMcastFaces.size(), netifsV4.size() - 1);
  auto udpMcastFacesV6 = this->listUdp6McastFaces();
  if (!netifsV6.empty())
    BOOST_CHECK_GE(udpMcastFacesV6.size(), netifsV6.size() - 1);
  udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
  BOOST_CHECK_LT(udpMcastFaces.size(), netifsV4.size() + netifsV6.size());
  BOOST_CHECK(std::none_of(udpMcastFaces.begin(), udpMcastFaces.end(),
                           [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));
}

BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);

  std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        whitelist
        {
          ifname %ifname
        }
      }
    }
  )CONFIG";
  std::string CONFIG2 = CONFIG1;
  boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
  boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());

  parseConfig(CONFIG1, false);
  g_io.poll();

  auto udpMcastFaces = this->listUdp4McastFaces();
  auto udpMcastFacesV6 = this->listUdp6McastFaces();
  udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
  BOOST_CHECK_GE(udpMcastFaces.size(), 1);
  BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
                          [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.front()); }));

  parseConfig(CONFIG2, false);
  g_io.poll();

  udpMcastFaces = this->listUdp4McastFaces();
  udpMcastFacesV6 = this->listUdp6McastFaces();
  udpMcastFaces.insert(udpMcastFaces.end(), udpMcastFacesV6.begin(), udpMcastFacesV6.end());
  BOOST_CHECK_GE(udpMcastFaces.size(), 1);
  BOOST_CHECK(std::all_of(udpMcastFaces.begin(), udpMcastFaces.end(),
                          [this] (const auto* face) { return isFaceOnNetif(*face, *netifs.back()); }));
}

BOOST_AUTO_TEST_CASE(Omitted)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
    }
  )CONFIG";

  parseConfig(CONFIG, true);
  parseConfig(CONFIG, false);

  BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
  BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
  BOOST_CHECK_EQUAL(this->listFacesByScheme("udp6", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
}

BOOST_AUTO_TEST_CASE(AllDisabled)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        enable_v4 no
        enable_v6 no
        mcast no
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadListen)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        listen hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadPort)
{
  // not a number
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        port hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  // negative number
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        port -1
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);

  // out of range
  const std::string CONFIG3 = R"CONFIG(
    face_system
    {
      udp
      {
        port 65536
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadIdleTimeout)
{
  // not a number
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        idle_timeout hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  // negative number
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        idle_timeout -15
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMtu)
{
  // not a number
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        unicast_mtu hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  // underflow
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        unicast_mtu 63
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);

  // underflow
  const std::string CONFIG3 = R"CONFIG(
    face_system
    {
      udp
      {
        unicast_mtu 8801
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMcast)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        mcast hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMcastGroupV4)
{
  // not an address
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  // non-multicast address
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group 10.0.0.1
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);

  // wrong address family
  const std::string CONFIG3 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group ff02::1234
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
{
  // not an address
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group_v6 foo
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  // non-multicast address
  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group_v6 fe80::1234
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);

  // wrong address family
  const std::string CONFIG3 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_group_v6 224.0.23.170
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMcastPortV4)
{
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_port hey
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_port 99999
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(BadMcastPortV6)
{
  const std::string CONFIG1 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_port_v6 bar
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);

  const std::string CONFIG2 = R"CONFIG(
    face_system
    {
      udp
      {
        mcast_port_v6 99999
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_CASE(UnknownOption)
{
  const std::string CONFIG = R"CONFIG(
    face_system
    {
      udp
      {
        hello
      }
    }
  )CONFIG";

  BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
  BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
}

BOOST_AUTO_TEST_SUITE_END() // ProcessConfig

BOOST_FIXTURE_TEST_CASE(GetChannels, UdpFactoryFixture)
{
  BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);

  std::set<std::string> expected;
  expected.insert(createChannel("127.0.0.1", 20070)->getUri().toString());
  expected.insert(createChannel("127.0.0.1", 20071)->getUri().toString());
  expected.insert(createChannel("::1", 20071)->getUri().toString());
  checkChannelListEqual(factory, expected);
}

BOOST_FIXTURE_TEST_CASE(CreateChannel, UdpFactoryMcastFixtureWithRealNetifs)
{
  auto channel1 = createChannel("127.0.0.1", 20070);
  auto channel1a = createChannel("127.0.0.1", 20070);
  BOOST_CHECK_EQUAL(channel1, channel1a);
  BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
  BOOST_CHECK_EQUAL(factory.getChannels().size(), 1);

  auto channel2 = createChannel("127.0.0.1", 20071);
  BOOST_CHECK_NE(channel1, channel2);
  BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);

  auto channel3 = createChannel("::1", 20071);
  BOOST_CHECK_NE(channel2, channel3);
  BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
  BOOST_CHECK_EQUAL(factory.getChannels().size(), 3);

#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);

  // createChannel with a local endpoint that has already been allocated to a UDP multicast face
  if (!netifsV4.empty()) {
    auto mcastFace = createMulticastFace("127.0.0.1", "224.0.0.254", 20072);
    BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", 20072), UdpFactory::Error,
                          [] (const UdpFactory::Error& e) {
                            return e.what() == "Cannot create UDP channel on 127.0.0.1:20072, "
                                               "endpoint already allocated to a UDP multicast face"s;
                          });
  }
  if (!netifsV6.empty()) {
    auto mcastFace = createMulticastFace("::1", "ff02::114", 20072);
    BOOST_CHECK_EXCEPTION(createChannel("::1", 20072), UdpFactory::Error,
                          [] (const UdpFactory::Error& e) {
                            return e.what() == "Cannot create UDP channel on [::1]:20072, "
                                               "endpoint already allocated to a UDP multicast face"s;
                          });
  }
}

BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV4, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);

  auto multicastFace1  = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
  auto multicastFace1a = createMulticastFace("127.0.0.1", "224.0.0.254", 20070);
  auto multicastFace2  = createMulticastFace("127.0.0.1", "224.0.0.254", 20030);
  BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
  BOOST_CHECK_NE(multicastFace1, multicastFace2);

  auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V4);
  if (!address.is_unspecified()) {
    auto multicastFace3  = createMulticastFace(address.to_string(), "224.0.0.254", 20070);
    BOOST_CHECK_NE(multicastFace1, multicastFace3);
    BOOST_CHECK_NE(multicastFace2, multicastFace3);
  }

  // create with a local endpoint already used by a channel
  auto channel = createChannel("127.0.0.1", 20071);
  BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.254", 20071), UdpFactory::Error,
                        [] (const UdpFactory::Error& e) {
                          return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20071, "
                                             "endpoint already allocated to a UDP channel"s;
                        });

  // create with a local endpoint already used by a multicast face on a different multicast group
  BOOST_CHECK_EXCEPTION(createMulticastFace("127.0.0.1", "224.0.0.42", 20070), UdpFactory::Error,
                        [] (const UdpFactory::Error& e) {
                          return e.what() == "Cannot create UDP multicast face on 127.0.0.1:20070, "
                                             "endpoint already allocated to a different UDP multicast face"s;
                        });
}

BOOST_FIXTURE_TEST_CASE(CreateMulticastFaceV6, UdpFactoryMcastFixtureWithRealNetifs)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);

  auto multicastFace1  = createMulticastFace("::1", "ff02::114", 20070);
  auto multicastFace1a = createMulticastFace("::1", "ff02::114", 20070);
  auto multicastFace2  = createMulticastFace("::1", "ff02::114", 20030);
  BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
  BOOST_CHECK_NE(multicastFace1, multicastFace2);

  auto address = findNonLoopbackAddressForMulticastFace(ndn::net::AddressFamily::V6);
  if (!address.is_unspecified()) {
    auto multicastFace3  = createMulticastFace(address.to_string(), "ff02::114", 20070);
    BOOST_CHECK_NE(multicastFace1, multicastFace3);
    BOOST_CHECK_NE(multicastFace2, multicastFace3);
  }

  // create with a local endpoint already used by a channel
  auto channel = createChannel("::1", 20071);
  BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::114", 20071), UdpFactory::Error,
                        [] (const UdpFactory::Error& e) {
                          return e.what() == "Cannot create UDP multicast face on [::1]:20071, "
                                             "endpoint already allocated to a UDP channel"s;
                        });

  // create with a local endpoint already used by a multicast face on a different multicast group
  BOOST_CHECK_EXCEPTION(createMulticastFace("::1", "ff02::42", 20070), UdpFactory::Error,
                        [] (const UdpFactory::Error& e) {
                          return e.what() == "Cannot create UDP multicast face on [::1]:20070, "
                                             "endpoint already allocated to a different UDP multicast face"s;
                        });
}

BOOST_FIXTURE_TEST_CASE(CreateFace, UdpFactoryFixture)
{
  createFace(factory,
             FaceUri("udp4://127.0.0.1:6363"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});

  createChannel("127.0.0.1", 20071);

  createFace(factory,
             FaceUri("udp4://127.0.0.1:6363"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:6363"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20072"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20073"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, true, false},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20073"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, {}, false, false, true},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20074"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, 1000, false, false, false},
             {CreateFaceExpectedResult::SUCCESS, 0, ""});
}

BOOST_FIXTURE_TEST_CASE(CreateFaceInvalidRequest, UdpFactoryFixture)
{
  createFace(factory,
             FaceUri("udp4://127.0.0.1:20072"),
             FaceUri("udp4://127.0.0.1:20071"),
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::FAILURE, 406,
              "Unicast UDP faces cannot be created with a LocalUri"});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20072"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::FAILURE, 406,
              "Outgoing UDP faces do not support on-demand persistency"});

  createFace(factory,
             FaceUri("udp4://233.252.0.1:23252"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, false, false, false},
             {CreateFaceExpectedResult::FAILURE, 406,
              "Cannot create multicast UDP faces"});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20072"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, {}, true, false, false},
             {CreateFaceExpectedResult::FAILURE, 406,
              "Local fields can only be enabled on faces with local scope"});

  createFace(factory,
             FaceUri("udp4://127.0.0.1:20072"),
             {},
             {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, 42, false, false, false},
             {CreateFaceExpectedResult::FAILURE, 406,
              "Override MTU cannot be less than 64"});
}

BOOST_FIXTURE_TEST_SUITE(OnInterfaceAdded, UdpFactoryMcastFixture)

BOOST_AUTO_TEST_CASE(EligibleV4)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V4_NETIF_COUNT_LT(1);

  parseConfig(R"CONFIG(
    face_system
    {
      udp
    }
  )CONFIG", false);
  g_io.poll();
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

  netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV4.front()));
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 1);
  BOOST_CHECK_LE(this->listUdp6McastFaces().size(), 1);
}

BOOST_AUTO_TEST_CASE(EligibleV6)
{
#ifdef __linux__
  // need superuser privileges to create multicast faces on Linux
  SKIP_IF_NOT_SUPERUSER();
#endif // __linux__
  SKIP_IF_UDP_MCAST_V6_NETIF_COUNT_LT(1);

  parseConfig(R"CONFIG(
    face_system
    {
      udp
    }
  )CONFIG", false);
  g_io.poll();
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

  netmon->addInterface(const_pointer_cast<NetworkInterface>(netifsV6.front()));
  BOOST_CHECK_LE(this->listUdp4McastFaces().size(), 1);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 1);
}

BOOST_AUTO_TEST_CASE(EligibleFailure)
{
  parseConfig(R"CONFIG(
    face_system
    {
      udp
    }
  )CONFIG", false);
  g_io.poll();

  // Add a fake interface that satisfies the multicast criteria.
  netmon->addInterface(this->makeFakeNetif());
  // Creation of multicast faces fails because the interface does not actually exist.
  // This test is to ensure that the factory handles failures gracefully.
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
}

BOOST_AUTO_TEST_CASE(Ineligible)
{
  parseConfig(R"CONFIG(
    face_system
    {
      udp
    }
  )CONFIG", false);
  g_io.poll();

  // netif is down
  auto netif = this->makeFakeNetif();
  netif->setFlags(netif->getFlags() & ~IFF_UP);
  netmon->addInterface(netif);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

  // netif is loopback
  netif = this->makeFakeNetif();
  netif->setFlags(netif->getFlags() | IFF_LOOPBACK);
  netmon->addInterface(netif);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

  // netif cannot multicast
  netif = this->makeFakeNetif();
  netif->setFlags(netif->getFlags() & ~IFF_MULTICAST);
  netmon->addInterface(netif);
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);

  // no viable IP address
  netmon->addInterface(this->makeFakeNetif(false));
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
}

BOOST_AUTO_TEST_CASE(Disabled)
{
  SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);

  parseConfig("", false);
  g_io.poll();

  netmon->addInterface(const_pointer_cast<NetworkInterface>(netifs.front()));
  BOOST_CHECK_EQUAL(this->listUdp4McastFaces().size(), 0);
  BOOST_CHECK_EQUAL(this->listUdp6McastFaces().size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // OnInterfaceAdded

BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
BOOST_AUTO_TEST_SUITE_END() // Face

} // namespace nfd::tests
