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

#include <boost/mpl/vector.hpp>

namespace nfd::tests {

using namespace nfd::face;

BOOST_AUTO_TEST_SUITE(Face)
BOOST_AUTO_TEST_SUITE(TestMulticastUdpTransport)

using MulticastUdpTransportFixtures = boost::mpl::vector<
  IpTransportFixture<MulticastUdpTransportFixture, AddressFamily::V4, AddressScope::Global, MulticastInterface::Yes>,
  IpTransportFixture<MulticastUdpTransportFixture, AddressFamily::V6, AddressScope::LinkLocal, MulticastInterface::Yes>,
  IpTransportFixture<MulticastUdpTransportFixture, AddressFamily::V6, AddressScope::Global, MulticastInterface::Yes>
>;

BOOST_FIXTURE_TEST_CASE_TEMPLATE(StaticProperties, T, MulticastUdpTransportFixtures, T)
{
  TRANSPORT_TEST_INIT();

  checkStaticPropertiesInitialized(*this->transport);

  BOOST_CHECK_EQUAL(this->transport->getLocalUri(), FaceUri(udp::endpoint(this->address, this->txPort)));
  BOOST_CHECK_EQUAL(this->transport->getRemoteUri(), FaceUri(this->mcastEp));
  BOOST_CHECK_EQUAL(this->transport->getScope(), ndn::nfd::FACE_SCOPE_NON_LOCAL);
  BOOST_CHECK_EQUAL(this->transport->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERMANENT);
  BOOST_CHECK_EQUAL(this->transport->getLinkType(), ndn::nfd::LINK_TYPE_MULTI_ACCESS);
  BOOST_CHECK_EQUAL(this->transport->getMtu(),
                    this->addressFamily == AddressFamily::V4 ? (65535 - 60 - 8) : (65535 - 8));
  BOOST_CHECK_GT(this->transport->getSendQueueCapacity(), 0);
}

using MulticastUdpTransportFixtureWithAddress = IpTransportFixture<MulticastUdpTransportFixture,
                                                                   AddressFamily::Any,
                                                                   AddressScope::LinkLocal,
                                                                   MulticastInterface::Yes>;

BOOST_FIXTURE_TEST_CASE(PersistencyChange, MulticastUdpTransportFixtureWithAddress)
{
  TRANSPORT_TEST_INIT();

  BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND), false);
  BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERSISTENT), false);
  BOOST_CHECK_EQUAL(transport->canChangePersistencyTo(ndn::nfd::FACE_PERSISTENCY_PERMANENT), true);
}

BOOST_FIXTURE_TEST_CASE_TEMPLATE(ReceiveFromMultipleEndpoints, T, MulticastUdpTransportFixtures, T)
{
  TRANSPORT_TEST_INIT();

  // we need a second remote tx socket for this test case
  udp::socket remoteSockTx2(this->g_io);
  MulticastUdpTransport::openTxSocket(remoteSockTx2, udp::endpoint(this->address, 0), nullptr, true);

  Block pkt1 = ndn::encoding::makeStringBlock(300, "hello");
  ndn::Buffer buf1(pkt1.begin(), pkt1.end());
  this->remoteWrite(buf1);

  Block pkt2 = ndn::encoding::makeStringBlock(301, "world");
  ndn::Buffer buf2(pkt2.begin(), pkt2.end());
  this->remoteWrite(buf2);

  BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 2);
  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, buf1.size() + buf2.size());
  BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);

  BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 2);
  BOOST_CHECK(this->receivedPackets->at(0).endpoint == this->receivedPackets->at(1).endpoint);
  BOOST_CHECK(std::holds_alternative<nfd::udp::Endpoint>(this->receivedPackets->at(0).endpoint));

  this->sendToGroup(remoteSockTx2, buf1);
  this->sendToGroup(remoteSockTx2, buf2);
  this->limitedIo.defer(1_s);

  BOOST_CHECK_EQUAL(this->transport->getCounters().nInPackets, 4);
  BOOST_CHECK_EQUAL(this->transport->getCounters().nInBytes, 2 * buf1.size() + 2 * buf2.size());
  BOOST_CHECK_EQUAL(this->transport->getState(), TransportState::UP);

  BOOST_REQUIRE_EQUAL(this->receivedPackets->size(), 4);
  EndpointId epId2(remoteSockTx2.local_endpoint());
  BOOST_CHECK(this->receivedPackets->at(0).endpoint != epId2);
  BOOST_CHECK(this->receivedPackets->at(1).endpoint != epId2);
  BOOST_CHECK(this->receivedPackets->at(2).endpoint == epId2);
  BOOST_CHECK(this->receivedPackets->at(3).endpoint == epId2);
}

BOOST_AUTO_TEST_SUITE_END() // TestMulticastUdpTransport
BOOST_AUTO_TEST_SUITE_END() // Face

} // namespace nfd::tests
