/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2023 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library 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 Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "ndn-cxx/lp/packet.hpp"
#include "ndn-cxx/prefix-announcement.hpp"

#include "tests/key-chain-fixture.hpp"
#include "tests/test-common.hpp"

namespace ndn {
namespace lp {
namespace tests {

BOOST_AUTO_TEST_SUITE(Lp)
BOOST_AUTO_TEST_SUITE(TestPacket)

BOOST_AUTO_TEST_CASE(FieldAccess)
{
  Packet packet;

  BOOST_CHECK(packet.empty());
  BOOST_CHECK(!packet.has<FragIndexField>());
  BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 0);

  packet.set<FragIndexField>(1234);
  BOOST_CHECK(!packet.empty());
  BOOST_CHECK(packet.has<FragIndexField>());
  BOOST_CHECK_THROW(packet.add<FragIndexField>(5678), std::invalid_argument);
  BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 1);
  BOOST_CHECK_EQUAL(packet.get<FragIndexField>(0), 1234);
  BOOST_CHECK_THROW(packet.get<FragIndexField>(1), std::out_of_range);
  BOOST_CHECK_THROW(packet.remove<FragIndexField>(1), std::out_of_range);

  packet.remove<FragIndexField>(0);
  BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 0);

  packet.add<FragIndexField>(832);
  std::vector<uint64_t> fragIndexes = packet.list<FragIndexField>();
  BOOST_CHECK_EQUAL(fragIndexes.size(), 1);
  BOOST_CHECK_EQUAL(fragIndexes.at(0), 832);

  packet.clear<FragIndexField>();
  BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 0);
  BOOST_CHECK(packet.empty());

  packet.add<AckField>(4001);
  packet.add<AckField>(4002);
  packet.add<AckField>(4003);
  BOOST_CHECK_EQUAL(packet.count<AckField>(), 3);
  BOOST_CHECK_EQUAL(packet.get<AckField>(0), 4001);
  BOOST_CHECK_EQUAL(packet.get<AckField>(1), 4002);
  BOOST_CHECK_EQUAL(packet.get<AckField>(2), 4003);

  packet.remove<AckField>(1);
  BOOST_CHECK_EQUAL(packet.count<AckField>(), 2);
  BOOST_CHECK_EQUAL(packet.get<AckField>(0), 4001);
  BOOST_CHECK_EQUAL(packet.get<AckField>(1), 4003);

  packet.remove<AckField>(0);
  packet.remove<AckField>(0);
  BOOST_CHECK_EQUAL(packet.count<AckField>(), 0);
  BOOST_CHECK(packet.empty());
}

BOOST_AUTO_TEST_CASE(EncodeFragment)
{
  static const uint8_t expectedBlock[] = {
    0x64, 0x0e, // LpPacket
          0x51, 0x08, // Sequence
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Buffer buf(2);
  buf[0] = 0x03;
  buf[1] = 0xe8;

  Packet packet;
  packet.add<FragmentField>({buf.begin(), buf.end()});
  packet.add<SequenceField>(1000);
  Block wire = packet.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(EncodeSubTlv)
{
  static const uint8_t expectedBlock[] = {
    0x64, 0x09, // LpPacket
          0xfd, 0x03, 0x20, 0x05, // Nack
                0xfd, 0x03, 0x21, 0x01, // NackReason
                      0x64,
  };

  NackHeader nack;
  nack.setReason(NackReason::DUPLICATE);

  Packet packet;
  packet.add<NackField>(nack);
  Block wire = packet.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(EncodeZeroLengthTlv)
{
  static const uint8_t expectedBlock[] = {
    0x64, 0x04, // LpPacket
          0xfd, 0x03, 0x4c, 0x00, // NonDiscovery
  };

  Packet packet1;
  packet1.set<NonDiscoveryField>(EmptyValue{});
  Block wire = packet1.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                wire.begin(), wire.end());

  Packet packet2;
  packet2.add<NonDiscoveryField>(EmptyValue{});
  wire = packet2.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(EncodeSortOrder)
{
  static const uint8_t expectedBlock[] = {
    0x64, 0x2e, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0x53, 0x01, // FragCount
                0x01,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Buffer frag(2);
  frag[0] = 0x03;
  frag[1] = 0xe8;

  Packet packet;
  packet.add<FragmentField>({frag.begin(), frag.end()});
  packet.add<FragIndexField>(0);
  packet.add<AckField>(2);
  packet.wireEncode();
  packet.add<FragCountField>(1);
  packet.wireEncode();
  packet.add<AckField>(4);
  packet.wireEncode();
  packet.add<AckField>(3);
  Block wire = packet.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(expectedBlock, expectedBlock + sizeof(expectedBlock),
                                wire.begin(), wire.end());
}

BOOST_AUTO_TEST_CASE(DecodeNormal)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x2e, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0x53, 0x01, // FragCount
                0x01,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
          0xfd, 0x03, 0x44, 0x08, // Ack
                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);

  BOOST_CHECK_EQUAL(packet.count<FragIndexField>(), 1);
  BOOST_CHECK_EQUAL(packet.get<FragIndexField>(), 0);

  BOOST_CHECK_EQUAL(packet.count<FragCountField>(), 1);
  BOOST_CHECK_EQUAL(packet.get<FragCountField>(), 1);

  BOOST_CHECK_EQUAL(packet.count<AckField>(), 3);
  BOOST_CHECK_EQUAL(packet.get<AckField>(), 1);
  BOOST_CHECK_EQUAL(packet.get<AckField>(0), 1);
  BOOST_CHECK_EQUAL(packet.get<AckField>(1), 3);
  BOOST_CHECK_EQUAL(packet.get<AckField>(2), 2);

  BOOST_CHECK_EQUAL(packet.count<FragmentField>(), 1);
  auto [first, last] = packet.get<FragmentField>(0);
  BOOST_CHECK_EQUAL(2, last - first);
  BOOST_CHECK_EQUAL(0x03, *first);
  BOOST_CHECK_EQUAL(0xe8, *(last - 1));
}

BOOST_AUTO_TEST_CASE(DecodeIdle)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x06, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0x53, 0x01, // FragCount
                0x01,
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
  BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
  BOOST_CHECK_EQUAL(1, packet.count<FragCountField>());
  BOOST_CHECK_EQUAL(0, packet.get<FragIndexField>(0));
  BOOST_CHECK_EQUAL(1, packet.get<FragCountField>(0));
}

BOOST_AUTO_TEST_CASE(DecodeFragment)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x04, // LpPacket
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
  BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
  auto [first, last] = packet.get<FragmentField>(0);
  BOOST_CHECK_EQUAL(2, last - first);
  BOOST_CHECK_EQUAL(0x03, *first);
  BOOST_CHECK_EQUAL(0xe8, *(last - 1));
}

BOOST_AUTO_TEST_CASE(DecodeNonDiscoveryHeader)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x04, // LpPacket
          0xfd, 0x03, 0x4c, 0x00, // NonDiscovery
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(true, packet.has<NonDiscoveryField>());
  packet.get<NonDiscoveryField>();
}

BOOST_AUTO_TEST_CASE(DecodeEmpty)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x00, // LpPacket
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(0, packet.count<FragmentField>());
  BOOST_CHECK_EQUAL(0, packet.count<FragIndexField>());
  BOOST_CHECK_EQUAL(false, packet.has<NonDiscoveryField>());
}

BOOST_AUTO_TEST_CASE(DecodeRepeatedNonRepeatableHeader)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x06, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0x52, 0x01, // FragIndex
                0x01,
  };

  Packet packet;
  Block wire(inputBlock);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_AUTO_TEST_CASE(DecodeRepeatedFragment)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x08, // LpPacket
          0x50, 0x02, // Fragment
                0x03, 0xe8,
          0x50, 0x02, // Fragment
                0x03, 0xe9,
  };

  Packet packet;
  Block wire(inputBlock);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_AUTO_TEST_CASE(DecodeWrongOrderAmongHeaders)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x0a, // LpPacket
          0x53, 0x01, // FragCount
                0x01,
          0x52, 0x01, // FragIndex
                0x00,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Packet packet;
  Block wire(inputBlock);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_AUTO_TEST_CASE(DecodeWrongOrderFragment)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x0a, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
          0x53, 0x01, // FragCount
                0x01,
  };

  Packet packet;
  Block wire(inputBlock);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_AUTO_TEST_CASE(DecodeIgnoredHeader)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x0c, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0xfd, 0x03, 0x24, 0x01, // unknown TLV-TYPE 804 (ignored)
                0x02,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());
  BOOST_CHECK_EQUAL(1, packet.count<FragIndexField>());
}

BOOST_AUTO_TEST_CASE(DecodeUnrecognizedHeader)
{
  static const uint8_t inputBlock[] = {
    0x64, 0x0c, // LpPacket
          0x52, 0x01, // FragIndex
                0x00,
          0xfd, 0x03, 0x22, 0x01, // unknown TLV-TYPE 802 (cannot ignore)
                0x02,
          0x50, 0x02, // Fragment
                0x03, 0xe8,
  };

  Packet packet;
  Block wire(inputBlock);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_AUTO_TEST_CASE(DecodeBareNetworkLayerPacket)
{
  static const uint8_t inputBlock[] = {
    0x05, 0x0a, // Interest
          0x07, 0x02, // Name
                0x03, 0xe8,
          0x0a, 0x04, // Nonce
                0x01, 0x02, 0x03, 0x04,
  };

  Packet packet;
  Block wire(inputBlock);
  packet.wireDecode(wire);
  BOOST_CHECK_EQUAL(1, packet.count<FragmentField>());

  Block encoded = packet.wireEncode();
  BOOST_CHECK_EQUAL_COLLECTIONS(inputBlock, inputBlock + sizeof(inputBlock),
                                encoded.begin(), encoded.end());
}

BOOST_AUTO_TEST_CASE(DecodeSeqNum)
{
  Packet packet;

  // Sequence number is fixed-width, not NonNegativeInteger
  packet.wireDecode("640A 5104A4A5A6A7 5002FFFF"_block);
  BOOST_CHECK_THROW(packet.get<SequenceField>(), ndn::tlv::Error);

  packet.wireDecode("640E 5108A0A1A2A3A4A5A6A7 5002FFFF"_block);
  BOOST_CHECK_EQUAL(packet.get<SequenceField>(), 0xA0A1A2A3A4A5A6A7);
}

BOOST_AUTO_TEST_CASE(DecodeUnrecognizedTlvType)
{
  Packet packet;
  Block wire = makeEmptyBlock(ndn::tlv::Name);
  BOOST_CHECK_THROW(packet.wireDecode(wire), Packet::Error);
}

BOOST_FIXTURE_TEST_CASE(DecodePrefixAnnouncement, ndn::tests::KeyChainFixture)
{
  // Construct Data which prefix announcement is attached to
  auto data0 = ndn::tests::makeData("/edu/ua/cs/news/index.html");

  Packet packet0;
  packet0.wireDecode(data0->wireEncode());

  // Construct Prefix Announcement
  PrefixAnnouncement pa;
  pa.setAnnouncedName("/net/example");
  pa.setExpiration(5_min);
  pa.setValidityPeriod(security::ValidityPeriod(time::fromIsoString("20181030T000000"),
                                                time::fromIsoString("20181124T235959")));
  pa.toData(m_keyChain, signingWithSha256(), 1);
  PrefixAnnouncementHeader pah0(pa);
  packet0.add<PrefixAnnouncementField>(pah0);
  Block encoded = packet0.wireEncode();

  // check decoding
  Packet packet1;
  packet1.wireDecode(encoded);
  BOOST_CHECK_EQUAL(true, packet1.has<PrefixAnnouncementField>());
  PrefixAnnouncementHeader pah1 = packet1.get<PrefixAnnouncementField>();
  BOOST_CHECK_EQUAL(pah1.getPrefixAnn()->getAnnouncedName(), "/net/example");
}

BOOST_AUTO_TEST_SUITE_END() // TestPacket
BOOST_AUTO_TEST_SUITE_END() // Lp

} // namespace tests
} // namespace lp
} // namespace ndn
