/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2021,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of ndn-tools (Named Data Networking Essential Tools).
 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
 *
 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * ndn-tools 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 * @author Zhuo Li <zhuoli@email.arizona.edu>
 * @author Davide Pesavento <davidepesa@gmail.com>
 */

#include "ndnpeek.hpp"
#include "core/version.hpp"

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

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

#include <cerrno>
#include <cstring>
#include <fstream>

namespace ndn {
namespace peek {

namespace po = boost::program_options;

static void
usage(std::ostream& os, const std::string& program, const po::options_description& options)
{
  os << "Usage: " << program << " [options] /name\n"
     << "\n"
     << "Fetch one data item matching the specified name and write it to the standard output.\n"
     << options;
}

static std::ifstream
openBinaryFile(const std::string& filename)
{
  std::ifstream file(filename, std::ios::binary);
  if (!file) {
    std::cerr << "ERROR: cannot open '" << filename << "' for reading: "
              << std::strerror(errno) << std::endl;
  }
  return file;
}

static int
main(int argc, char* argv[])
{
  std::string progName(argv[0]);
  PeekOptions options;

  po::options_description genericOptDesc("Generic options");
  genericOptDesc.add_options()
    ("help,h",    "print help and exit")
    ("payload,p", po::bool_switch(&options.wantPayloadOnly),
                  "print payload only, instead of full packet")
    ("timeout,w", po::value<time::milliseconds::rep>(), "execution timeout, in milliseconds")
    ("verbose,v", po::bool_switch(&options.isVerbose), "turn on verbose output")
    ("version,V", "print version and exit")
  ;

  po::options_description interestOptDesc("Interest construction");
  interestOptDesc.add_options()
    ("prefix,P",   po::bool_switch(&options.canBePrefix), "set CanBePrefix")
    ("fresh,f",    po::bool_switch(&options.mustBeFresh), "set MustBeFresh")
    ("link-file",  po::value<std::string>(), "set ForwardingHint from a raw binary file")
    ("lifetime,l", po::value<time::milliseconds::rep>()->default_value(options.interestLifetime.count()),
                   "set InterestLifetime, in milliseconds")
    ("hop-limit,H",     po::value<int>(), "set HopLimit")
    ("app-params,A",    po::value<std::string>(), "set ApplicationParameters from a base64-encoded string")
    ("app-params-file", po::value<std::string>(), "set ApplicationParameters from a file")
  ;

  po::options_description visibleOptDesc;
  visibleOptDesc.add(genericOptDesc).add(interestOptDesc);

  po::options_description hiddenOptDesc;
  hiddenOptDesc.add_options()
    ("name", po::value<std::string>(), "Interest name");

  po::options_description optDesc;
  optDesc.add(visibleOptDesc).add(hiddenOptDesc);

  po::positional_options_description optPos;
  optPos.add("name", -1);

  po::variables_map vm;
  try {
    po::store(po::command_line_parser(argc, argv).options(optDesc).positional(optPos).run(), vm);
    po::notify(vm);
  }
  catch (const po::error& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return 2;
  }

  if (vm.count("help") > 0) {
    usage(std::cout, progName, visibleOptDesc);
    return 0;
  }

  if (vm.count("version") > 0) {
    std::cout << "ndnpeek " << tools::VERSION << std::endl;
    return 0;
  }

  if (vm.count("name") == 0) {
    std::cerr << "ERROR: missing name\n\n";
    usage(std::cerr, progName, visibleOptDesc);
    return 2;
  }

  try {
    options.name = vm["name"].as<std::string>();
  }
  catch (const Name::Error& e) {
    std::cerr << "ERROR: invalid name: " << e.what() << std::endl;
    return 2;
  }

  if (vm.count("timeout") > 0) {
    options.timeout = time::milliseconds(vm["timeout"].as<time::milliseconds::rep>());
    if (*options.timeout < 0_ms) {
      std::cerr << "ERROR: timeout cannot be negative" << std::endl;
      return 2;
    }
  }

  if (vm.count("link-file") > 0) {
    auto filename = vm["link-file"].as<std::string>();
    std::ifstream linkFile = openBinaryFile(filename);
    if (!linkFile) {
      return 2;
    }
    options.link = io::load<Link>(linkFile, io::NO_ENCODING);
    if (!options.link) {
      std::cerr << "ERROR: cannot parse a valid Link object from file '" << filename << "'" << std::endl;
      return 2;
    }
  }

  options.interestLifetime = time::milliseconds(vm["lifetime"].as<time::milliseconds::rep>());
  if (options.interestLifetime < 0_ms) {
    std::cerr << "ERROR: InterestLifetime cannot be negative" << std::endl;
    return 2;
  }

  if (vm.count("hop-limit") > 0) {
    auto hopLimit = vm["hop-limit"].as<int>();
    if (hopLimit < 0 || hopLimit > 255) {
      std::cerr << "ERROR: HopLimit must be between 0 and 255" << std::endl;
      return 2;
    }
    options.hopLimit = static_cast<uint8_t>(hopLimit);
  }

  if (vm.count("app-params") > 0) {
    if (vm.count("app-params-file") > 0) {
      std::cerr << "ERROR: cannot specify both '--app-params' and '--app-params-file'" << std::endl;
      return 2;
    }
    std::istringstream is(vm["app-params"].as<std::string>());
    try {
      options.applicationParameters = io::loadBuffer(is, io::BASE64);
    }
    catch (const io::Error& e) {
      std::cerr << "ERROR: invalid ApplicationParameters string: " << e.what() << std::endl;
      return 2;
    }
  }

  if (vm.count("app-params-file") > 0) {
    auto filename = vm["app-params-file"].as<std::string>();
    std::ifstream paramsFile = openBinaryFile(filename);
    if (!paramsFile) {
      return 2;
    }
    try {
      options.applicationParameters = io::loadBuffer(paramsFile, io::NO_ENCODING);
    }
    catch (const io::Error& e) {
      std::cerr << "ERROR: cannot read ApplicationParameters from file '" << filename
                << "': " << e.what() << std::endl;
      return 2;
    }
  }

  try {
    Face face;
    NdnPeek program(face, options);

    program.start();
    face.processEvents();

    return static_cast<int>(program.getResult());
  }
  catch (const std::exception& e) {
    std::cerr << "ERROR: " << e.what() << std::endl;
    return 1;
  }
}

} // namespace peek
} // namespace ndn

int
main(int argc, char* argv[])
{
  return ndn::peek::main(argc, argv);
}
