/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2016 Regents of the University of California.
*
* This file is part of the nTorrent codebase.
*
* nTorrent 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.
*
* nTorrent 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 nTorrent, e.g., in COPYING.md file. SoIf not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS for complete list of nTorrent authors and contributors.
*/

#include "boost-test.hpp"

#include "dummy-parser-fixture.hpp"
#include "torrent-manager.hpp"
#include "torrent-file.hpp"
#include "unit-test-time-fixture.hpp"

#include <set>

#include <boost/filesystem.hpp>

#include <ndn-cxx/util/dummy-client-face.hpp>
#include <ndn-cxx/util/io.hpp>

namespace ndn {
namespace ntorrent {
namespace tests {

using std::vector;
using ndn::Name;
using ndn::util::DummyClientFace;

namespace fs = boost::filesystem;

class TestTorrentManager : public TorrentManager {
public:
  TestTorrentManager(const ndn::Name&                 torrentFileName,
                     const std::string&               filePath,
                     std::shared_ptr<DummyClientFace> face)
  : TorrentManager(torrentFileName, filePath, false, face)
  , m_face(face)
  {
    m_keyChain = make_shared<KeyChain>();
  }

  std::vector<TorrentFile> torrentSegments() const {
    return m_torrentSegments;
  }

  std::vector<FileManifest> fileManifests() const {
    return m_fileManifests;
  }

  void pushTorrentSegment(const TorrentFile& t) {
    m_torrentSegments.push_back(t);
  }

  void pushFileManifestSegment(const FileManifest& m) {
    m_fileManifests.push_back(m);
  }

  shared_ptr<Name> findTorrentFileSegmentToDownload() {
    return TorrentManager::findTorrentFileSegmentToDownload();
  }

  shared_ptr<Name> findManifestSegmentToDownload(const Name& manifestName) {
    return TorrentManager::findManifestSegmentToDownload(manifestName);
  }

  std::vector<bool> fileState(const ndn::Name& manifestName) {
    auto fout = m_fileStates[manifestName].first;
    if (nullptr != fout) {
      fout->flush();
    }
    return m_fileStates[manifestName].second;
  }

  void setFileState(const ndn::Name manifestName,
                    std::shared_ptr<fs::fstream> f,
                    const std::vector<bool>& stateVec) {

    m_fileStates.insert({ manifestName, std::make_pair(f, stateVec) });
  }

  bool writeData(const Data& data) {
    return TorrentManager::writeData(data);
  }

  bool writeTorrentSegment(const TorrentFile& segment, const std::string& path) {
    return TorrentManager::writeTorrentSegment(segment, path);
  }

  bool writeFileManifest(const FileManifest& manifest, const std::string& path) {
    return TorrentManager::writeFileManifest(manifest, path);
  }

  void sendRoutablePrefixResponse() {
    // Create a data packet containing one name as content
    shared_ptr<Data> d = DummyParser::createDataPacket(Name("/localhop/nfd/rib/routable-prefixes"),
                                                       { Name("ucla") });
    m_keyChain->sign(*d);
    m_face->receive(*d);
  }

private:
  shared_ptr<KeyChain> m_keyChain;
  shared_ptr<DummyClientFace> m_face;
};

class FaceFixture : public UnitTestTimeFixture
{
public:
  explicit
  FaceFixture(bool enableRegistrationReply = true)
    : face(new DummyClientFace(io, { true, enableRegistrationReply }))
  {
  }

  ~FaceFixture()
  {
    fs::remove_all(".appdata");
  }

public:
  std::shared_ptr<DummyClientFace> face;
};

class FacesNoRegistrationReplyFixture : public FaceFixture
{
public:
  FacesNoRegistrationReplyFixture()
    : FaceFixture(false)
  {
  }
};

BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerInitialize, FaceFixture)

BOOST_AUTO_TEST_CASE(CheckInitializeComplete)
{
   const struct {
       const char    *d_directoryPath;
       const char    *d_initialSegmentName;
       size_t         d_namesPerSegment;
       size_t         d_subManifestSize;
       size_t         d_dataPacketSize;
   } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
     {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128,  128, 128},
     // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851",   1,    1, 128},
   };
   enum { NUM_DATA = sizeof DATA / sizeof *DATA };
   for (int i = 0; i < NUM_DATA; ++i) {
     auto directoryPath      = DATA[i].d_directoryPath;
     Name initialSegmentName = DATA[i].d_initialSegmentName;
     auto namesPerSegment    = DATA[i].d_namesPerSegment;
     auto dataPacketSize     = DATA[i].d_dataPacketSize;
     auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<FileManifest> manifests;
    vector<TorrentFile> torrentSegments;
    std::string filePath = "tests/testdata/";
    // get torrent files and manifests
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
      auto temp1      = temp.second;
      for (const auto& ms : temp1) {
        manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      }
    }
    // write the torrent segments and manifests to disk
    std::string dirPath = ".appdata/foo/";
    boost::filesystem::create_directories(dirPath);
    std::string torrentPath = dirPath + "torrent_files/";
    boost::filesystem::create_directory(torrentPath);
    auto fileNum = 0;
    for (const auto& t : torrentSegments) {
      fileNum++;
      auto filename = torrentPath + to_string(fileNum);
      io::save(t, filename);
    }
    auto manifestPath = dirPath + "manifests/";
    boost::filesystem::create_directory(manifestPath);
    for (const auto& m : manifests) {
      fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
      boost::filesystem::create_directories(filename.parent_path());
      io::save(m, filename.string());
    }
    // Initialize and verify
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();
    BOOST_CHECK(manager.hasAllTorrentSegments());

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    // Check that the torrent segments and file manifests match (content and order)
    BOOST_CHECK(manager.torrentSegments() == torrentSegments);
    BOOST_CHECK(manager.fileManifests()   == manifests);
    // next check the data packet state vectors
    for (auto m : manager.fileManifests()) {
      auto fileState = manager.fileState(m.getFullName());
      BOOST_CHECK(fileState.size() == m.catalog().size());
      for (auto s : fileState) {
        BOOST_CHECK(s);
      }
    }
    fs::remove_all(dirPath);
  }
}

BOOST_AUTO_TEST_CASE(CheckInitializeEmpty)
{
  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
                             "tests/testdata/", face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  BOOST_CHECK(!manager.hasAllTorrentSegments());

  BOOST_CHECK(manager.torrentSegments() == vector<TorrentFile>());
  BOOST_CHECK(manager.fileManifests()   == vector<FileManifest>());
}

BOOST_AUTO_TEST_CASE(CheckInitializeNoManifests)
{
   const struct {
       const char    *d_directoryPath;
       const char    *d_initialSegmentName;
       size_t         d_namesPerSegment;
       size_t         d_subManifestSize;
       size_t         d_dataPacketSize;
   } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
     {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128,  128, 128},
     // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851",   1,    1, 128},
   };
   enum { NUM_DATA = sizeof DATA / sizeof *DATA };
   for (int i = 0; i < NUM_DATA; ++i) {
     auto directoryPath      = DATA[i].d_directoryPath;
     Name initialSegmentName = DATA[i].d_initialSegmentName;
     auto namesPerSegment    = DATA[i].d_namesPerSegment;
     auto dataPacketSize     = DATA[i].d_dataPacketSize;
     auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<FileManifest> manifests;
    vector<TorrentFile> torrentSegments;
    std::string filePath = "tests/testdata/";
    // get torrent files and manifests
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
    }
    // write the torrent segments  and manifests to disk
    std::string dirPath = ".appdata/foo/";
    boost::filesystem::create_directories(dirPath);
    std::string torrentPath = dirPath + "torrent_files/";
    boost::filesystem::create_directory(torrentPath);
    auto fileNum = 0;
    for (const auto& t : torrentSegments) {
      fileNum++;
      auto filename = torrentPath + to_string(fileNum);
      io::save(t, filename);
    }
    // Initialize and verify
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();
    BOOST_CHECK(manager.hasAllTorrentSegments());

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    // Check that the torrent segments and file manifests match (content and order)
    BOOST_CHECK(manager.torrentSegments() == torrentSegments);
    BOOST_CHECK(manager.fileManifests()   == vector<FileManifest>());

    fs::remove_all(".appdata");
  }
}

BOOST_AUTO_TEST_CASE(CheckInitializeMissingManifests)
{
   const struct {
       const char    *d_directoryPath;
       const char    *d_initialSegmentName;
       size_t         d_namesPerSegment;
       size_t         d_subManifestSize;
       size_t         d_dataPacketSize;
   } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
     {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128,  128, 128},
     // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851",   1,    1, 128},
   };
   enum { NUM_DATA = sizeof DATA / sizeof *DATA };
   for (int i = 0; i < NUM_DATA; ++i) {
     auto directoryPath      = DATA[i].d_directoryPath;
     Name initialSegmentName = DATA[i].d_initialSegmentName;
     auto namesPerSegment    = DATA[i].d_namesPerSegment;
     auto dataPacketSize     = DATA[i].d_dataPacketSize;
     auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<FileManifest> manifests;
    vector<TorrentFile> torrentSegments;
    std::string filePath = "tests/testdata/";
    // get torrent files and manifests
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
      auto temp1      = temp.second;
      temp1.pop_back(); // remove the manifests for the last file
      for (const auto& ms : temp1) {
        manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      }
    }
    // write the torrent segments  and manifests to disk
    std::string dirPath = ".appdata/foo/";
    boost::filesystem::create_directories(dirPath);
    std::string torrentPath = dirPath + "torrent_files/";
    boost::filesystem::create_directories(torrentPath);
    auto fileNum = 0;
    for (const auto& t : torrentSegments) {
      fileNum++;
      auto filename = torrentPath + to_string(fileNum);
      io::save(t, filename);
    }
    auto manifestPath = dirPath + "manifests/";
    boost::filesystem::create_directory(manifestPath);
    for (const auto& m : manifests) {
      fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
      boost::filesystem::create_directory(filename.parent_path());
      io::save(m, filename.string());
    }

    // Initialize and verify
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();
    BOOST_CHECK(manager.hasAllTorrentSegments());

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    // Check that the torrent segments and file manifests match (content and order)
    BOOST_CHECK(manager.torrentSegments() == torrentSegments);
    BOOST_CHECK(manager.fileManifests()   == manifests);
    // next check the data packet state vectors
    for (auto m : manager.fileManifests()) {
      auto fileState = manager.fileState(m.getFullName());
      BOOST_CHECK(fileState.size() == m.catalog().size());
      for (auto s : fileState) {
        BOOST_CHECK(s);
      }
    }
    fs::remove_all(".appdata");
  }
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerNetworkingStuff, FaceFixture)

BOOST_AUTO_TEST_CASE(TestDownloadingTorrentFile)
{
  vector<FileManifest> manifests;
  vector<TorrentFile> torrentSegments;
  std::string filePath = ".appdata/foo/";
  // get torrent files and manifests
  {
    auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);

    torrentSegments = temp.first;
    auto temp1      = temp.second;
    temp1.pop_back(); // remove the manifests for the last file
    for (const auto& ms : temp1) {
      for (const auto& m : ms.first) {
        manifests.push_back(m);
      }
    }
  }

  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
                             filePath, face);

  manager.Initialize();
  BOOST_CHECK(!manager.hasAllTorrentSegments());

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  // Test download torrent file segments
  uint32_t counter = 0;
  manager.downloadTorrentFile(filePath + "torrent_files", [&counter, &torrentSegments]
                                (const std::vector<ndn::Name>& vec) {
                                  uint32_t manifestNum = 0;
                                  for (auto i = vec.begin(); i != vec.end(); i++) {
                                    Name n = torrentSegments[counter].getCatalog()[manifestNum];
                                    BOOST_CHECK_EQUAL(n, *i);
                                    manifestNum++;
                                  }
                                  counter++;
                                },
                                bind([] {
                                  BOOST_FAIL("Unexpected failure");
                                }));

  for (auto i = torrentSegments.begin(); i != torrentSegments.end(); i++) {
    advanceClocks(time::milliseconds(1), 40);
    face->receive(dynamic_cast<Data&>(*i));
  }
  BOOST_CHECK(manager.hasAllTorrentSegments());
  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

BOOST_AUTO_TEST_CASE(TestDownloadingFileManifests)
{
  vector<FileManifest> manifests;
  vector<TorrentFile> torrentSegments;
  std::string filePath = ".appdata/foo/";
  // get torrent files and manifests
  {
    auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);

    torrentSegments = temp.first;
    auto temp1      = temp.second;
    temp1.pop_back(); // remove the manifests for the last file
    for (const auto& ms : temp1) {
      for (const auto& m : ms.first) {
        manifests.push_back(m);
      }
    }
  }

  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
                             filePath, face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  // Test download manifest segments -- 2 files (the first one segment, the second multiple)
  int counter = 0;
  manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
                                [&counter, &manifests]
                                (const std::vector<ndn::Name>& vec) {
                                  uint32_t packetIndex = 0;
                                  for (auto j = vec.begin(); j != vec.end(); j++) {
                                    BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
                                                      *j);
                                    packetIndex++;
                                  }
                                  counter++;
                                },
                                [](const ndn::Name& name, const std::string& reason) {
                                  BOOST_FAIL("Unexpected failure");
                                });

  advanceClocks(time::milliseconds(1), 40);
  face->receive(dynamic_cast<Data&>(manifests[0]));

  manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
                                [&counter, &manifests]
                                (const std::vector<ndn::Name>& vec) {
                                  uint32_t packetIndex = 0;
                                  for (auto j = vec.begin(); j != vec.end(); j++) {
                                    BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
                                                      *j);
                                    // if we have read all the packet names from a
                                    // segment, move to the next one
                                    if (packetIndex == manifests[counter].catalog().size() - 1) {
                                      packetIndex = 0;
                                      counter++;
                                    }
                                    else {
                                      packetIndex++;
                                    }
                                  }
                                },
                                [](const ndn::Name& name, const std::string& reason) {
                                  BOOST_FAIL("Unexpected failure");
                                });

  for (auto i = manifests.begin() + 1; i != manifests.end(); i++) {
    advanceClocks(time::milliseconds(1), 40);
    face->receive(dynamic_cast<Data&>(*i));
  }

  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

BOOST_AUTO_TEST_CASE(TestDownloadingDataPackets)
{
  std::string filePath = ".appdata/foo/";
  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
                             filePath, face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  Name dataName("/test/ucla");

  // Download data successfully
  manager.download_data_packet(dataName,
                              [&dataName] (const ndn::Name& name) {
                                BOOST_CHECK_EQUAL(name, dataName);
                              },
                              [](const ndn::Name& name, const std::string& reason) {
                                BOOST_FAIL("Unexpected failure");
                              });

  auto data = make_shared<Data>(dataName);
  SignatureSha256WithRsa fakeSignature;
  fakeSignature.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
  data->setSignature(fakeSignature);
  data->wireEncode();

  advanceClocks(time::milliseconds(1), 40);
  face->receive(*data);

  // Fail to download data
  manager.download_data_packet(dataName,
                              [](const ndn::Name& name) {
                                BOOST_FAIL("Unexpected failure");
                              },
                              [&dataName](const ndn::Name& name, const std::string& reason) {
                                BOOST_CHECK_EQUAL(name, dataName);
                              });

  advanceClocks(time::milliseconds(1), 2100);

  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

// we already have downloaded the torrent file
BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload1)
{
  std::string filePath = ".appdata/foo/";
  TestTorrentManager manager("NTORRENT/test/torrent-file/sha256digest",
                             filePath, face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  TorrentFile t1(Name("NTORRENT/test/torrent-file/sha256digest"),
                 Name("NTORRENT/test/torrent-file/1/sha256digest"), Name("/test"),
                 { Name("/manifest1") });
  manager.pushTorrentSegment(t1);

  TorrentFile t2(Name("NTORRENT/test/torrent-file/1/sha256digest"),
                 Name("NTORRENT/test/torrent-file/2/sha256digest"), Name("/test"),
                 { Name("/manifest2"), Name("/manifest3") });
  manager.pushTorrentSegment(t2);

  TorrentFile t3(Name("NTORRENT/test/torrent-file/3/sha256digest"),
                 Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"),
                 { Name("/manifest4"), Name("/manifest5") });
  manager.pushTorrentSegment(t3);

  TorrentFile t4(Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"), {});
  manager.pushTorrentSegment(t4);

  BOOST_CHECK(!(manager.findTorrentFileSegmentToDownload()));

  std::vector<Name> manifests;
  manager.downloadTorrentFile("/test");
  manager.findFileManifestsToDownload(manifests);

  BOOST_CHECK_EQUAL(manifests[0].toUri(), "/manifest1");
  BOOST_CHECK_EQUAL(manifests[1].toUri(), "/manifest2");
  BOOST_CHECK_EQUAL(manifests[2].toUri(), "/manifest3");
  BOOST_CHECK_EQUAL(manifests[3].toUri(), "/manifest4");
  BOOST_CHECK_EQUAL(manifests[4].toUri(), "/manifest5");

  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

// we do not have the torrent file
BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload2)
{
  std::string filePath = ".appdata/foo/";
  TestTorrentManager manager("NTORRENT/test/torrent-file/0/sha256digest",
                             filePath, face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  BOOST_CHECK_EQUAL(manager.findTorrentFileSegmentToDownload()->toUri(),
                    "/NTORRENT/test/torrent-file/0/sha256digest");

  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload1)
{
  std::string filePath = ".appdata/foo/";
  TestTorrentManager manager("NTORRENT/test/torrent-file/sha256digest",
                             filePath, face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  Name n1(Name("NTORRENT/test/file0"));
  n1.appendSequenceNumber(0);

  Name n2(Name("NTORRENT/test/file0"));
  n2.appendSequenceNumber(1);

  Name n3(Name("NTORRENT/test/file0"));
  n3.appendSequenceNumber(2);

  Name n4(Name("NTORRENT/test/file0"));
  n4.appendSequenceNumber(3);

  Name n5(Name("NTORRENT/test/file0"));
  n5.appendSequenceNumber(4);

  Name n6(Name("NTORRENT/test1/file0"));
  n6.appendSequenceNumber(0);

  Name n7(Name("NTORRENT/test1/file0"));
  n7.appendSequenceNumber(1);

  // In theory, this may not be correct, but here let's suck it up for the sake
  // of testing the function correctness
  Name n8(Name("NTORRENT/test1/file2"));
  n8.appendSequenceNumber(0);

  Name n9(Name("NTORRENT/test1/file2"));
  n9.appendSequenceNumber(1);

  FileManifest f1(n1, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n2));
  manager.pushFileManifestSegment(f1);

  FileManifest f2(n2, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n3));
  manager.pushFileManifestSegment(f2);

  FileManifest f3(n3, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n4));
  manager.pushFileManifestSegment(f3);

  FileManifest f4(n4, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n5));
  manager.pushFileManifestSegment(f4);

  FileManifest f5(n6, 50, Name("NTORRENT/test2"), {}, make_shared<Name>(n7));
  manager.pushFileManifestSegment(f5);

  FileManifest f6(n7, 50, Name("NTORRENT/test2"), {}, {});
  manager.pushFileManifestSegment(f6);

  FileManifest f7(n8, 50, Name("NTORRENT/test3"), {}, make_shared<Name>(n9));
  manager.pushFileManifestSegment(f7);

  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n2.toUri() + "/sha256digest"))->toUri(), n5.toUri());
  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n8.toUri() + "/sha256digest"))->toUri(), n9.toUri());
  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n5.toUri() + "/sha256digest"))->toUri(),
                                                               Name(n5.toUri() + "/sha256digest").toUri());
  BOOST_CHECK(!(manager.findManifestSegmentToDownload(Name(n7.toUri() + "/sha256digest"))));

  Name n10(Name("NTORRENT/test1/file1"));
  n10.appendSequenceNumber(1);
  n10 = Name(n10.toUri() + "/sha256digest");

  BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(n10)->toUri(), n10.toUri());
}

BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload2)
{
  vector<FileManifest> manifests;
  vector<TorrentFile>  torrentSegments;
  // for each file, the data packets
  std::vector<vector<Data>> fileData;
  std::string filePath = "tests/testdata/temp";
  // get torrent files and manifests
  {
    auto temp = TorrentFile::generate("tests/testdata/foo",
                                      1024,
                                      2048,
                                      8192,
                                      true);
    torrentSegments = temp.first;
    auto temp1      = temp.second;
    for (const auto& ms : temp1) {
      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      fileData.push_back(ms.second);
    }
  }
  // write the torrent segments and manifests to disk
  std::string dirPath = ".appdata/foo/";
  boost::filesystem::create_directories(dirPath);
  std::string torrentPath = dirPath + "torrent_files/";
  boost::filesystem::create_directories(torrentPath);
  auto fileNum = 0;
  for (const auto& t : torrentSegments) {
    fileNum++;
    auto filename = torrentPath + to_string(fileNum);
    io::save(t, filename);
  }

  auto manifestPath = dirPath + "manifests/";
  boost::filesystem::create_directory(manifestPath);
  for (const auto& m : manifests) {
    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
    boost::filesystem::create_directory(filename.parent_path());
    io::save(m, filename.string());
  }
  // Initialize manager
  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
                             filePath,
                             face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  // Set the file state
  std::vector<bool> v1 = {true};
  manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);

  std::vector<bool> v2 = {false, true, true, false, false, false};
  manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);

  std::vector<bool> v3 = {true, false, false, false, false, false};
  manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);

  manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
                                [&manifests](const std::vector<ndn::Name>& vec) {
                                      BOOST_CHECK_EQUAL(vec.size(), 0);
                                },
                                [](const ndn::Name& name, const std::string& reason) {
                                  BOOST_FAIL("Unexpected failure");
                                });

  manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
                                 [&manifests](const std::vector<ndn::Name>& vec) {
                                   BOOST_CHECK_EQUAL(vec[0].toUri(),
                                                     manifests[1].catalog()[0].toUri());
                                   BOOST_CHECK_EQUAL(vec[1].toUri(),
                                                     manifests[1].catalog()[3].toUri());
                                   BOOST_CHECK_EQUAL(vec[2].toUri(),
                                                     manifests[1].catalog()[4].toUri());
                                   BOOST_CHECK_EQUAL(vec[3].toUri(),
                                                     manifests[1].catalog()[5].toUri());
                                 },
                                 [](const ndn::Name& name, const std::string& reason) {
                                   BOOST_FAIL("Unexpected failure");
                                 });

  manager.download_file_manifest(manifests[2].getFullName(), filePath + "manifests",
                                 [&manifests](const std::vector<ndn::Name>& vec) {
                                   BOOST_CHECK_EQUAL(vec[0].toUri(),
                                                     manifests[2].catalog()[1].toUri());
                                   BOOST_CHECK_EQUAL(vec[1].toUri(),
                                                     manifests[2].catalog()[2].toUri());
                                   BOOST_CHECK_EQUAL(vec[2].toUri(),
                                                     manifests[2].catalog()[3].toUri());
                                   BOOST_CHECK_EQUAL(vec[3].toUri(),
                                                     manifests[2].catalog()[4].toUri());
                                   BOOST_CHECK_EQUAL(vec[4].toUri(),
                                                     manifests[2].catalog()[5].toUri());
                                 },
                                 [](const ndn::Name& name, const std::string& reason) {
                                   BOOST_FAIL("Unexpected failure");
                                 });
  fs::remove_all(filePath);
  fs::remove_all(".appdata");
}

BOOST_AUTO_TEST_CASE(TestDataAlreadyDownloaded)
{
  vector<FileManifest> manifests;
  vector<TorrentFile>  torrentSegments;
  // for each file, the data packets
  std::vector<vector<Data>> fileData;
  std::string filePath = "tests/testdata/temp";
  // get torrent files and manifests
  {
    auto temp = TorrentFile::generate("tests/testdata/foo",
                                      1024,
                                      2048,
                                      8192,
                                      true);
    torrentSegments = temp.first;
    auto temp1      = temp.second;
    for (const auto& ms : temp1) {
      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      fileData.push_back(ms.second);
    }
  }
  // write the torrent segments and manifests to disk
  std::string dirPath = ".appdata/foo/";
  boost::filesystem::create_directories(dirPath);
  std::string torrentPath = dirPath + "torrent_files/";
  boost::filesystem::create_directories(torrentPath);
  auto fileNum = 0;
  for (const auto& t : torrentSegments) {
    fileNum++;
    auto filename = torrentPath + to_string(fileNum);
    io::save(t, filename);
  }

  auto manifestPath = dirPath + "manifests/";
  boost::filesystem::create_directory(manifestPath);
  for (const auto& m : manifests) {
    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
    boost::filesystem::create_directory(filename.parent_path());
    io::save(m, filename.string());
  }
  // Initialize manager
  TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
                             filePath,
                             face);

  manager.Initialize();
  BOOST_CHECK(manager.hasAllTorrentSegments());

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  // Set the file state
  std::vector<bool> v1 = {true};
  manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);

  std::vector<bool> v2 = {false, true, true, false, false, false};
  manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);

  std::vector<bool> v3 = {true, false, false, false, false, false};
  manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);

  Name p1("NTORRENT/foo/bar1.txt");
  p1.appendSequenceNumber(0);
  p1.appendSequenceNumber(0);
  p1 = Name(p1.toUri() + "/sha256digest");

  BOOST_CHECK(!(manager.hasDataPacket(p1)));

  Name p2("NTORRENT/foo/bar.txt");
  p2.appendSequenceNumber(0);
  p2.appendSequenceNumber(0);
  p2 = Name(p2.toUri() + "/sha256digest");

  BOOST_CHECK(manager.hasDataPacket(p2));
}

BOOST_AUTO_TEST_CASE(CheckSeedComplete)
{
   const struct {
       const char    *d_directoryPath;
       const char    *d_initialSegmentName;
       size_t         d_namesPerSegment;
       size_t         d_subManifestSize;
       size_t         d_dataPacketSize;
   } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
     {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128,  128, 128},
     // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851",   1,    1, 128},
   };
   enum { NUM_DATA = sizeof DATA / sizeof *DATA };
   for (int i = 0; i < NUM_DATA; ++i) {
     auto directoryPath      = DATA[i].d_directoryPath;
     Name initialSegmentName = DATA[i].d_initialSegmentName;
     auto namesPerSegment    = DATA[i].d_namesPerSegment;
     auto dataPacketSize     = DATA[i].d_dataPacketSize;
     auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<FileManifest> manifests;
    vector<TorrentFile> torrentSegments;
    std::string filePath = "tests/testdata/";
    std::vector<vector<Data>> fileData;
    // get torrent files and manifests
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
      auto temp1      = temp.second;
      for (const auto& ms : temp1) {
        manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
        fileData.push_back(ms.second);
      }
    }
    // write the torrent segments  and manifests to disk
    std::string dirPath = ".appdata/foo/";
    boost::filesystem::create_directories(dirPath);
    std::string torrentPath = dirPath + "torrent_files/";
    boost::filesystem::create_directory(torrentPath);
    auto fileNum = 0;
    for (const auto& t : torrentSegments) {
      fileNum++;
      auto filename = torrentPath + to_string(fileNum);
      io::save(t, filename);
    }
    auto manifestPath = dirPath + "manifests/";
    boost::filesystem::create_directory(manifestPath);
    for (const auto& m : manifests) {
      fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
      boost::filesystem::create_directories(filename.parent_path());
      io::save(m, filename.string());
    }
    // Initialize and verify
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    size_t nData = 0;
    BOOST_CHECK_EQUAL(0, face->sentData.size());
    // request all the torrent segments
    for (const auto& t : torrentSegments) {
      Interest interest(t.getFullName(), time::milliseconds(50));
      face->expressInterest(interest,
                            [&t](const Interest& i, const Data& d) {
                              TorrentFile t1(d.wireEncode());
                              BOOST_CHECK(t  == d);
                              BOOST_CHECK(t1 == t);
                            },
                            bind([] {
                              BOOST_FAIL("Unexpected Nack");
                            }),
                            bind([] {
                              BOOST_FAIL("Unexpected timeout");
                            }));
      advanceClocks(time::milliseconds(1), 40);
      face->receive(interest);
      manager.processEvents(time::milliseconds(-1));
      // check that one piece of data is sent, and it is what was expected
      BOOST_CHECK_EQUAL(++nData, face->sentData.size());
      face->receive(face->sentData[nData - 1]);
    }
    // request all the file manifests
    for (const auto& m : manifests) {
      Interest interest(m.getFullName(), time::milliseconds(50));
      face->expressInterest(interest,
                            [&m](const Interest& i, const Data& d) {
                              FileManifest m1(d.wireEncode());
                              BOOST_CHECK(m == d);
                              BOOST_CHECK(m1 == m);
                            },
                             bind([] {
                               BOOST_FAIL("Unexpected Nack");
                             }),
                             bind([] {
                               BOOST_FAIL("Unexpected timeout");
                             }));
      advanceClocks(time::milliseconds(1), 40);
      face->receive(interest);
      manager.processEvents(time::milliseconds(-1));
      // check that one piece of data is sent, and it is what was expected
      BOOST_CHECK_EQUAL(++nData, face->sentData.size());
      face->receive(face->sentData[nData - 1]);
    }
    // request all the data packets
    for (const auto& file : fileData) {
      for (const auto& data : file) {
      Interest interest(data.getFullName(), time::milliseconds(50));
      face->expressInterest(interest,
                            [&data](const Interest& i, const Data& d) {
                              BOOST_CHECK(data == d);
                            },
                             bind([] {
                               BOOST_FAIL("Unexpected Nack");
                             }),
                             bind([] {
                               BOOST_FAIL("Unexpected timeout");
                             }));
        advanceClocks(time::milliseconds(1), 40);
        face->receive(interest);
        manager.processEvents(time::milliseconds(-1));
        // check that one piece of data is sent, and it is what was expected
        BOOST_CHECK_EQUAL(++nData, face->sentData.size());
        face->receive(face->sentData[nData - 1]);
      }
    }
    // clean up tests
    face->sentData.clear();
    fs::remove_all(".appdata/");
  }
}

BOOST_AUTO_TEST_CASE(CheckSeedRandom)
{
  vector<FileManifest> manifests;
  vector<TorrentFile>  torrentSegments;
  // for each file, the data packets
  std::vector<Data> data;
  std::string filePath = "tests/testdata/";
  std::string dirPath = ".appdata/foo/";
  Name initialSegmentName = "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253";
  // get torrent files and manifests
  {
    auto temp = TorrentFile::generate("tests/testdata/foo",
                                      1024,
                                      1024,
                                      1024,
                                      true);
    torrentSegments = temp.first;
    auto temp1      = temp.second;
    for (const auto& ms : temp1) {
      manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      data.insert(data.end(), ms.second.begin(), ms.second.end());
    }
  }
  // write the torrent segments and manifests to disk
  boost::filesystem::create_directories(dirPath);
  auto torrentPath = dirPath + "torrent_files/";
  boost::filesystem::create_directories(torrentPath);
  auto fileNum = 0;
  for (const auto& t : torrentSegments) {
    fileNum++;
    auto filename = torrentPath + to_string(fileNum);
    io::save(t, filename);
  }
  auto manifestPath = dirPath + "manifests/";
  boost::filesystem::create_directory(manifestPath);
  for (const auto& m : manifests) {
    fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
    boost::filesystem::create_directory(filename.parent_path());
    io::save(m, filename.string());
  }

  // Initialize manager
  TestTorrentManager manager(initialSegmentName,
                             filePath,
                             face);

  manager.Initialize();

  advanceClocks(time::milliseconds(1), 10);
  manager.sendRoutablePrefixResponse();

  // insert the other entities
  data.insert(data.end(), torrentSegments.begin(), torrentSegments.end());
  data.insert(data.end(), manifests.begin(), manifests.end());

  std::random_shuffle(data.begin(), data.end());
  // request all the data packets
  auto nData = 0;
  for(const auto& d : data) {
    Interest interest(d.getFullName(), time::milliseconds(50));
    face->expressInterest(interest,
                          [&d](const Interest& i, const Data& data) {
                            BOOST_CHECK(data == d);
                          },
                          bind([] {
                            BOOST_FAIL("Unexpected Nack");
                          }),
                          bind([] {
                            BOOST_FAIL("Unexpected timeout");
                          }));
    advanceClocks(time::milliseconds(1), 40);
    face->receive(interest);
    manager.processEvents(time::milliseconds(-1));
    // check that one piece of data is sent, and it is what was expected
    BOOST_CHECK_EQUAL(++nData, face->sentData.size());
    face->receive(face->sentData[nData - 1]);
  }
  fs::remove_all(".appdata");
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE(CheckTorrentManagerUtilities, FaceFixture)

BOOST_AUTO_TEST_CASE(CheckWriteDataComplete)
{
  const struct {
      const char    *d_directoryPath;
      const char    *d_initialSegmentName;
      size_t         d_namesPerSegment;
      size_t         d_subManifestSize;
      size_t         d_dataPacketSize;
  } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128,  128, 128},
  };
  enum { NUM_DATA = sizeof DATA / sizeof *DATA };
  for (int i = 0; i < NUM_DATA; ++i) {
    auto directoryPath      = DATA[i].d_directoryPath;
    Name initialSegmentName = DATA[i].d_initialSegmentName;
    auto namesPerSegment    = DATA[i].d_namesPerSegment;
    auto dataPacketSize     = DATA[i].d_dataPacketSize;
    auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<TorrentFile>  torrentSegments;
    vector<FileManifest> manifests;
    // for each file, the data packets
    std::vector<vector<Data>> fileData;
    std::string filePath = "tests/testdata/temp";
    // get torrent files and manifests
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
      auto temp1      = temp.second;
      for (const auto& ms : temp1) {
        manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
        fileData.push_back(ms.second);
      }
    }
    // write the torrent segments and manifests to disk
    std::string dirPath = ".appdata/foo/";
    boost::filesystem::create_directories(dirPath);
    std::string torrentPath = dirPath + "torrent_files/";
    boost::filesystem::create_directories(torrentPath);
    auto fileNum = 0;
    for (const auto& t : torrentSegments) {
      fileNum++;
      auto filename = torrentPath + to_string(fileNum);
      io::save(t, filename);
    }
    auto manifestPath = dirPath + "manifests/";
    boost::filesystem::create_directory(manifestPath);
    for (const auto& m : manifests) {
      fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
      boost::filesystem::create_directory(filename.parent_path());
      io::save(m, filename.string());
    }
    // Initialize manager
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    // check that initially there is no data on disk
    for (auto m : manager.fileManifests()) {
      auto fileState = manager.fileState(m.getFullName());
      BOOST_CHECK(fileState.empty());
    }
    // write all data to disk (for each file manifest)
    auto manifest_it = manifests.begin();
    for (auto& data : fileData) {
      for (auto& d : data) {
        BOOST_CHECK(manager.writeData(d));
      }
      // check that the state is updated appropriately
      auto fileState = manager.fileState(manifest_it->getFullName());
      for (auto s : fileState) {
        BOOST_CHECK(s);
      }
      ++manifest_it;
    }
    // get the file names (ascending)
    std::set<std::string> fileNames;
    for (auto i = fs::recursive_directory_iterator(filePath + "/foo");
         i != fs::recursive_directory_iterator();
         ++i) {
      fileNames.insert(i->path().string());
    }
    // verify file by file that the data packets are written correctly
    auto f_it = fileData.begin();
    for (auto f : fileNames) {
      // read file from disk
      std::vector<uint8_t> file_bytes;
      fs::ifstream is(f, fs::ifstream::binary | fs::ifstream::in);
      is >> std::noskipws;
      std::istream_iterator<uint8_t> start(is), end;
      file_bytes.insert(file_bytes.end(), start, end);
      std::vector<uint8_t> data_bytes;
      // get content from data packets
      for (const auto& d : *f_it) {
        auto content = d.getContent();
        data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
      }
      BOOST_CHECK(data_bytes == file_bytes);
      ++f_it;
    }
    fs::remove_all(filePath);
    fs::remove_all(".appdata");
  }
}

BOOST_AUTO_TEST_CASE(CheckWriteTorrentComplete)
{
  const struct {
      const char    *d_directoryPath;
      const char    *d_initialSegmentName;
      size_t         d_namesPerSegment;
      size_t         d_subManifestSize;
      size_t         d_dataPacketSize;
  } DATA [] = {
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
    {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=96d900d6788465f9a7b00191581b004c910d74b3762d141ec0e82173731bc9f4",    1,    1, 1024},
  };
  enum { NUM_DATA = sizeof DATA / sizeof *DATA };
  for (int i = 0; i < NUM_DATA; ++i) {
    auto directoryPath      = DATA[i].d_directoryPath;
    Name initialSegmentName = DATA[i].d_initialSegmentName;
    auto namesPerSegment    = DATA[i].d_namesPerSegment;
    auto dataPacketSize     = DATA[i].d_dataPacketSize;
    auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<TorrentFile>  torrentSegments;
    std::string filePath = "tests/testdata/temp";
    // get torrent files
    {
      auto temp = TorrentFile::generate(directoryPath,
                                        namesPerSegment,
                                        subManifestSize,
                                        dataPacketSize,
                                        false);
      torrentSegments = temp.first;
    }
    // Initialize manager
    TestTorrentManager manager(initialSegmentName,
                               filePath,
                               face);

    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    std::string dirPath = ".appdata/foo/";
    std::string torrentPath = dirPath + "torrent_files/";
    BOOST_CHECK(manager.torrentSegments().empty());
    for (const auto& t : torrentSegments) {
      BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
    }
    BOOST_CHECK(manager.torrentSegments() == torrentSegments);
    // check that initializing a new manager also gets all the torrent torrentSegments
    TestTorrentManager manager2(initialSegmentName,
                                filePath,
                                face);

    manager2.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager2.sendRoutablePrefixResponse();

    BOOST_CHECK(manager2.torrentSegments() == torrentSegments);

    // start anew
    fs::remove_all(torrentPath);
    fs::create_directories(torrentPath);
    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    BOOST_CHECK(manager.torrentSegments().empty());

    // check that there is no dependence on the order of torrent segments
    // randomize the order of the torrent segments
    auto torrentSegmentsRandom = torrentSegments;
    std::random_shuffle(torrentSegmentsRandom.begin(), torrentSegmentsRandom.end());
    for (const auto& t : torrentSegmentsRandom) {
      BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
    }
    BOOST_CHECK(manager.torrentSegments() == torrentSegments);
    fs::remove_all(".appdata");
  }
}

BOOST_AUTO_TEST_CASE(CheckWriteManifestComplete)
{
  std::string dirPath = ".appdata/foo/";
  std::string torrentPath = dirPath + "torrent_files/";
  std::string manifestPath = dirPath + "manifests/";

  const struct {
     const char    *d_directoryPath;
     const char    *d_initialSegmentName;
     size_t         d_namesPerSegment;
     size_t         d_subManifestSize;
     size_t         d_dataPacketSize;
  } DATA [] = {
   {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
   {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",     128,  128, 1024},
  };
  enum { NUM_DATA = sizeof DATA / sizeof *DATA };
  for (int i = 0; i < NUM_DATA; ++i) {
    auto directoryPath      = DATA[i].d_directoryPath;
    Name initialSegmentName = DATA[i].d_initialSegmentName;
    auto namesPerSegment    = DATA[i].d_namesPerSegment;
    auto dataPacketSize     = DATA[i].d_dataPacketSize;
    auto subManifestSize    = DATA[i].d_subManifestSize;

    vector<FileManifest> manifests;
    vector<TorrentFile>  torrentSegments;

    std::string filePath = "tests/testdata/temp";
    // get torrent files and manifests
    {
       auto temp = TorrentFile::generate(directoryPath,
                                         namesPerSegment,
                                         subManifestSize,
                                         dataPacketSize,
                                         false);
      torrentSegments = temp.first;
      auto temp1      = temp.second;
      for (const auto& ms : temp1) {
        manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
      }
    }
    TestTorrentManager manager(initialSegmentName,
                              filePath,
                              face);

    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    for (const auto& t : torrentSegments) {
      manager.writeTorrentSegment(t, torrentPath);
    }

    BOOST_CHECK(manager.fileManifests().empty());
    for (const auto& m : manifests) {
      BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
    }
    BOOST_CHECK(manager.fileManifests() == manifests);

    TestTorrentManager manager2(initialSegmentName,
                                filePath,
                                face);

    manager2.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager2.sendRoutablePrefixResponse();

    BOOST_CHECK(manager2.fileManifests() == manifests);

    // start anew
    fs::remove_all(manifestPath);
    fs::create_directories(manifestPath);
    manager.Initialize();

    advanceClocks(time::milliseconds(1), 10);
    manager.sendRoutablePrefixResponse();

    BOOST_CHECK(manager.fileManifests().empty());

    // check that there is no dependence on the order of torrent segments
    // randomize the order of the torrent segments
    auto fileManifestsRandom = manifests;
    std::random_shuffle(fileManifestsRandom.begin(), fileManifestsRandom.end());
    for (const auto& m : fileManifestsRandom) {
      BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
    }
    BOOST_CHECK(manager2.fileManifests() == manifests);
    fs::remove_all(".appdata");
  }
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace nTorrent
} // namespace ndn
