/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  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 NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "status-main.hpp"
#include "core/version.hpp"
#include "status-report.hpp"
#include "forwarder-general-module.hpp"
#include "channel-module.hpp"
#include "face-module.hpp"
#include "fib-module.hpp"
#include "rib-module.hpp"
#include "strategy-choice-module.hpp"

#include <ndn-cxx/security/validator-null.hpp>
#include <boost/program_options.hpp>

namespace nfd {
namespace tools {
namespace nfdc {

struct Options
{
  ReportFormat output = ReportFormat::TEXT;
  bool wantForwarderGeneral = false;
  bool wantChannels = false;
  bool wantFaces = false;
  bool wantFib = false;
  bool wantRib = false;
  bool wantStrategyChoice = false;
};

static void
showUsage(std::ostream& os, const boost::program_options::options_description& cmdOptions)
{
  os << "Usage: nfd-status [options]\n\n"
     << "Show NFD version and status information.\n\n"
     << cmdOptions;
}

/** \brief parse command line, and show usage if necessary
 *  \return if first item is -1, caller should retrieve and display StatusReport;
 *          otherwise, caller should immediately exit with the specified exit code
 */
static std::tuple<int, Options>
parseCommandLine(int argc, const char* const* argv)
{
  Options options;

  namespace po = boost::program_options;
  po::options_description cmdOptions("Options");
  cmdOptions.add_options()
    ("help,h", "print this help message")
    ("version,V", "show program version")
    ("general,v", po::bool_switch(&options.wantForwarderGeneral), "show general status")
    ("channels,c", po::bool_switch(&options.wantChannels), "show channels")
    ("faces,f", po::bool_switch(&options.wantFaces), "show faces")
    ("fib,b", po::bool_switch(&options.wantFib), "show FIB entries")
    ("rib,r", po::bool_switch(&options.wantRib), "show RIB routes")
    ("sc,s", po::bool_switch(&options.wantStrategyChoice), "show strategy choice entries")
    ("xml,x", "output as XML instead of text (implies -vcfbrs)");
  po::variables_map vm;
  try {
    po::store(po::parse_command_line(argc, argv, cmdOptions), vm);
  }
  catch (const po::error& e) {
    std::cerr << e.what() << "\n";
    showUsage(std::cerr, cmdOptions);
    return std::make_tuple(2, options);
  }
  po::notify(vm);

  if (vm.count("help") > 0) {
    showUsage(std::cout, cmdOptions);
    return std::make_tuple(0, options);
  }
  if (vm.count("version") > 0) {
    std::cout << "nfd-status " << NFD_VERSION_BUILD_STRING << "\n";
    return std::make_tuple(0, options);
  }

  if (vm.count("xml") > 0) {
    options.output = ReportFormat::XML;
  }
  if (options.output == ReportFormat::XML ||
      (!options.wantForwarderGeneral && !options.wantChannels && !options.wantFaces &&
       !options.wantFib && !options.wantRib && !options.wantStrategyChoice)) {
    options.wantForwarderGeneral = options.wantChannels = options.wantFaces =
      options.wantFib = options.wantRib = options.wantStrategyChoice = true;
  }

  return std::make_tuple(-1, options);
}

int
statusMain(int argc, char** argv)
{
  int exitCode = -1;
  Options options;
  std::tie(exitCode, options) = parseCommandLine(argc, argv);
  if (exitCode >= 0) {
    return exitCode;
  }

  Face face;
  KeyChain keyChain;
  unique_ptr<Validator> validator = make_unique<ndn::ValidatorNull>();
  CommandOptions ctrlOptions;

  StatusReport report;

  if (options.wantForwarderGeneral) {
    auto nfdIdCollector = make_unique<NfdIdCollector>(std::move(validator));
    auto forwarderGeneralModule = make_unique<ForwarderGeneralModule>();
    forwarderGeneralModule->setNfdIdCollector(*nfdIdCollector);
    report.sections.push_back(std::move(forwarderGeneralModule));
    validator = std::move(nfdIdCollector);
  }

  if (options.wantChannels) {
    report.sections.push_back(make_unique<ChannelModule>());
  }

  if (options.wantFaces) {
    report.sections.push_back(make_unique<FaceModule>());
  }

  if (options.wantFib) {
    report.sections.push_back(make_unique<FibModule>());
  }

  if (options.wantRib) {
    report.sections.push_back(make_unique<RibModule>());
  }

  if (options.wantStrategyChoice) {
    report.sections.push_back(make_unique<StrategyChoiceModule>());
  }

  uint32_t code = report.collect(face, keyChain, *validator, ctrlOptions);
  if (code != 0) {
    // Give a simple error code for end user.
    // Technical support personnel:
    // 1. get the exact command from end user
    // 2. code div 1000000 is zero-based section index
    // 3. code mod 1000000 is a Controller.fetch error code
    std::cerr << "Error while collecting status report (" << code << ").\n";
    return 1;
  }

  switch (options.output) {
    case ReportFormat::XML:
      report.formatXml(std::cout);
      break;
    case ReportFormat::TEXT:
      report.formatText(std::cout);
      break;
  }
  return 0;
}

} // namespace nfdc
} // namespace tools
} // namespace nfd
