/* -*- 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/tcp-channel-factory.hpp"
#include "core/scheduler.hpp"

#include <ndn-cpp-dev/security/key-chain.hpp>

#include <boost/test/unit_test.hpp>

namespace nfd {

BOOST_AUTO_TEST_SUITE(FaceTcp)

BOOST_AUTO_TEST_CASE(ChannelMap)
{
  boost::asio::io_service io;
  TcpChannelFactory factory(io);
  
  shared_ptr<TcpChannel> channel1 = factory.create("127.0.0.1", "20070");
  shared_ptr<TcpChannel> channel1a = factory.create("127.0.0.1", "20070");
  BOOST_CHECK_EQUAL(channel1, channel1a);
  
  shared_ptr<TcpChannel> channel2 = factory.create("127.0.0.1", "20071");
  BOOST_CHECK_NE(channel1, channel2);
}

class EndToEndFixture
{
public:
  void
  channel1_onFaceCreated(const shared_ptr<TcpFace>& newFace)
  {
    BOOST_CHECK(!static_cast<bool>(m_face1));
    m_face1 = newFace;
    m_face1->onReceiveInterest +=
      bind(&EndToEndFixture::face1_onReceiveInterest, this, _1);
    m_face1->onReceiveData +=
      bind(&EndToEndFixture::face1_onReceiveData, this, _1);

    this->afterIo();
  }

  void
  channel1_onConnectFailed(const std::string& reason)
  {
    BOOST_CHECK_MESSAGE(false, reason);

    this->afterIo();
  }
  
  void
  face1_onReceiveInterest(const Interest& interest)
  {
    m_face1_receivedInterests.push_back(interest);

    this->afterIo();
  }
  
  void
  face1_onReceiveData(const Data& data)
  {
    m_face1_receivedDatas.push_back(data);

    this->afterIo();
  }

  void
  channel2_onFaceCreated(const shared_ptr<TcpFace>& newFace)
  {
    BOOST_CHECK(!static_cast<bool>(m_face2));
    m_face2 = newFace;
    m_face2->onReceiveInterest +=
      bind(&EndToEndFixture::face2_onReceiveInterest, this, _1);
    m_face2->onReceiveData +=
      bind(&EndToEndFixture::face2_onReceiveData, this, _1);

    this->afterIo();
  }

  void
  channel2_onConnectFailed(const std::string& reason)
  {
    BOOST_CHECK_MESSAGE(false, reason);

    this->afterIo();
  }
  
  void
  face2_onReceiveInterest(const Interest& interest)
  {
    m_face2_receivedInterests.push_back(interest);

    this->afterIo();
  }
  
  void
  face2_onReceiveData(const Data& data)
  {
    m_face2_receivedDatas.push_back(data);

    this->afterIo();
  }

  void
  abortTestCase(const std::string& message)
  {
    m_ioService.stop();
    BOOST_FAIL(message);
  }
  
private:
  void
  afterIo()
  {
    if (--m_ioRemaining <= 0) m_ioService.stop();
  }

public:
  boost::asio::io_service m_ioService;

  int m_ioRemaining;

  shared_ptr<TcpFace> m_face1;
  std::vector<Interest> m_face1_receivedInterests;
  std::vector<Data> m_face1_receivedDatas;
  shared_ptr<TcpFace> m_face2;
  std::vector<Interest> m_face2_receivedInterests;
  std::vector<Data> m_face2_receivedDatas;
};


BOOST_FIXTURE_TEST_CASE(EndToEnd, EndToEndFixture)
{
  TcpChannelFactory factory(m_ioService);
  Scheduler scheduler(m_ioService); // to limit the amount of time the test may take

  EventId abortEvent =
    scheduler.scheduleEvent(time::seconds(1),
                            bind(&EndToEndFixture::abortTestCase, this,
                                 "TcpChannel error: cannot connect or cannot accept connection"));
  
  shared_ptr<TcpChannel> channel1 = factory.create("127.0.0.1", "20070");
  shared_ptr<TcpChannel> channel2 = factory.create("127.0.0.1", "20071");
  
  channel1->listen(bind(&EndToEndFixture::channel1_onFaceCreated,   this, _1),
                   bind(&EndToEndFixture::channel1_onConnectFailed, this, _1));
  
  channel2->connect("127.0.0.1", "20070",
                    bind(&EndToEndFixture::channel2_onFaceCreated, this, _1),
                    bind(&EndToEndFixture::channel2_onConnectFailed, this, _1),
                    time::milliseconds(100)); // very short timeout

  m_ioRemaining = 2;
  m_ioService.run();
  m_ioService.reset();
  scheduler.cancelEvent(abortEvent);

  BOOST_REQUIRE(static_cast<bool>(m_face1));
  BOOST_REQUIRE(static_cast<bool>(m_face2));
    
  abortEvent =
    scheduler.scheduleEvent(time::seconds(1),
                            bind(&EndToEndFixture::abortTestCase, this,
                                 "TcpChannel error: cannot send or receive Interest/Data packets"));

  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);
  
  m_face1->sendInterest(interest1);
  m_face1->sendData    (data1    );
  m_face2->sendInterest(interest2);
  m_face2->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 nfd
