/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2017,  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 "core/network.hpp"
#include "core/version.hpp"

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/mgmt/nfd/controller.hpp>
#include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
#include <ndn-cxx/mgmt/nfd/face-status.hpp>
#include <ndn-cxx/net/face-uri.hpp>
#include <ndn-cxx/security/key-chain.hpp>

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

#include <iostream>

namespace ndn {
namespace nfd_autoreg {

using ::nfd::Network;

class AutoregServer : boost::noncopyable
{
public:
  AutoregServer()
    : m_controller(m_face, m_keyChain)
    , m_faceMonitor(m_face)
    , m_cost(255)
  {
  }

  void
  onRegisterCommandSuccess(uint64_t faceId, const Name& prefix)
  {
    std::cerr << "SUCCEED: register " << prefix << " on face " << faceId << std::endl;
  }

  void
  onRegisterCommandFailure(uint64_t faceId, const Name& prefix,
                           const nfd::ControlResponse& response)
  {
    std::cerr << "FAILED: register " << prefix << " on face " << faceId
              << " (code: " << response.getCode() << ", reason: " << response.getText() << ")"
              << std::endl;
  }

  /**
   * \return true if uri has schema allowed to do auto-registrations
   */
  bool
  hasAllowedSchema(const FaceUri& uri)
  {
    const std::string& scheme = uri.getScheme();
    return (scheme == "udp4" || scheme == "tcp4" ||
            scheme == "udp6" || scheme == "tcp6");
  }

  /**
   * \return true if address is blacklisted
   */
  bool
  isBlacklisted(const boost::asio::ip::address& address)
  {
    return std::any_of(m_blackList.begin(), m_blackList.end(),
                       bind(&Network::doesContain, _1, address));
  }

  /**
   * \return true if address is whitelisted
   */
  bool
  isWhitelisted(const boost::asio::ip::address& address)
  {
    return std::any_of(m_whiteList.begin(), m_whiteList.end(),
                       bind(&Network::doesContain, _1, address));
  }

  void
  registerPrefixesForFace(uint64_t faceId, const std::vector<Name>& prefixes)
  {
    for (const Name& prefix : prefixes) {
      m_controller.start<nfd::RibRegisterCommand>(
        nfd::ControlParameters()
          .setName(prefix)
          .setFaceId(faceId)
          .setOrigin(nfd::ROUTE_ORIGIN_AUTOREG)
          .setCost(m_cost)
          .setExpirationPeriod(time::milliseconds::max()),
        bind(&AutoregServer::onRegisterCommandSuccess, this, faceId, prefix),
        bind(&AutoregServer::onRegisterCommandFailure, this, faceId, prefix, _1));
    }
  }

  void
  registerPrefixesIfNeeded(uint64_t faceId, const FaceUri& uri, nfd::FacePersistency facePersistency)
  {
    if (hasAllowedSchema(uri)) {
      boost::system::error_code ec;
      boost::asio::ip::address address = boost::asio::ip::address::from_string(uri.getHost(), ec);

      if (!address.is_multicast()) {
        // register all-face prefixes
        registerPrefixesForFace(faceId, m_allFacesPrefixes);

        // register autoreg prefixes if new face is on-demand and not blacklisted and whitelisted
        if (facePersistency == nfd::FACE_PERSISTENCY_ON_DEMAND &&
            !isBlacklisted(address) && isWhitelisted(address)) {
          registerPrefixesForFace(faceId, m_autoregPrefixes);
        }
      }
    }
  }

  void
  onNotification(const nfd::FaceEventNotification& notification)
  {
    if (notification.getKind() == nfd::FACE_EVENT_CREATED &&
        notification.getFaceScope() != nfd::FACE_SCOPE_LOCAL) {
      std::cerr << "PROCESSING: " << notification << std::endl;

      registerPrefixesIfNeeded(notification.getFaceId(), FaceUri(notification.getRemoteUri()),
                               notification.getFacePersistency());
    }
    else {
      std::cerr << "IGNORED: " << notification << std::endl;
    }
  }

  void
  signalHandler()
  {
    m_face.shutdown();
  }

  void
  usage(std::ostream& os,
        const boost::program_options::options_description& desc,
        const char* programName)
  {
    os << "Usage:\n"
       << "  " << programName << " --prefix=</autoreg/prefix> [--prefix=/another/prefix] ...\n"
       << "\n";
    os << desc;
  }

  void
  startProcessing()
  {
    std::cerr << "AUTOREG prefixes: " << std::endl;
    for (const Name& prefix : m_autoregPrefixes) {
      std::cout << "  " << prefix << std::endl;
    }
    std::cerr << "ALL-FACES-AUTOREG prefixes: " << std::endl;
    for (const Name& prefix : m_allFacesPrefixes) {
      std::cout << "  " << prefix << std::endl;
    }

    if (!m_blackList.empty()) {
      std::cerr << "Blacklisted networks: " << std::endl;
      for (const Network& network : m_blackList) {
        std::cout << "  " << network << std::endl;
      }
    }

    std::cerr << "Whitelisted networks: " << std::endl;
    for (const Network& network : m_whiteList) {
      std::cout << "  " << network << std::endl;
    }

    m_faceMonitor.onNotification.connect(bind(&AutoregServer::onNotification, this, _1));
    m_faceMonitor.start();

    boost::asio::signal_set signalSet(m_face.getIoService(), SIGINT, SIGTERM);
    signalSet.async_wait(bind(&AutoregServer::signalHandler, this));

    m_face.processEvents();
  }

  void
  startFetchingFaceStatusDataset()
  {
    m_controller.fetch<nfd::FaceDataset>(
      [this] (const std::vector<nfd::FaceStatus>& faces) {
        for (const auto& faceStatus : faces) {
          registerPrefixesIfNeeded(faceStatus.getFaceId(), FaceUri(faceStatus.getRemoteUri()),
                                   faceStatus.getFacePersistency());
        }
      },
      [] (uint32_t code, const std::string& reason) {});
  }

  int
  main(int argc, char* argv[])
  {
    namespace po = boost::program_options;

    po::options_description optionDesciption;
    optionDesciption.add_options()
      ("help,h", "produce help message")
      ("prefix,i", po::value<std::vector<Name>>(&m_autoregPrefixes)->composing(),
       "prefix that should be automatically registered when new a remote non-local face is "
       "established")
      ("all-faces-prefix,a", po::value<std::vector<Name>>(&m_allFacesPrefixes)->composing(),
       "prefix that should be automatically registered for all TCP and UDP non-local faces "
       "(blacklists and whitelists do not apply to this prefix)")
      ("cost,c", po::value<uint64_t>(&m_cost)->default_value(255),
       "FIB cost which should be assigned to autoreg nexthops")
      ("whitelist,w", po::value<std::vector<Network>>(&m_whiteList)->composing(),
       "Whitelisted network, e.g., 192.168.2.0/24 or ::1/128")
      ("blacklist,b", po::value<std::vector<Network>>(&m_blackList)->composing(),
       "Blacklisted network, e.g., 192.168.2.32/30 or ::1/128")
      ("version,V", "show version and exit")
      ;

    po::variables_map options;
    try {
      po::store(po::command_line_parser(argc, argv).options(optionDesciption).run(), options);
      po::notify(options);
    }
    catch (const std::exception& e) {
      std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
      usage(std::cerr, optionDesciption, argv[0]);
      return 1;
    }

    if (options.count("help")) {
      usage(std::cout, optionDesciption, argv[0]);
      return 0;
    }

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

    if (m_autoregPrefixes.empty() && m_allFacesPrefixes.empty()) {
      std::cerr << "ERROR: at least one --prefix or --all-faces-prefix must be specified"
                << std::endl << std::endl;
      usage(std::cerr, optionDesciption, argv[0]);
      return 2;
    }

    if (m_whiteList.empty()) {
      // Allow everything
      m_whiteList.push_back(Network::getMaxRangeV4());
      m_whiteList.push_back(Network::getMaxRangeV6());
    }

    try {
      startFetchingFaceStatusDataset();
      startProcessing();
    }
    catch (const std::exception& e) {
      std::cerr << "ERROR: " << e.what() << std::endl;
      return 2;
    }

    return 0;
  }

private:
  Face m_face;
  KeyChain m_keyChain;
  nfd::Controller m_controller;
  nfd::FaceMonitor m_faceMonitor;
  std::vector<Name> m_autoregPrefixes;
  std::vector<Name> m_allFacesPrefixes;
  uint64_t m_cost;
  std::vector<Network> m_whiteList;
  std::vector<Network> m_blackList;
};

} // namespace nfd_autoreg
} // namespace ndn

int
main(int argc, char* argv[])
{
  ndn::nfd_autoreg::AutoregServer server;
  return server.main(argc, argv);
}
