/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 */

#include "interest.hpp"
#include "data.hpp"
#include "security/signature-sha256-with-rsa.hpp"
#include "security/signature-sha256.hpp"

#include "boost-test.hpp"

using namespace std;
namespace ndn {

BOOST_AUTO_TEST_SUITE(TestInterest)

BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Interest>));
BOOST_CONCEPT_ASSERT((boost::EqualityComparable<Selectors>));

const uint8_t Interest1[] = {
  0x05,  0x59, // NDN Interest
      0x07,  0x14, // Name
          0x08,  0x5, // NameComponent
              0x6c,  0x6f,  0x63,  0x61,  0x6c,
          0x08,  0x3, // NameComponent
              0x6e,  0x64,  0x6e,
          0x08,  0x6, // NameComponent
              0x70,  0x72,  0x65,  0x66,  0x69,  0x78,
      0x09,  0x37, // Selectors
          0x0d,  0x1,  0x1,  // MinSuffix
          0x0e,  0x1,  0x1,  // MaxSuffix
          0x1c, 0x16, // KeyLocator
              0x07, 0x14, // Name
                  0x08, 0x04,
                      0x74, 0x65, 0x73, 0x74,
                  0x08, 0x03,
                      0x6b, 0x65, 0x79,
                  0x08, 0x07,
                      0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
          0x10,  0x14, // Exclude
              0x08,  0x4, // NameComponent
                  0x61,  0x6c,  0x65,  0x78,
              0x08,  0x4, // NameComponent
                  0x78,  0x78,  0x78,  0x78,
              0x13,  0x0, // Any
              0x08,  0x4, // NameComponent
                  0x79,  0x79,  0x79,  0x79,
          0x11,  0x1, // ChildSelector
              0x1,
      0x0a,  0x1, // Nonce
          0x1,
      0x0b,  0x1, // Scope
          0x1,
      0x0c,       // InterestLifetime
          0x2,  0x3,  0xe8
};

const uint8_t InterestWithLocalControlHeader[] = {
  0x50, 0x22, 0x51, 0x01, 0x0a, 0x05, 0x1d, 0x07, 0x14, 0x08, 0x05, 0x6c, 0x6f, 0x63, 0x61,
  0x6c, 0x08, 0x03, 0x6e, 0x64, 0x6e, 0x08, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x09,
  0x02, 0x12, 0x00, 0x0a, 0x01, 0x01
};

const uint8_t InterestWithoutLocalControlHeader[] = {
  0x05, 0x1d, 0x07, 0x14, 0x08, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x08, 0x03, 0x6e, 0x64,
  0x6e, 0x08, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x09, 0x02, 0x12, 0x00, 0x0a, 0x01,
  0x01
};

BOOST_AUTO_TEST_CASE(InterestEqualityChecks)
{
  // Interest ::= INTEREST-TYPE TLV-LENGTH
  //                Name
  //                Selectors?
  //                Nonce
  //                Scope?
  //                InterestLifetime?

  Interest a;
  Interest b;

  // if nonce is not set, it will be set to a random value
  a.setNonce(1);
  b.setNonce(1);

  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // check comparison on Name
  a.setName("ndn:/A");
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setName("ndn:/B");
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setName("ndn:/A");
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // check comparison on Selectors
  a.setChildSelector(1);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setChildSelector(1);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // check comparison on Nonce
  a.setNonce(100);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setNonce(100);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // check comparison on Nonce
  a.setScope(1);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setScope(1);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // check comparison on InterestLifetime
  a.setInterestLifetime(time::seconds(10));
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setInterestLifetime(time::seconds(10));
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);
}

BOOST_AUTO_TEST_CASE(SelectorsEqualityChecks)
{
  // Selectors ::= SELECTORS-TYPE TLV-LENGTH
  //                 MinSuffixComponents?
  //                 MaxSuffixComponents?
  //                 PublisherPublicKeyLocator?
  //                 Exclude?
  //                 ChildSelector?
  //                 MustBeFresh?

  Selectors a;
  Selectors b;
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // MinSuffixComponents
  a.setMinSuffixComponents(1);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setMinSuffixComponents(2);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setMinSuffixComponents(1);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // MaxSuffixComponents
  a.setMaxSuffixComponents(10);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setMaxSuffixComponents(10);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // PublisherPublicKeyLocator
  a.setPublisherPublicKeyLocator(KeyLocator("/key/Locator/name"));
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setPublisherPublicKeyLocator(KeyLocator("/key/Locator/name"));
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // Exclude
  a.setExclude(Exclude().excludeOne(name::Component("exclude")));
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setExclude(Exclude().excludeOne(name::Component("exclude")));
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // ChildSelector
  a.setChildSelector(1);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setChildSelector(1);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);

  // MustBeFresh
  a.setMustBeFresh(true);
  BOOST_CHECK_EQUAL(a == b, false);
  BOOST_CHECK_EQUAL(a != b, true);

  b.setMustBeFresh(true);
  BOOST_CHECK_EQUAL(a == b, true);
  BOOST_CHECK_EQUAL(a != b, false);
}

BOOST_AUTO_TEST_CASE(Decode)
{
  Block interestBlock(Interest1, sizeof(Interest1));

  ndn::Interest i;
  BOOST_REQUIRE_NO_THROW(i.wireDecode(interestBlock));

  BOOST_CHECK_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
  BOOST_CHECK_EQUAL(i.getScope(), 1);
  BOOST_CHECK_EQUAL(i.getInterestLifetime(), time::milliseconds(1000));
  BOOST_CHECK_EQUAL(i.getMinSuffixComponents(), 1);
  BOOST_CHECK_EQUAL(i.getMaxSuffixComponents(), 1);
  BOOST_CHECK_EQUAL(i.getPublisherPublicKeyLocator().getType(),
                    static_cast<uint32_t>(KeyLocator::KeyLocator_Name));
  BOOST_CHECK_EQUAL(i.getPublisherPublicKeyLocator().getName(), "ndn:/test/key/locator");
  BOOST_CHECK_EQUAL(i.getChildSelector(), 1);
  BOOST_CHECK_EQUAL(i.getMustBeFresh(), false);
  BOOST_CHECK_EQUAL(i.getExclude().toUri(), "alex,xxxx,*,yyyy");
  BOOST_CHECK_EQUAL(i.getNonce(), 1U);
}

BOOST_AUTO_TEST_CASE(DecodeFromStream)
{
  boost::iostreams::stream<boost::iostreams::array_source> is(
    reinterpret_cast<const char *>(Interest1), sizeof(Interest1));

  Block interestBlock(is);

  ndn::Interest i;
  BOOST_REQUIRE_NO_THROW(i.wireDecode(interestBlock));

  BOOST_CHECK_EQUAL(i.getName().toUri(), "/local/ndn/prefix");
  BOOST_CHECK_EQUAL(i.getScope(), 1);
  BOOST_CHECK_EQUAL(i.getInterestLifetime(), time::milliseconds(1000));
  BOOST_CHECK_EQUAL(i.getMinSuffixComponents(), 1);
  BOOST_CHECK_EQUAL(i.getMaxSuffixComponents(), 1);
  BOOST_CHECK_EQUAL(i.getChildSelector(), 1);
  BOOST_CHECK_EQUAL(i.getMustBeFresh(), false);
  BOOST_CHECK_EQUAL(i.getExclude().toUri(), "alex,xxxx,*,yyyy");
  BOOST_CHECK_EQUAL(i.getNonce(), 1U);
}

BOOST_AUTO_TEST_CASE(Encode)
{
  ndn::Interest i(ndn::Name("/local/ndn/prefix"));
  i.setScope(1);
  i.setInterestLifetime(time::milliseconds(1000));
  i.setMinSuffixComponents(1);
  i.setMaxSuffixComponents(1);
  i.setPublisherPublicKeyLocator(KeyLocator("ndn:/test/key/locator"));
  i.setChildSelector(1);
  i.setMustBeFresh(false);
  Exclude exclude;
  exclude
    .excludeOne(name::Component("alex"))
    .excludeRange(name::Component("xxxx"), name::Component("yyyy"));
  i.setExclude(exclude);
  i.setNonce(1);

  const Block &wire = i.wireEncode();

  BOOST_CHECK_EQUAL_COLLECTIONS(Interest1, Interest1 + sizeof(Interest1),
                                wire.begin(), wire.end());
}


BOOST_AUTO_TEST_CASE(EncodeWithLocalHeader)
{
  ndn::Interest interest(ndn::Name("/local/ndn/prefix"));
  interest.setMustBeFresh(true);
  interest.setIncomingFaceId(10);
  interest.setNonce(1);

  BOOST_CHECK(!interest.hasWire());

  Block headerBlock = interest.getLocalControlHeader().wireEncode(interest, true, true);

  BOOST_CHECK(interest.hasWire());
  BOOST_CHECK(headerBlock.hasWire());

  BOOST_CHECK_NE(headerBlock.wire(), interest.wireEncode().wire());
  BOOST_CHECK_NE(headerBlock.size(), interest.wireEncode().size());
  BOOST_CHECK_EQUAL(headerBlock.size(), 5);

  BOOST_CHECK_EQUAL_COLLECTIONS(InterestWithLocalControlHeader,
                                InterestWithLocalControlHeader + 5,
                                headerBlock.begin(), headerBlock.end());

  interest.setNonce(1000);

  Block updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, true, true);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 5);

  // only length should have changed
  BOOST_CHECK_EQUAL_COLLECTIONS(updatedHeaderBlock.begin() + 2, updatedHeaderBlock.end(),
                                headerBlock.begin() + 2,        headerBlock.end());

  // updating IncomingFaceId that keeps the length
  interest.setIncomingFaceId(100);
  updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, true, true);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 5);
  BOOST_CHECK_NE(*(updatedHeaderBlock.begin() + 4), *(headerBlock.begin() + 4));

  // updating IncomingFaceId that increases the length by 2
  interest.setIncomingFaceId(1000);
  updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, true, true);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 6);

  // adding NextHopId
  interest.setNextHopFaceId(1);
  updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, true, true);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 9);

  // masking IncomingFaceId
  updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, false, true);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 5);

  // masking NextHopId
  updatedHeaderBlock = interest.getLocalControlHeader().wireEncode(interest, true, false);
  BOOST_CHECK_EQUAL(updatedHeaderBlock.size(), 6);

  // masking everything
  BOOST_CHECK_THROW(interest.getLocalControlHeader().wireEncode(interest, false, false),
                    nfd::LocalControlHeader::Error);
}


BOOST_AUTO_TEST_CASE(DecodeWithLocalHeader)
{
  Block wireBlock(InterestWithLocalControlHeader, sizeof(InterestWithLocalControlHeader));
  const Block& payload = nfd::LocalControlHeader::getPayload(wireBlock);
  BOOST_REQUIRE_NE(&payload, &wireBlock);

  BOOST_CHECK_EQUAL(payload.type(), static_cast<uint32_t>(Tlv::Interest));
  BOOST_CHECK_EQUAL(wireBlock.type(), static_cast<uint32_t>(tlv::nfd::LocalControlHeader));

  Interest interest(payload);
  BOOST_CHECK(!interest.getLocalControlHeader().hasIncomingFaceId());
  BOOST_CHECK(!interest.getLocalControlHeader().hasNextHopFaceId());

  BOOST_REQUIRE_NO_THROW(interest.getLocalControlHeader().wireDecode(wireBlock));

  BOOST_CHECK_EQUAL(interest.getLocalControlHeader().wireEncode(interest, true, true).size(), 5);

  BOOST_CHECK_EQUAL(interest.getIncomingFaceId(), 10);
  BOOST_CHECK(!interest.getLocalControlHeader().hasNextHopFaceId());

  BOOST_CHECK_THROW(interest.getLocalControlHeader().wireEncode(interest, false, false),
                    nfd::LocalControlHeader::Error);

  BOOST_CHECK_THROW(interest.getLocalControlHeader().wireEncode(interest, false, true),
                    nfd::LocalControlHeader::Error);

  BOOST_CHECK_NO_THROW(interest.getLocalControlHeader().wireEncode(interest, true, false));
  BOOST_CHECK_NO_THROW(interest.getLocalControlHeader().wireEncode(interest, true, true));

  BOOST_CHECK_NE((void*)interest.getLocalControlHeader().wireEncode(interest, true, true).wire(),
                 (void*)wireBlock.wire());

  BOOST_CHECK_EQUAL(interest.getLocalControlHeader().wireEncode(interest, true, true).size(), 5);
}

BOOST_AUTO_TEST_CASE(DecodeWithoutLocalHeader)
{
  Block wireBlock(InterestWithoutLocalControlHeader, sizeof(InterestWithoutLocalControlHeader));
  const Block& payload = nfd::LocalControlHeader::getPayload(wireBlock);
  BOOST_CHECK_EQUAL(&payload, &wireBlock);
}

BOOST_AUTO_TEST_CASE(MatchesData)
{
  Interest interest;
  interest.setName("ndn:/A")
          .setMinSuffixComponents(2)
          .setMaxSuffixComponents(2)
          .setPublisherPublicKeyLocator(KeyLocator("ndn:/B"))
          .setExclude(Exclude().excludeBefore(name::Component("C")));

  Data data("ndn:/A/D");
  SignatureSha256WithRsa signature;
  signature.setKeyLocator(KeyLocator("ndn:/B"));
  data.setSignature(signature);
  BOOST_CHECK_EQUAL(interest.matchesData(data), true);

  Data data1 = data;
  data1.setName("ndn:/A");// violates MinSuffixComponents
  BOOST_CHECK_EQUAL(interest.matchesData(data1), false);

  Data data2 = data;
  data2.setName("ndn:/A/E/F");// violates MaxSuffixComponents
  BOOST_CHECK_EQUAL(interest.matchesData(data2), false);

  Data data3 = data;
  SignatureSha256WithRsa signature3;
  signature3.setKeyLocator(KeyLocator("ndn:/G"));// violates PublisherPublicKeyLocator
  data3.setSignature(signature3);
  BOOST_CHECK_EQUAL(interest.matchesData(data3), false);

  Data data4 = data;
  SignatureSha256 signature4;// violates PublisherPublicKeyLocator
  data4.setSignature(signature4);
  BOOST_CHECK_EQUAL(interest.matchesData(data4), false);

  Data data5 = data;
  data5.setName("ndn:/A/C");// violates Exclude
  BOOST_CHECK_EQUAL(interest.matchesData(data5), false);

  Data data6 = data;
  data6.setName("ndn:/H/I");// violates Name
  BOOST_CHECK_EQUAL(interest.matchesData(data6), false);
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace ndn
