/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2018,  University of Memphis.
 *
 * This file is part of ndn-tools (Named Data Networking Essential Tools).
 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
 *
 * ndn-tools 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.
 *
 * ndn-tools 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
 * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "tools/dump/ndndump.hpp"

#include "tests/identity-management-fixture.hpp"
#include "tests/test-common.hpp"

#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/net/ethernet.hpp>

namespace ndn {
namespace dump {
namespace tests {

using namespace ndn::tests;

class StdCoutRedirector
{
public:
  StdCoutRedirector(std::ostream& os)
  {
    // Redirect std::cout to the specified output stream
    originalBuffer = std::cout.rdbuf(os.rdbuf());
  }

  ~StdCoutRedirector()
  {
    // Revert state for std::cout
    std::cout.rdbuf(originalBuffer);
  }

private:
  std::streambuf* originalBuffer;
};

class NdnDumpFixture : public IdentityManagementFixture
{
protected:
  NdnDumpFixture()
  {
    dump.m_dataLinkType = DLT_EN10MB;
  }

  template<typename Packet>
  void
  receive(const Packet& packet)
  {
    EncodingBuffer buffer(packet.wireEncode());
    receive(buffer);
  }

  void
  receive(EncodingBuffer& buffer)
  {
    ethernet::Address host;

    // Ethernet header
    uint16_t type = htons(ethernet::ETHERTYPE_NDN);
    buffer.prependByteArray(reinterpret_cast<const uint8_t*>(&type), ethernet::TYPE_LEN);
    buffer.prependByteArray(host.data(), host.size());
    buffer.prependByteArray(host.data(), host.size());

    pcap_pkthdr pkthdr{};
    pkthdr.caplen = pkthdr.len = buffer.size();

    {
      StdCoutRedirector redirect(output);
      dump.printPacket(&pkthdr, buffer.buf());
    }
  }

protected:
  NdnDump dump;
  boost::test_tools::output_test_stream output;
};

BOOST_AUTO_TEST_SUITE(Dump)
BOOST_FIXTURE_TEST_SUITE(TestNdnDump, NdnDumpFixture)

BOOST_AUTO_TEST_CASE(CaptureInterest)
{
  Interest interest("/test");
  interest.setNonce(0);

  this->receive(interest);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, INTEREST: /test?ndn.Nonce=0\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureData)
{
  Data data("/test");
  m_keyChain.sign(data);

  this->receive(data);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, DATA: /test\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureNack)
{
  Interest interest("/test");
  interest.setNonce(0);
  lp::Nack nack(interest);
  nack.setReason(lp::NackReason::DUPLICATE);
  lp::Packet lpPacket(interest.wireEncode());
  lpPacket.add<lp::NackField>(nack.getHeader());

  this->receive(lpPacket);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, NACK: Duplicate, /test?ndn.Nonce=0\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureLpFragment)
{
  const uint8_t data[10] = {
    0x06, 0x08, // Data packet
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  };

  Buffer buffer(data, 4);
  lp::Packet lpPacket;
  lpPacket.add<lp::FragmentField>(std::make_pair(buffer.begin(), buffer.end()));
  lpPacket.add<lp::FragIndexField>(0);
  lpPacket.add<lp::FragCountField>(2);
  lpPacket.add<lp::SequenceField>(1000);

  this->receive(lpPacket);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, NDNLPv2-FRAGMENT\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureIdleLpPacket)
{
  lp::Packet lpPacket;

  this->receive(lpPacket);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, NDNLPv2-IDLE\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureIncompletePacket)
{
  const uint8_t interest[] = {
  0x05, 0x0E, // Interest
    0x07, 0x06, // Name
      0x08, 0x04, // NameComponent
        0x74, 0x65, 0x73, 0x74,
    0x0a, 0x04, // Nonce
      0x00, 0x00, 0x00, 0x01
  };

  EncodingBuffer buffer;
  buffer.prependByteArray(interest, 4);

  this->receive(buffer);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, INCOMPLETE-PACKET, size: 4\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(CaptureUnknownNetworkPacket)
{
  EncodingBuffer buffer(encoding::makeEmptyBlock(tlv::Name));

  this->receive(buffer);

  const std::string expected = "0.000000 Tunnel Type: EthernetFrame, UNKNOWN-NETWORK-PACKET\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_CASE(PcapTraceFile)
{
  dump.inputFile = "tests/dump/nack.pcap";
  dump.pcapFilter = "";

  {
    StdCoutRedirector redirect(output);
    dump.run();
  }

  const std::string expected =
    "1456768916.467099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=2581361680\n"
    "1456768916.567099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=4138343109\n"
    "1456768916.667099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: UDP, INTEREST: /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=4034910304\n"
    "1456768916.767099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: Congestion, /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=2581361680\n"
    "1456768916.867099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: Duplicate, /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=4138343109\n"
    "1456768916.967099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: UDP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=4034910304\n"
    "1456768917.067099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=3192497423\n"
    "1456768917.267099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: Congestion, /producer/nack/congestion?ndn.MustBeFresh=1&ndn.Nonce=3192497423\n"
    "1456768917.367099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=522390724\n"
    "1456768917.567099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: Duplicate, /producer/nack/duplicate?ndn.MustBeFresh=1&ndn.Nonce=522390724\n"
    "1456768917.767099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=2002441365\n"
    "1456768917.967099 From: 1.0.0.1, To: 1.0.0.2, Tunnel Type: TCP, INTEREST: /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=3776824408\n"
    "1456768918.067099 From: 1.0.0.2, To: 1.0.0.1, Tunnel Type: TCP, NACK: None, /producer/nack/no-reason?ndn.MustBeFresh=1&ndn.Nonce=3776824408\n";
  BOOST_CHECK(output.is_equal(expected));
}

BOOST_AUTO_TEST_SUITE_END() // TestNdnDump
BOOST_AUTO_TEST_SUITE_END() // Dump

} // namespace tests
} // namespace dump
} // namespace ndn
