/* -*- 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.
*/

#ifndef INCLUDED_UTIL_IO_UTIL_H
#define INCLUDED_UTIL_IO_UTIL_H

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

#include <ndn-cxx/data.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/io.hpp>

#include <set>
#include <string>
#include <vector>

namespace fs = boost::filesystem;

namespace ndn {
namespace ntorrent {

class TorrentFile;
class FileManifest;

class IoUtil {
 public:
  /*
   * An enum used to identify the type of content to which a name refers
   */
  enum NAME_TYPE
  {
    TORRENT_FILE,
    FILE_MANIFEST,
    DATA_PACKET,
    UNKNOWN
  };

  template<typename T>
  static std::vector<T>
  load_directory(const std::string& dirPath,
                 ndn::io::IoEncoding encoding = ndn::io::IoEncoding::BASE64);

  static std::vector<ndn::Data>
  packetize_file(const fs::path& filePath,
                 const ndn::Name& commonPrefix,
                 size_t dataPacketSize,
                 size_t subManifestSize,
                 size_t subManifestNum);

  /*
   * @brief Write the @p segment torrent segment to disk at the specified path.
   * @param segment The torrent file segment to be written to disk
   * @param path The path at which to write the torrent file segment
   * Write the segment to disk, return 'true' if data successfully written to disk 'false'
   * otherwise. Behavior is undefined unless @segment is a correct segment for the torrent file of
   * this manager and @p path is the directory used for all segments of this torrent file.
   */
  static bool
  writeTorrentSegment(const TorrentFile& segment, const std::string& path);

    /*
   * @brief Write the @p manifest file manifest to disk at the specified @p path.
   * @param manifest The file manifest  to be written to disk
   * @param path The path at which to write the file manifest
   * Write the file manifest to disk, return 'true' if data successfully written to disk 'false'
   * otherwise. Behavior is undefined unless @manifest is a correct file manifest for a file in the
   * torrent file of this manager and @p path is the directory used for all file manifests of this
   * torrent file.
   */
  static bool
  writeFileManifest(const FileManifest& manifest, const std::string& path);

  /*
   * @brief Write @p packet composed of torrent date to disk.
   * @param packet The data packet to be written to the disk
   * @param os The output stream to which to write
   * Write the Data packet to disk, return 'true' if data successfully written to disk 'false'
   * otherwise. Behavior is undefined unless the corresponding file manifest has already been
   * downloaded.
   */
  static bool
  writeData(const Data&         packet,
            const FileManifest& manifest,
            size_t              subManifestSize,
            fs::fstream&        os);

  /*
   * @brief Read a data packet from the provided stream
   * @param packetFullName The fullname of the expected Data packet
   * @param manifest The file manifest for the requested  Data packet
   * @param subManifestSize The number of Data packets in each catalog for this Data packet
   * @param is The stream from which to read the  packet
   * Read the data  packet from the @p is stream, validate it against the provided @p packetFullName
   * and @p manifest, if successful return a pointer to the packet, otherwise return nullptr.
   */
  static std::shared_ptr<Data>
  readDataPacket(const Name&         packetFullName,
                 const FileManifest& manifest,
                 size_t              subManifestSize,
                 fs::fstream&        is);

  /*
   * @brief Return the type of the specified name
   */
  static IoUtil::NAME_TYPE
  findType(const Name& name);

};

template<typename T>
inline std::vector<T>
IoUtil::load_directory(const std::string& dirPath,
                       ndn::io::IoEncoding encoding) {
  std::vector<T> structures;
  std::set<std::string> fileNames;
  if (fs::exists(dirPath)) {
    for(fs::recursive_directory_iterator it(dirPath);
      it !=  fs::recursive_directory_iterator();
      ++it)
    {
      fileNames.insert(it->path().string());
    }
    for (const auto& f : fileNames) {
      auto data_ptr = ndn::io::load<T>(f, encoding);
      if (nullptr != data_ptr) {
        structures.push_back(*data_ptr);
      }
    }
  }
  structures.shrink_to_fit();
  return structures;
}

} // namespace ntorrent
} // namespace ndn

#endif // INCLUDED_UTIL_IO_UTIL_H
