/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014  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
 *
 * 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 <getopt.h>
#include <boost/filesystem.hpp>

#include "version.hpp"
#include "core/logger.hpp"
#include "core/global-io.hpp"
#include "core/privilege-helper.hpp"
#include "fw/forwarder.hpp"
#include "mgmt/internal-face.hpp"
#include "mgmt/fib-manager.hpp"
#include "mgmt/face-manager.hpp"
#include "mgmt/strategy-choice-manager.hpp"
#include "mgmt/status-server.hpp"
#include "core/config-file.hpp"
#include "mgmt/general-config-section.hpp"

namespace nfd {

NFD_LOG_INIT("NFD");

struct ProgramOptions
{
  bool showUsage;
  bool showVersion;
  bool showModules;
  std::string config;
};

class Nfd : noncopyable
{
public:
  explicit
  Nfd(const std::string& configFile)
    : m_configFile(configFile)
    , m_originalStreamBuf(0)
  {
  }

  ~Nfd()
  {
    if (static_cast<bool>(m_originalStreamBuf)) {
      std::clog.rdbuf(m_originalStreamBuf);
    }
  }

  void
  initialize()
  {
    initializeLogging();

    m_forwarder = make_shared<Forwarder>();

    initializeManagement();

    PrivilegeHelper::drop();
  }


  void
  initializeLogging()
  {
    ConfigFile config(&ConfigFile::ignoreUnknownSection);
    LoggerFactory::getInstance().setConfigFile(config);

    config.parse(m_configFile, true);
    config.parse(m_configFile, false);
  }

  class IgnoreRibAndLogSections
  {
  public:
    void
    operator()(const std::string& filename,
               const std::string& sectionName,
               const ConfigSection& section,
               bool isDryRun)

    {
      // Ignore "log" and sections beginning with "rib_" (intended for rib manager),
      // but raise an error if we're missing a handler for an NFD section.

      if (sectionName.find("rib") == 0 || sectionName == "log")
        {
          // do nothing
        }
      else
        {
          // missing NFD section
          ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun);
        }
    }
  };

  void
  initializeManagement()
  {
    m_internalFace = make_shared<InternalFace>();

    m_fibManager = make_shared<FibManager>(ref(m_forwarder->getFib()),
                                           bind(&Forwarder::getFace, m_forwarder.get(), _1),
                                           m_internalFace);

    m_faceManager = make_shared<FaceManager>(ref(m_forwarder->getFaceTable()),
                                             m_internalFace);

    m_strategyChoiceManager =
      make_shared<StrategyChoiceManager>(ref(m_forwarder->getStrategyChoice()),
                                         m_internalFace);

    m_statusServer = make_shared<StatusServer>(m_internalFace,
                                               ref(*m_forwarder));

    ConfigFile config((IgnoreRibAndLogSections()));

    general::setConfigFile(config);
    m_internalFace->getValidator().setConfigFile(config);

    m_forwarder->addFace(m_internalFace);

    m_faceManager->setConfigFile(config);

    // parse config file
    config.parse(m_configFile, true);
    config.parse(m_configFile, false);

    // add FIB entry for NFD Management Protocol
    shared_ptr<fib::Entry> entry = m_forwarder->getFib().insert("/localhost/nfd").first;
    entry->addNextHop(m_internalFace, 0);
  }

  static void
  printUsage(std::ostream& os, const std::string& programName)
  {
    os << "Usage: \n"
       << "  " << programName << " [options]\n"
       << "\n"
       << "Run NFD forwarding daemon\n"
       << "\n"
       << "Options:\n"
       << "  [--help]    - print this help message\n"
       << "  [--version] - print version and exit\n"
       << "  [--modules] - list available logging modules\n"
       << "  [--config /path/to/nfd.conf] - path to configuration file "
       << "(default: " << DEFAULT_CONFIG_FILE << ")\n"
      ;
  }

  static void
  printModules(std::ostream& os)
  {
    using namespace std;

    os << "Available logging modules: \n";

    list<string> modules(LoggerFactory::getInstance().getModules());
    for (list<string>::const_iterator i = modules.begin(); i != modules.end(); ++i)
      {
        os << *i << "\n";
      }
  }

  static bool
  parseCommandLine(int argc, char** argv, ProgramOptions& options)
  {
    options.showUsage = false;
    options.showVersion = false;
    options.showModules = false;
    options.config = DEFAULT_CONFIG_FILE;

    while (true) {
      int optionIndex = 0;
      static ::option longOptions[] = {
        { "help"   , no_argument      , 0, 0 },
        { "modules", no_argument      , 0, 0 },
        { "config" , required_argument, 0, 0 },
        { "version", no_argument      , 0, 0 },
        { 0        , 0                , 0, 0 }
      };
      int c = getopt_long_only(argc, argv, "", longOptions, &optionIndex);
      if (c == -1)
        break;

      switch (c) {
      case 0:
        switch (optionIndex) {
        case 0: // help
          options.showUsage = true;
          break;
        case 1: // modules
          options.showModules = true;
          break;
        case 2: // config
          options.config = ::optarg;
          break;
        case 3: // version
          options.showVersion = true;
          break;
        default:
          return false;
        }
        break;
      }
    }
    return true;
  }

  void
  terminate(const boost::system::error_code& error,
            int signalNo,
            boost::asio::signal_set& signalSet)
  {
    if (error)
      return;

    if (signalNo == SIGINT ||
        signalNo == SIGTERM)
      {
        getGlobalIoService().stop();
        NFD_LOG_INFO("Caught signal '" << strsignal(signalNo) << "', exiting...");
      }
    else
      {
        signalSet.async_wait(bind(&Nfd::terminate, this, _1, _2, ref(signalSet)));
      }
  }

  void
  reload(const boost::system::error_code& error,
         int signalNo,
         boost::asio::signal_set& signalSet)
  {
    if (error)
      return;

    NFD_LOG_INFO("Caught signal '" << strsignal(signalNo));

    ////////////////////////
    // Reload config file //
    ////////////////////////

    // Logging
    initializeLogging();
    /// \todo Reopen log file

    // Other stuff
    ConfigFile config((IgnoreRibAndLogSections()));

    general::setConfigFile(config);

    m_internalFace->getValidator().setConfigFile(config);
    m_faceManager->setConfigFile(config);

    config.parse(m_configFile, false);

    ////////////////////////

    signalSet.async_wait(bind(&Nfd::reload, this, _1, _2, ref(signalSet)));
  }

private:
  std::string m_configFile;

  shared_ptr<Forwarder> m_forwarder;

  shared_ptr<InternalFace>          m_internalFace;
  shared_ptr<FibManager>            m_fibManager;
  shared_ptr<FaceManager>           m_faceManager;
  shared_ptr<StrategyChoiceManager> m_strategyChoiceManager;
  shared_ptr<StatusServer>          m_statusServer;

  shared_ptr<std::ofstream>         m_logFile;
  std::basic_streambuf<char>*       m_originalStreamBuf;
};

} // namespace nfd

int
main(int argc, char** argv)
{
  using namespace nfd;

  ProgramOptions options;
  bool isCommandLineValid = Nfd::parseCommandLine(argc, argv, options);
  if (!isCommandLineValid) {
    Nfd::printUsage(std::cerr, argv[0]);
    return 1;
  }

  if (options.showUsage) {
    Nfd::printUsage(std::cout, argv[0]);
    return 0;
  }

  if (options.showVersion) {
    std::cout << NFD_VERSION_BUILD_STRING << std::endl;
    return 0;
  }

  if (options.showModules) {
    Nfd::printModules(std::cout);
    return 0;
  }

  Nfd nfdInstance(options.config);

  try {
    nfdInstance.initialize();
  }
  catch (boost::filesystem::filesystem_error& e) {
    if (e.code() == boost::system::errc::permission_denied) {
      NFD_LOG_FATAL("Permissions denied for " << e.path1() << ". " <<
                    argv[0] << " should be run as superuser");
    }
    else {
      NFD_LOG_FATAL(e.what());
    }
    return 1;
  }
  catch (const std::exception& e) {
    NFD_LOG_FATAL(e.what());
    return 2;
  }
  catch (const PrivilegeHelper::Error& e) {
    // PrivilegeHelper::Errors do not inherit from std::exception
    // and represent seteuid/gid failures

    NFD_LOG_FATAL(e.what());
    return 3;
  }

  boost::asio::signal_set terminationSignalSet(getGlobalIoService());
  terminationSignalSet.add(SIGINT);
  terminationSignalSet.add(SIGTERM);
  terminationSignalSet.async_wait(bind(&Nfd::terminate, &nfdInstance, _1, _2,
                                       ref(terminationSignalSet)));

  boost::asio::signal_set reloadSignalSet(getGlobalIoService());
  reloadSignalSet.add(SIGHUP);
  reloadSignalSet.async_wait(bind(&Nfd::reload, &nfdInstance, _1, _2,
                                  ref(reloadSignalSet)));

  try {
    getGlobalIoService().run();
  }
  catch (const std::exception& e) {
    NFD_LOG_FATAL(e.what());
    return 4;
  }
  catch (const PrivilegeHelper::Error& e) {
    NFD_LOG_FATAL(e.what());
    return 5;
  }

  return 0;
}
