/* -*- 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.md for complete list of nTorrent authors and contributors.
 */
#include "sequential-data-fetcher.hpp"
#include "torrent-file.hpp"
#include "util/io-util.hpp"
#include "util/logging.hpp"

#include <iostream>
#include <iterator>
#include <stdexcept>
#include <algorithm>

#include <boost/program_options.hpp>
#include <boost/program_options/errors.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>

namespace logging = boost::log;
namespace po = boost::program_options;

using namespace ndn;
using namespace ndn::ntorrent;

namespace ndn {

class Error : public std::runtime_error
{
public:
  explicit
  Error(const std::string& what)
    : runtime_error(what)
  {
  }
};

} // end ndn

// TODO(msweatt) Add options verification
int main(int argc, char *argv[])
{
  try {
   LoggingUtil::init();
   logging::add_common_attributes();

    po::options_description desc("Allowed options");
    desc.add_options()
    // TODO(msweatt) Consider  adding  flagged args for other parameters
      ("help,h", "produce help message")
      ("generate,g" , "-g <data directory> <output-path>? <names-per-segment>? <names-per-manifest-segment>? <data-packet-size>?")
      ("seed,s", "After download completes, continue to seed")
      ("dump,d", "-d <file> Dump the contents of the Data stored at the <file>.")
      ("args", po::value<std::vector<std::string> >(), "For arguments you want to specify without flags")
    ;
    po::positional_options_description p;
    p.add("args", -1);

    po::variables_map vm;
    po::store(po::command_line_parser(argc, argv).
              options(desc).allow_unregistered().positional(p).run(), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 1;
    }
    if (vm.count("args")) {
      auto args = vm["args"].as<std::vector<std::string>>();
      // if generate mode
      if (vm.count("generate")) {
        if (args.size() < 1 || args.size() > 5) {
          throw ndn::Error("wrong number of arguments for generate");
        }
        auto dataPath         = args[0];
        auto outputPath       = args.size() >= 2 ? args[1] : ".appdata/";
        auto namesPerSegment  = args.size() >= 3 ? boost::lexical_cast<size_t>(args[2]) : 1024;
        auto namesPerManifest = args.size() >= 4 ? boost::lexical_cast<size_t>(args[3]) : 1024;
        auto dataPacketSize   = args.size() == 5 ? boost::lexical_cast<size_t>(args[4]) : 1024;

        const auto& content = TorrentFile::generate(dataPath,
                                                    namesPerSegment,
                                                    namesPerManifest,
                                                    dataPacketSize);
        const auto& torrentSegments = content.first;
        std::vector<FileManifest> manifests;
        for (const auto& ms : content.second) {
          manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
        }
        auto torrentPrefix = fs::canonical(dataPath).filename().string();
        outputPath += torrentPrefix;
        auto torrentPath =  outputPath + "/torrent_files/";
        // write all the torrent segments
        for (const TorrentFile& t : torrentSegments) {
          if (!IoUtil::writeTorrentSegment(t, torrentPath)) {
            LOG_ERROR << "Write failed: " << t.getName() << std::endl;
            return -1;
          }
        }
        auto manifestPath = outputPath + "/manifests/";
        for (const FileManifest& m : manifests) {
          if (!IoUtil::writeFileManifest(m, manifestPath)) {
            LOG_ERROR << "Write failed: " << m.getName() << std::endl;
            return -1;
          }
        }
      }
      // if dump mode
      else if(vm.count("dump")) {
        if (args.size() != 1) {
          throw ndn::Error("wrong number of arguments for dump");
        }
        auto filePath = args[0];
        auto data = io::load<Data>(filePath);
        if (nullptr != data) {
          std::cout << data->getFullName() << std::endl;
        }
        else {
          throw ndn::Error("Invalid data.");
        }
      }
      // standard torrent mode
      else {
        // <torrent-file-name> <data-path>
        if (args.size() != 2) {
          throw ndn::Error("wrong number of arguments for torrent");
        }
        auto torrentName = args[0];
        auto dataPath    = args[1];
        auto seedFlag    = (vm.count("seed") != 0);
        SequentialDataFetcher fetcher(torrentName, dataPath, seedFlag);
        fetcher.start();
      }
    }
    else {
      std::cout << desc << std::endl;
      return 1;
    }
  }
  catch(std::exception& e) {
    std::cerr << "error: " << e.what() << "\n";
    return 1;
  }
  catch(...) {
    std::cerr << "Exception of unknown type!\n";
  }
  return 0;
}
