/* -*- 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 "face/ethernet-factory.hpp"
#include <ndn-cpp-dev/security/key-chain.hpp>

#include "tests/test-common.hpp"

namespace nfd {
namespace tests {

BOOST_FIXTURE_TEST_SUITE(FaceEthernet, BaseFixture)

BOOST_AUTO_TEST_CASE(MulticastFacesMap)
{
  EthernetFactory factory;

  std::vector<ethernet::Endpoint> interfaces = EthernetFactory::findAllInterfaces();
  if (interfaces.size() > 0)
    {
      shared_ptr<EthernetFace> face1;
      BOOST_REQUIRE_NO_THROW(face1 =
                             factory.createMulticastFace(interfaces[0],
                                                     ethernet::getBroadcastAddress()));
      shared_ptr<EthernetFace> face1bis;
      BOOST_REQUIRE_NO_THROW(face1bis =
                             factory.createMulticastFace(interfaces[0],
                                                         ethernet::getBroadcastAddress()));
      BOOST_CHECK_EQUAL(face1, face1bis);

      if (interfaces.size() > 1)
        {
          shared_ptr<EthernetFace> face2;
          BOOST_REQUIRE_NO_THROW(face2 =
                                 factory.createMulticastFace(interfaces[1],
                                                             ethernet::getBroadcastAddress()));
          BOOST_CHECK_NE(face1, face2);
        }
      else
        {
          BOOST_WARN_MESSAGE(interfaces.size() < 2, "Cannot test second EthernetFace creation, "
                             "only one interface available for pcap");
        }

      shared_ptr<EthernetFace> face3;
      BOOST_REQUIRE_NO_THROW(face3 =
                             factory.createMulticastFace(interfaces[0],
                                                         ethernet::getDefaultMulticastAddress()));
      BOOST_CHECK_NE(face1, face3);
    }
  else
    {
      BOOST_WARN_MESSAGE(interfaces.empty(), "Cannot perform MulticastFacesMap tests, "
                         "no interfaces are available for pcap");
    }
}

BOOST_AUTO_TEST_CASE(SendPacket)
{
  EthernetFactory factory;

  std::vector<ethernet::Endpoint> interfaces = EthernetFactory::findAllInterfaces();
  if (interfaces.empty())
    {
      BOOST_WARN_MESSAGE(interfaces.empty(),
                         "No interfaces are available for pcap, cannot perform SendPacket test");
      return;
    }

  shared_ptr<EthernetFace> face =
    factory.createMulticastFace(interfaces[0], ethernet::getDefaultMulticastAddress());

  BOOST_REQUIRE(static_cast<bool>(face));
  BOOST_CHECK_EQUAL(face->isLocal(), false);

  Interest interest1("ndn:/TpnzGvW9R");
  Data     data1    ("ndn:/KfczhUqVix");
  data1.setContent(0, 0);
  Interest interest2("ndn:/QWiIMfj5sL");
  Data     data2    ("ndn:/XNBV796f");
  data2.setContent(0, 0);

  ndn::SignatureSha256WithRsa fakeSignature;
  fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue, reinterpret_cast<const uint8_t*>(0), 0));

  // set fake signature on data1 and data2
  data1.setSignature(fakeSignature);
  data2.setSignature(fakeSignature);

  BOOST_CHECK_NO_THROW(face->sendInterest(interest1));
  BOOST_CHECK_NO_THROW(face->sendData    (data1    ));
  BOOST_CHECK_NO_THROW(face->sendInterest(interest2));
  BOOST_CHECK_NO_THROW(face->sendData    (data2    ));

//  m_ioRemaining = 4;
//  m_ioService.run();
//  m_ioService.reset();

//  BOOST_REQUIRE_EQUAL(m_face1_receivedInterests.size(), 1);
//  BOOST_REQUIRE_EQUAL(m_face1_receivedDatas    .size(), 1);
//  BOOST_REQUIRE_EQUAL(m_face2_receivedInterests.size(), 1);
//  BOOST_REQUIRE_EQUAL(m_face2_receivedDatas    .size(), 1);

//  BOOST_CHECK_EQUAL(m_face1_receivedInterests[0].getName(), interest2.getName());
//  BOOST_CHECK_EQUAL(m_face1_receivedDatas    [0].getName(), data2.getName());
//  BOOST_CHECK_EQUAL(m_face2_receivedInterests[0].getName(), interest1.getName());
//  BOOST_CHECK_EQUAL(m_face2_receivedDatas    [0].getName(), data1.getName());
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace nfd
