/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "table/cs.hpp"
#include <ndn-cxx/util/crypto.hpp>

#include "tests/test-common.hpp"

#define CHECK_CS_FIND(expected) find([&] (uint32_t found) { BOOST_CHECK_EQUAL(expected, found); });

namespace nfd {
namespace cs {
namespace tests {

using namespace nfd::tests;

BOOST_AUTO_TEST_SUITE(Table)
BOOST_FIXTURE_TEST_SUITE(TestCs, BaseFixture)

class FindFixture : protected BaseFixture
{
protected:
  Name
  insert(uint32_t id, const Name& name)
  {
    shared_ptr<Data> data = makeData(name);
    data->setFreshnessPeriod(time::milliseconds(99999));
    data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
    data->wireEncode();

    m_cs.insert(*data);

    return data->getFullName();
  }

  Interest&
  startInterest(const Name& name)
  {
    m_interest = make_shared<Interest>(name);
    return *m_interest;
  }

  void
  find(const std::function<void(uint32_t)>& check)
  {
    m_cs.find(*m_interest,
              [&] (const Interest& interest, const Data& data) {
                  const Block& content = data.getContent();
                  uint32_t found = *reinterpret_cast<const uint32_t*>(content.value());
                  check(found); },
              bind([&] { check(0); }));
  }

protected:
  Cs m_cs;
  shared_ptr<Interest> m_interest;
};

BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)

BOOST_AUTO_TEST_CASE(EmptyDataName)
{
  insert(1, "ndn:/");

  startInterest("ndn:/");
  CHECK_CS_FIND(1);
}

BOOST_AUTO_TEST_CASE(EmptyInterestName)
{
  insert(1, "ndn:/A");

  startInterest("ndn:/");
  CHECK_CS_FIND(1);
}

BOOST_AUTO_TEST_CASE(ExactName)
{
  insert(1, "ndn:/");
  insert(2, "ndn:/A");
  insert(3, "ndn:/A/B");
  insert(4, "ndn:/A/C");
  insert(5, "ndn:/D");

  startInterest("ndn:/A");
  CHECK_CS_FIND(2);
}

BOOST_AUTO_TEST_CASE(FullName)
{
  Name n1 = insert(1, "ndn:/A");
  Name n2 = insert(2, "ndn:/A");

  startInterest(n1);
  CHECK_CS_FIND(1);

  startInterest(n2);
  CHECK_CS_FIND(2);
}

BOOST_AUTO_TEST_CASE(Leftmost)
{
  insert(1, "ndn:/A");
  insert(2, "ndn:/B/p/1");
  insert(3, "ndn:/B/p/2");
  insert(4, "ndn:/B/q/1");
  insert(5, "ndn:/B/q/2");
  insert(6, "ndn:/C");

  startInterest("ndn:/B");
  CHECK_CS_FIND(2);
}

BOOST_AUTO_TEST_CASE(Rightmost)
{
  insert(1, "ndn:/A");
  insert(2, "ndn:/B/p/1");
  insert(3, "ndn:/B/p/2");
  insert(4, "ndn:/B/q/1");
  insert(5, "ndn:/B/q/2");
  insert(6, "ndn:/C");

  startInterest("ndn:/B")
    .setChildSelector(1);
  CHECK_CS_FIND(4);
}

BOOST_AUTO_TEST_CASE(MinSuffixComponents)
{
  insert(1, "ndn:/");
  insert(2, "ndn:/A");
  insert(3, "ndn:/B/1");
  insert(4, "ndn:/C/1/2");
  insert(5, "ndn:/D/1/2/3");
  insert(6, "ndn:/E/1/2/3/4");

  startInterest("ndn:/")
    .setMinSuffixComponents(0);
  CHECK_CS_FIND(1);

  startInterest("ndn:/")
    .setMinSuffixComponents(1);
  CHECK_CS_FIND(1);

  startInterest("ndn:/")
    .setMinSuffixComponents(2);
  CHECK_CS_FIND(2);

  startInterest("ndn:/")
    .setMinSuffixComponents(3);
  CHECK_CS_FIND(3);

  startInterest("ndn:/")
    .setMinSuffixComponents(4);
  CHECK_CS_FIND(4);

  startInterest("ndn:/")
    .setMinSuffixComponents(5);
  CHECK_CS_FIND(5);

  startInterest("ndn:/")
    .setMinSuffixComponents(6);
  CHECK_CS_FIND(6);

  startInterest("ndn:/")
    .setMinSuffixComponents(7);
  CHECK_CS_FIND(0);
}

BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
{
  insert(1, "ndn:/");
  insert(2, "ndn:/A");
  insert(3, "ndn:/B/2");
  insert(4, "ndn:/C/2/3");
  insert(5, "ndn:/D/2/3/4");
  insert(6, "ndn:/E/2/3/4/5");

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(0);
  CHECK_CS_FIND(0);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(1);
  CHECK_CS_FIND(1);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(2);
  CHECK_CS_FIND(2);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(3);
  CHECK_CS_FIND(3);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(4);
  CHECK_CS_FIND(4);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(5);
  CHECK_CS_FIND(5);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(6);
  CHECK_CS_FIND(6);

  startInterest("ndn:/")
    .setChildSelector(1)
    .setMaxSuffixComponents(7);
  CHECK_CS_FIND(6);
}

BOOST_AUTO_TEST_CASE(DigestOrder)
{
  insert(1, "ndn:/A");
  insert(2, "ndn:/A");
  // We don't know which comes first, but there must be some order

  int leftmost = 0, rightmost = 0;
  startInterest("ndn:/A")
    .setChildSelector(0);
  m_cs.find(*m_interest,
            [&leftmost] (const Interest& interest, const Data& data) {
              leftmost = *reinterpret_cast<const uint32_t*>(data.getContent().value());},
            bind([] { BOOST_CHECK(false); }));
  startInterest("ndn:/A")
    .setChildSelector(1);
  m_cs.find(*m_interest,
            [&rightmost] (const Interest, const Data& data) {
              rightmost = *reinterpret_cast<const uint32_t*>(data.getContent().value()); },
            bind([] { BOOST_CHECK(false); }));
  BOOST_CHECK_NE(leftmost, rightmost);
}

BOOST_AUTO_TEST_CASE(DigestExclude)
{
  insert(1, "ndn:/A");
  Name n2 = insert(2, "ndn:/A");
  insert(3, "ndn:/A/B");

  uint8_t digest00[ndn::crypto::SHA256_DIGEST_SIZE];
  std::fill_n(digest00, sizeof(digest00), 0x00);
  uint8_t digestFF[ndn::crypto::SHA256_DIGEST_SIZE];
  std::fill_n(digestFF, sizeof(digestFF), 0xFF);

  Exclude excludeDigest;
  excludeDigest.excludeRange(
    name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
    name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));

  startInterest("ndn:/A")
    .setChildSelector(0)
    .setExclude(excludeDigest);
  CHECK_CS_FIND(3);

  startInterest("ndn:/A")
    .setChildSelector(1)
    .setExclude(excludeDigest);
  CHECK_CS_FIND(3);

  Exclude excludeGeneric;
  excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));

  startInterest("ndn:/A")
    .setChildSelector(0)
    .setExclude(excludeGeneric);
  find([] (uint32_t found) { BOOST_CHECK(found == 1 || found == 2); });

  startInterest("ndn:/A")
    .setChildSelector(1)
    .setExclude(excludeGeneric);
  find([] (uint32_t found) { BOOST_CHECK(found == 1 || found == 2); });

  Exclude exclude2 = excludeGeneric;
  exclude2.excludeOne(n2.get(-1));

  startInterest("ndn:/A")
    .setChildSelector(0)
    .setExclude(exclude2);
  CHECK_CS_FIND(1);

  startInterest("ndn:/A")
    .setChildSelector(1)
    .setExclude(exclude2);
  CHECK_CS_FIND(1);
}

/// \todo test MustBeFresh

BOOST_AUTO_TEST_SUITE_END() // Find

// When the capacity limit is set to zero, Data cannot be inserted;
// this test case covers this situation.
// The behavior of non-zero capacity limit depends on the eviction policy,
// and is tested in policy test suites.
BOOST_FIXTURE_TEST_CASE(ZeroCapacity, FindFixture)
{
  m_cs.setLimit(0);

  BOOST_CHECK_EQUAL(m_cs.getLimit(), 0);
  BOOST_CHECK_EQUAL(m_cs.size(), 0);
  BOOST_CHECK(m_cs.begin() == m_cs.end());

  insert(1, "ndn:/A");
  BOOST_CHECK_EQUAL(m_cs.size(), 0);

  startInterest("ndn:/A");
  CHECK_CS_FIND(0);
}

BOOST_AUTO_TEST_CASE(CachePolicyNoCache)
{
  Cs cs(3);

  shared_ptr<Data> dataA = makeData("ndn:/A");
  dataA->wireEncode();
  dataA->setTag(make_shared<lp::CachePolicyTag>(
                lp::CachePolicy().setPolicy(lp::CachePolicyType::NO_CACHE)));
  cs.insert(*dataA);

  BOOST_CHECK_EQUAL(cs.size(), 0);
  cs.find(Interest("ndn:/A"),
          bind([] { BOOST_CHECK(false); }),
          bind([] { BOOST_CHECK(true); }));
}

BOOST_AUTO_TEST_CASE(Enumeration)
{
  Cs cs;

  Name nameA("/A");
  Name nameAB("/A/B");
  Name nameABC("/A/B/C");
  Name nameD("/D");

  BOOST_CHECK_EQUAL(cs.size(), 0);
  BOOST_CHECK(cs.begin() == cs.end());

  cs.insert(*makeData(nameABC));
  BOOST_CHECK_EQUAL(cs.size(), 1);
  BOOST_CHECK(cs.begin() != cs.end());
  BOOST_CHECK(cs.begin()->getName() == nameABC);
  BOOST_CHECK((*cs.begin()).getName() == nameABC);

  auto i = cs.begin();
  auto j = cs.begin();
  BOOST_CHECK(++i == cs.end());
  BOOST_CHECK(j++ == cs.begin());
  BOOST_CHECK(j == cs.end());

  cs.insert(*makeData(nameA));
  cs.insert(*makeData(nameAB));
  cs.insert(*makeData(nameD));

  std::set<Name> expected = {nameA, nameAB, nameABC, nameD};
  std::set<Name> actual;
  for (const auto& csEntry : cs) {
    actual.insert(csEntry.getName());
  }
  BOOST_CHECK_EQUAL_COLLECTIONS(actual.begin(), actual.end(), expected.begin(), expected.end());
}

BOOST_AUTO_TEST_SUITE_END() // TestCs
BOOST_AUTO_TEST_SUITE_END() // Table

} // namespace tests
} // namespace cs
} // namespace nfd
