/* -*- 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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128,  128, 128},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d",   1,  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<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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981",
                             "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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128,  128, 128},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d",   1,  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<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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128,  128, 128},
     {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d",   1,  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<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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
                             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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
                             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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
                             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("/ndn/multicast/NTORRENT/test/torrent-file/sha256digest",
                             filePath, face);

  manager.Initialize();

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

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

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

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

  TorrentFile t4(Name("/ndn/multicast/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("/ndn/multicast/NTORRENT/test/torrent-file/0/sha256digest",
                             filePath, face);

  manager.Initialize();

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

  BOOST_CHECK_EQUAL(manager.findTorrentFileSegmentToDownload()->toUri(),
                    "/ndn/multicast/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("/ndn/multicast/NTORRENT/test/torrent-file/sha256digest",
                             filePath, face);

  manager.Initialize();

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

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

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

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

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

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

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

  Name n7(Name("/ndn/multicast/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("/ndn/multicast/NTORRENT/test1/file2"));
  n8.appendSequenceNumber(0);

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

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

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

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

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

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

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

  FileManifest f7(n8, 50, Name("/ndn/multicast/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("/ndn/multicast/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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=6114e56874fc01bf8f9c40fa652741a895eb922372f1baf039ccea64dacd2152",
                             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("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=6114e56874fc01bf8f9c40fa652741a895eb922372f1baf039ccea64dacd2152",
                             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("/ndn/multicast/NTORRENT/foo/bar1.txt");
  p1.appendSequenceNumber(0);
  p1.appendSequenceNumber(0);
  p1 = Name(p1.toUri() + "/sha256digest");

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

  Name p2("/ndn/multicast/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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
      // {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128,  128, 128},
      // {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d",   1,  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<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,
                                        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_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 = "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981";
  // 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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
    {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
    // {"tests/testdata/foo", "/ndn/multicast/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", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
   {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981",     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
