/* -*- 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. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS for complete list of nTorrent authors and contributors.
*/

#include "boost-test.hpp"

#include "torrent-file.hpp"
#include "file-manifest.hpp"

#include <ndn-cxx/data.hpp>
#include <ndn-cxx/signature.hpp>
#include <ndn-cxx/security/key-chain.hpp>

#include <boost/range/adaptors.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>

namespace fs = boost::filesystem;

namespace ndn {

namespace ntorrent {

namespace tests {


const static uint8_t TorrentFileTest[] = {
  0x6, 0xfd, // data
  0x1, 0xea,
     0x7, 0x2c, // name
        0x8, 0x8,
           0x4e, 0x54, 0x4f, 0x52, 0x52, 0x45, 0x4e, 0x54,
        0x8, 0xa,
           0x6c, 0x69, 0x6e, 0x75, 0x78, 0x31, 0x35, 0x2e, 0x30, 0x31,
        0x8, 0xc,
           0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x69, 0x6c, 0x65,
        0x8, 0x6,
           0x41, 0x42, 0x32, 0x43, 0x44, 0x41,
      0x14, 0x0, // meta-info
      0x15, 0x76,  // content
          0x7, 0x36,
             0x8, 0x8,
                0x4e, 0x54, 0x4f, 0x52, 0x52, 0x45, 0x4e, 0x54,
             0x8, 0xa,
                0x6c, 0x69, 0x6e, 0x75, 0x78, 0x31, 0x35, 0x2e, 0x30, 0x31,
             0x8, 0xc,
                0x74, 0x6f, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x2d, 0x66, 0x69, 0x6c, 0x65,
             0x8, 0x8,
                0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x32,
             0x8, 0x6,
                0x41, 0x45, 0x33, 0x32, 0x31, 0x43,
          0x7, 0x16,
             0x8, 0x8,
                0x4e, 0x54, 0x4f, 0x52, 0x52, 0x45, 0x4e, 0x54,
             0x8, 0xa,
                0x6c, 0x69, 0x6e, 0x75, 0x78, 0x31, 0x35, 0x2e, 0x30, 0x31,
          0x7, 0x11,
             0x8, 0x5,
                0x66, 0x69, 0x6c, 0x65, 0x30,
             0x8, 0x8,
                0x31, 0x41, 0x32, 0x42, 0x33, 0x43, 0x34, 0x44,
          0x7, 0x11,
             0x8, 0x5,
                0x66, 0x69, 0x6c, 0x65, 0x31,
             0x8, 0x8,
                0x32, 0x41, 0x33, 0x42, 0x34, 0x43, 0x35, 0x45,
      0x16, 0x3c, // SignatureInfo
          0x1b, 0x1, // SignatureType
              0x1,
          0x1c, 0x37, // KeyLocator
              0x7, 0x35,
                 0x8, 0xc,
                    0x74, 0x6d, 0x70, 0x2d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
                 0x8, 0x4,
                    0x3d, 0xa8, 0x2c, 0x19,
                 0x8, 0x3,
                    0x4b, 0x45, 0x59,
                 0x8, 0x11,
                    0x6b, 0x73, 0x6b, 0x2d, 0x31, 0x34, 0x35, 0x34, 0x39, 0x37, 0x33, 0x38,
                    0x37, 0x36, 0x31, 0x37, 0x31,
                 0x8, 0x7,
                    0x49, 0x44, 0x2d, 0x43, 0x45, 0x52, 0x54,
      0x17, 0xfd, // SignatureValue
          0x1, 0x0, 0x3d, 0xb6, 0x32, 0x59, 0xbd, 0xe5, 0xad, 0x27, 0x1b, 0xc2, 0x68,
          0x3d, 0x7a, 0xd3, 0x4e, 0xf, 0x40, 0xa5, 0xf8, 0x80, 0x4b, 0xf2, 0xf9, 0xb1,
          0x7, 0xea, 0x56, 0x84, 0xd, 0x94, 0xd, 0xf9, 0x88, 0xd4, 0xe0, 0xb6, 0x63, 0xac,
          0x3a, 0xdc, 0x17, 0xc2, 0xff, 0xde, 0xc, 0xc3, 0xef, 0xb, 0x3b, 0x1a, 0xef, 0xb,
          0x7, 0x99, 0x9b, 0xb7, 0xe6, 0x4a, 0x68, 0xf8, 0xda, 0x62, 0x29, 0xfd, 0xb1, 0xb1,
          0xe9, 0xe3, 0x3a, 0x42, 0x1f, 0xbd, 0xad, 0x96, 0xc4, 0x5f, 0x34, 0x55, 0x9, 0xba,
          0x7a, 0x82, 0x2d, 0x9c, 0x7b, 0x52, 0x9d, 0xf, 0xd6, 0xea, 0xc3, 0x60, 0xbf, 0x75,
          0xfb, 0x0, 0x1b, 0xb8, 0x4, 0xa8, 0x6e, 0x95, 0x5a, 0xcf, 0xca, 0x90, 0x20, 0x21,
          0x58, 0x27, 0x2c, 0xef, 0xed, 0x23, 0x37, 0xfa, 0xd, 0xc6, 0x3, 0x7b, 0xd6, 0xef,
          0x76, 0x3, 0xd7, 0x22, 0xd8, 0x6f, 0xa2, 0x7d, 0xc2, 0x84, 0xee, 0x65, 0xbf, 0x63,
          0xe2, 0x27, 0xc4, 0xeb, 0xb7, 0xb2, 0xa6, 0xa0, 0x58, 0x68, 0x1a, 0x3a, 0x85, 0xd8,
          0x8d, 0xd8, 0xfb, 0x52, 0x9b, 0xba, 0x22, 0x2d, 0xb2, 0x4b, 0x9e, 0x3d, 0xf5, 0x61,
          0x83, 0x6f, 0x78, 0x67, 0x85, 0x3d, 0xf, 0x24, 0x47, 0xbf, 0x8c, 0xdf, 0xdf, 0x8a,
          0xc8, 0xa9, 0xed, 0xaf, 0x8b, 0x49, 0xdf, 0x2d, 0x2a, 0xfe, 0x2f, 0x4b, 0xc5, 0xe6,
          0x7e, 0xee, 0x35, 0xf1, 0x6, 0x88, 0x9c, 0xa0, 0x25, 0xf, 0x6, 0x56, 0xf4, 0x72,
          0x89, 0x2f, 0x95, 0x64, 0x39, 0x38, 0x21, 0xc3, 0x75, 0xef, 0x80, 0x5a, 0x73, 0x1a,
          0xec, 0xb9, 0x6d, 0x3, 0x47, 0xac, 0x64, 0x7f, 0x85, 0xbe, 0xb9, 0xab, 0x87, 0x9f,
          0xd2, 0x9c, 0xe7, 0x9c, 0x86, 0xd5, 0x59, 0x65, 0x73, 0x24, 0x15, 0x3e, 0xfc, 0x94,
          0xf8, 0x7, 0x26, 0x9b, 0x4f, 0x6e, 0x1b, 0x1c
};

BOOST_AUTO_TEST_SUITE(TestTorrentFile)

BOOST_AUTO_TEST_CASE(CheckGettersSetters)
{

  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C",
                   "/NTORRENT/linux15.01",
                   {"/NTORRENT/linux15.01/file0/1A2B3C4D",
                   "/NTORRENT/linux15.01/file1/2A3B4C5E"});

  BOOST_CHECK_EQUAL(file.getName(), "/NTORRENT/linux15.01/torrent-file/AB2CDA");
  BOOST_CHECK_EQUAL(file.getCatalog().size(), 2);
  BOOST_CHECK_EQUAL(*(file.getTorrentFilePtr()),
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C");
  BOOST_CHECK_EQUAL(file.getCatalog()[0], "/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file.getCatalog()[1], "/NTORRENT/linux15.01/file1/2A3B4C5E");

  TorrentFile file2("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                    "/NTORRENT/linux15.01",
                    {"/NTORRENT/linux15.01/file0/1A2B3C4D"});

  BOOST_CHECK_EQUAL(file2.getName(), "/NTORRENT/linux15.01/torrent-file/AB2CDA");
  BOOST_CHECK(!file2.getTorrentFilePtr());
  BOOST_CHECK_EQUAL(file2.getCatalog().size(), 1);
}

BOOST_AUTO_TEST_CASE(CheckEncodeDecode)
{
  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C",
                   "/NTORRENT/linux15.01",
                   {"/NTORRENT/linux15.01/file0/1A2B3C4D",
                   "/NTORRENT/linux15.01/file1/2A3B4C5E"});

  file.finalize();
  KeyChain keyChain;
  keyChain.sign(file);

  Block wire = file.wireEncode();

  TorrentFile file2;
  file2.wireDecode(wire);

  BOOST_CHECK_EQUAL(file2.getName(), "/NTORRENT/linux15.01/torrent-file/AB2CDA");
  BOOST_CHECK_EQUAL(*(file2.getTorrentFilePtr()),
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C");
  BOOST_CHECK_EQUAL(file2.getCatalog().size(), 2);
  BOOST_CHECK_EQUAL(file2.getCatalog()[0], "/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file2.getCatalog()[1], "/NTORRENT/linux15.01/file1/2A3B4C5E");
  BOOST_CHECK_EQUAL(file2.getCommonPrefix(), "/NTORRENT/linux15.01");
}

BOOST_AUTO_TEST_CASE(CheckEncodeDecodeNoTorrentFilePtr)
{
  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                   "/NTORRENT/linux15.01",
                   {"/NTORRENT/linux15.01/file0/1A2B3C4D",
                   "/NTORRENT/linux15.01/file1/2A3B4C5E"});

  file.finalize();
  KeyChain keyChain;
  keyChain.sign(file);

  Block wire = file.wireEncode();

  TorrentFile file2;
  file2.wireDecode(wire);

  BOOST_CHECK_EQUAL(file2.getName(), "/NTORRENT/linux15.01/torrent-file/AB2CDA");
  BOOST_CHECK(!file2.getTorrentFilePtr());
  BOOST_CHECK_EQUAL(file2.getCatalog().size(), 2);
  BOOST_CHECK_EQUAL(file2.getCatalog()[0], "/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file2.getCatalog()[1], "/NTORRENT/linux15.01/file1/2A3B4C5E");
}

BOOST_AUTO_TEST_CASE(CheckEncodeDecodeEmptyTorrentFile)
{
  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                  "",
                  {});

  file.finalize();
  KeyChain keyChain;
  keyChain.sign(file);

  Block wire = file.wireEncode();

  TorrentFile file2;

  BOOST_REQUIRE_THROW(file2.wireDecode(wire), TorrentFile::Error);
}


BOOST_AUTO_TEST_CASE(CheckEncodeDecodeEmptyCatalog)
{

  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                  "/NTORRENT/linux15.01/torrent-file/segment2/AE321C",
                  "/NTORRENT/linux15.01",
                  {});

  file.finalize();
  KeyChain keyChain;
  keyChain.sign(file);

  Block wire = file.wireEncode();

  TorrentFile file2;

  BOOST_REQUIRE_THROW(file2.wireDecode(wire), TorrentFile::Error);
}

BOOST_AUTO_TEST_CASE(DecodeFromWire)
{

  Block TorrentFileBlock(TorrentFileTest, sizeof(TorrentFileTest));
  TorrentFile file(TorrentFileBlock);

  BOOST_CHECK_EQUAL(file.getName(), "/NTORRENT/linux15.01/torrent-file/AB2CDA");
  BOOST_CHECK_EQUAL(*(file.getTorrentFilePtr()),
                    "/NTORRENT/linux15.01/torrent-file/segment2/AE321C");
  BOOST_CHECK_EQUAL(file.getCatalog().size(), 2);
  BOOST_CHECK_EQUAL(file.getCatalog()[0], "/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file.getCatalog()[1], "/NTORRENT/linux15.01/file1/2A3B4C5E");
  BOOST_CHECK_EQUAL(file.getCommonPrefix(), "/NTORRENT/linux15.01");
}

BOOST_AUTO_TEST_CASE(TestInsertErase)
{
  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C",
                   "/NTORRENT/linux15.01",
                   {"/NTORRENT/linux15.01/file0/1A2B3C4D",
                   "/NTORRENT/linux15.01/file1/2A3B4C5E"});

  file.erase("/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file.getCatalog()[0], "/NTORRENT/linux15.01/file1/2A3B4C5E");

  file.erase("/NTORRENT/linux15.01/file1/2A3B4C5E");
  BOOST_CHECK_EQUAL(file.getCatalog().size(), 0);

  file.insert("/NTORRENT/linux15.01/file3/AB34C5KA");
  BOOST_CHECK_EQUAL(file.getCatalog().size(), 1);
  BOOST_CHECK_EQUAL(file.getCatalog()[0], "/NTORRENT/linux15.01/file3/AB34C5KA");
}

BOOST_AUTO_TEST_CASE(TestInsertAndEncodeTwice)
{
  TorrentFile file("/NTORRENT/linux15.01/torrent-file/AB2CDA",
                   "/NTORRENT/linux15.01/torrent-file/segment2/AE321C",
                   "/NTORRENT/linux15.01",
                   {"/NTORRENT/linux15.01/file0/1A2B3C4D",
                   "/NTORRENT/linux15.01/file1/2A3B4C5E"});

  file.finalize();
  KeyChain keyChain;
  keyChain.sign(file);
  Block wire = file.wireEncode();

  TorrentFile file2;
  file2.wireDecode(wire);
  BOOST_CHECK_EQUAL(file2.getCatalog().size(), 2);

  file.insert("/NTORRENT/linux15.01/file3/AB34C5KA");
  file.insert("/NTORRENT/linux15.01/file4/CB24C3GB");
  file.finalize();
  Block wire2 = file.wireEncode();

  file2.wireDecode(wire2);
  BOOST_CHECK_EQUAL(file2.getCatalog().size(), 4);

  BOOST_CHECK_EQUAL(file2.getCatalog()[0], "/NTORRENT/linux15.01/file0/1A2B3C4D");
  BOOST_CHECK_EQUAL(file2.getCatalog()[1], "/NTORRENT/linux15.01/file1/2A3B4C5E");
  BOOST_CHECK_EQUAL(file2.getCatalog()[2], "/NTORRENT/linux15.01/file3/AB34C5KA");
  BOOST_CHECK_EQUAL(file2.getCatalog()[3], "/NTORRENT/linux15.01/file4/CB24C3GB");
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_CASE(TestTorrentFileGenerator)
{
  const struct {
      size_t         d_dataPacketSize;
      size_t         d_subManifestSize;
      const char     *d_directoryPath;
      size_t         d_namesPerSegment;
      bool           d_shouldThrow;
  } DATA [] = {
    // Affirmative tests
    {1024           , 100          , "tests/testdata/foo" , 1, false },
    {512            , 80           , "tests/testdata/foo" , 3, false },
    {256            , 50           , "tests/testdata/foo" , 2, false },
    {2048           , 20           , "tests/testdata/foo" , 4, false },
    {512            , 80           , "tests/testdata/foo" , 1, false },
    {1024           , 50           , "tests/testdata/foo" , 1, false },
    {2048           , 128          , "tests/testdata/foo",  2, false },
    // Negative tests
    // non-existent directory
    {128          , 128            , "tests/testdata/foo-fake", 2, true },
  };
  enum { NUM_DATA = sizeof DATA / sizeof *DATA };
  for (int i = 0; i < NUM_DATA; ++i) {
    auto dataPacketSize  = DATA[i].d_dataPacketSize;
    auto subManifestSize = DATA[i].d_subManifestSize;
    auto directoryPath   = DATA[i].d_directoryPath;
    auto namesPerSegment = DATA[i].d_namesPerSegment;
    auto shouldThrow     = DATA[i].d_shouldThrow;


    std::pair<std::vector<TorrentFile>,
              std::vector<std::pair<std::vector<FileManifest>,
                                    std::vector<Data>>>> torrentFilePair1;

    std::pair<std::vector<TorrentFile>,
              std::vector<std::pair<std::vector<FileManifest>,
                                    std::vector<Data>>>> torrentFilePair2;

    if (shouldThrow) {
      BOOST_REQUIRE_THROW(TorrentFile::generate(directoryPath,
                                              namesPerSegment,
                                              subManifestSize,
                                              dataPacketSize),
                          TorrentFile::Error);

      BOOST_REQUIRE_THROW(TorrentFile::generate(directoryPath,
                                                namesPerSegment,
                                                subManifestSize,
                                                dataPacketSize,
                                                true),
                          TorrentFile::Error);
    }
    else {
      torrentFilePair1 = TorrentFile::generate(directoryPath,
                                              namesPerSegment,
                                              subManifestSize,
                                              dataPacketSize);

      torrentFilePair2 = TorrentFile::generate(directoryPath,
                                              namesPerSegment,
                                              subManifestSize,
                                              dataPacketSize,
                                              true);

      auto torrentFileSegments = torrentFilePair1.first;
      auto manifestPairs1 = torrentFilePair1.second;
      auto manifestPairs2 = torrentFilePair2.second;

      // Check that generate has not returned any data packets unless otherwise specified
      for (auto i = manifestPairs1.begin(); i != manifestPairs1.end(); ++i) {
        BOOST_CHECK_EQUAL((*i).second.size(), 0);
      }

      Name directoryPathName(directoryPath);
      fs::recursive_directory_iterator directoryPtr(fs::system_complete(directoryPath).string());
      int numberOfDirectoryFiles = 0;
      for (fs::recursive_directory_iterator i = directoryPtr;
           i != fs::recursive_directory_iterator(); ++i) {
        numberOfDirectoryFiles++;
      }
      // Verify the basic attributes of the torrent-file
      for (auto it = torrentFileSegments.begin(); it != torrentFileSegments.end(); ++it) {
        // Verify that each file torrent-file is signed
        BOOST_CHECK_NO_THROW(it->getFullName());
        BOOST_CHECK_EQUAL(it->getCommonPrefix(),
                          Name("/NTORRENT" +
                               directoryPathName.getSubName(
                                 directoryPathName.size() - 1).toUri()));
        if (it != torrentFileSegments.end() - 1) {
          BOOST_CHECK_EQUAL(it->getCatalog().size(), namesPerSegment);
          BOOST_CHECK_EQUAL(*(it->getTorrentFilePtr()), (it+1)->getFullName());
        }
        else {
          BOOST_CHECK_LE(it->getCatalog().size(), subManifestSize);
          BOOST_CHECK(!(it->getTorrentFilePtr()));
        }
      }
      int myDiv = (numberOfDirectoryFiles / namesPerSegment);
      if (numberOfDirectoryFiles % namesPerSegment == 0) {
        BOOST_CHECK_EQUAL(torrentFileSegments.size(), myDiv);
      }
      else {
        BOOST_CHECK_EQUAL(torrentFileSegments.size(), (myDiv + 1));
      }

      std::vector<uint8_t> dataBytes;
      for (auto i = manifestPairs2.begin() ; i != manifestPairs2.end(); ++i) {
        for (auto d : (*i).second) {
          auto content = d.getContent();
          dataBytes.insert(dataBytes.end(), content.value_begin(), content.value_end());
        }
      }
      // load  the contents of the directory files from disk
      std::vector<uint8_t> directoryFilesBytes;
      fs::recursive_directory_iterator directoryPtr2(fs::system_complete(directoryPath).string());
      for (fs::recursive_directory_iterator i = directoryPtr2;
           i != fs::recursive_directory_iterator();
           ++i) {
        fs::ifstream is((*i), fs::ifstream::binary | fs::ifstream::in);
        is >> std::noskipws;
        std::istream_iterator<uint8_t> start(is), end;
        std::vector<uint8_t> fileBytes(start, end);
        directoryFilesBytes.insert(directoryFilesBytes.end(), fileBytes.begin(), fileBytes.end());
      }
      // confirm that they are equal
      BOOST_CHECK_EQUAL_COLLECTIONS(directoryFilesBytes.begin(), directoryFilesBytes.end(),
                                    dataBytes.begin(), dataBytes.end());
    }
  }
}

} // namespace tests

} // namespace ntorrent

} // namespace ndn
