/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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 "common/global.hpp"
#include "face/face.hpp"
#include "face/tcp-channel.hpp"
#include "face/udp-channel.hpp"

#include <boost/exception/diagnostic_information.hpp>

#include <fstream>
#include <iostream>

#ifdef NFD_HAVE_VALGRIND
#include <valgrind/callgrind.h>
#endif

namespace nfd::tests {

class FaceBenchmark
{
public:
  explicit
  FaceBenchmark(const char* configFileName)
    : m_terminationSignalSet{getGlobalIoService(), SIGINT, SIGTERM}
    , m_tcpChannel{tcp::Endpoint{boost::asio::ip::tcp::v4(), 6363}, false,
                   [] (auto&&...) { return ndn::nfd::FACE_SCOPE_NON_LOCAL; }}
    , m_udpChannel{udp::Endpoint{boost::asio::ip::udp::v4(), 6363}, 10_min, false, ndn::MAX_NDN_PACKET_SIZE}
  {
    m_terminationSignalSet.async_wait([] (const auto& error, int) {
      if (!error)
        getGlobalIoService().stop();
    });

    parseConfig(configFileName);

    m_tcpChannel.listen(std::bind(&FaceBenchmark::onLeftFaceCreated, this, _1),
                        std::bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
    std::clog << "Listening on " << m_tcpChannel.getUri() << std::endl;

    m_udpChannel.listen(std::bind(&FaceBenchmark::onLeftFaceCreated, this, _1),
                        std::bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
    std::clog << "Listening on " << m_udpChannel.getUri() << std::endl;
  }

private:
  void
  parseConfig(const char* configFileName)
  {
    std::ifstream file{configFileName};
    std::string uriStrL;
    std::string uriStrR;

    while (file >> uriStrL >> uriStrR) {
      FaceUri uriL{uriStrL};
      FaceUri uriR{uriStrR};

      if (uriL.getScheme() != "tcp4" && uriL.getScheme() != "udp4") {
        std::clog << "Unsupported protocol '" << uriL.getScheme() << "'" << std::endl;
      }
      else if (uriR.getScheme() != "tcp4" && uriR.getScheme() != "udp4") {
        std::clog << "Unsupported protocol '" << uriR.getScheme() << "'" << std::endl;
      }
      else {
        m_faceUris.emplace_back(uriL, uriR);
      }
    }

    if (m_faceUris.empty()) {
      NDN_THROW(std::runtime_error("No supported FaceUri pairs found in config file"));
    }
  }

  void
  onLeftFaceCreated(const shared_ptr<Face>& faceL)
  {
    std::clog << "Left face created: remote=" << faceL->getRemoteUri()
              << " local=" << faceL->getLocalUri() << std::endl;

    // find a matching right uri
    FaceUri uriR;
    for (const auto& [first, second] : m_faceUris) {
      if (first.getHost() == faceL->getRemoteUri().getHost() &&
          first.getScheme() == faceL->getRemoteUri().getScheme()) {
        uriR = second;
      }
      else if (second.getHost() == faceL->getRemoteUri().getHost() &&
               second.getScheme() == faceL->getRemoteUri().getScheme()) {
        uriR = first;
      }
    }

    if (uriR == FaceUri()) {
      std::clog << "No FaceUri matched, ignoring..." << std::endl;
      faceL->close();
      return;
    }

    // create the right face
    auto addr = boost::asio::ip::address::from_string(uriR.getHost());
    auto port = boost::lexical_cast<uint16_t>(uriR.getPort());
    if (uriR.getScheme() == "tcp4") {
      m_tcpChannel.connect(tcp::Endpoint(addr, port), {},
                           std::bind(&FaceBenchmark::onRightFaceCreated, faceL, _1),
                           std::bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
    }
    else if (uriR.getScheme() == "udp4") {
      m_udpChannel.connect(udp::Endpoint(addr, port), {},
                           std::bind(&FaceBenchmark::onRightFaceCreated, faceL, _1),
                           std::bind(&FaceBenchmark::onFaceCreationFailed, _1, _2));
    }
  }

  static void
  onRightFaceCreated(const shared_ptr<Face>& faceL, const shared_ptr<Face>& faceR)
  {
    std::clog << "Right face created: remote=" << faceR->getRemoteUri()
              << " local=" << faceR->getLocalUri() << std::endl;

    tieFaces(faceR, faceL);
    tieFaces(faceL, faceR);
  }

  static void
  tieFaces(const shared_ptr<Face>& face1, const shared_ptr<Face>& face2)
  {
    face1->afterReceiveInterest.connect([face2] (const auto& interest, const EndpointId&) {
      face2->sendInterest(interest);
    });
    face1->afterReceiveData.connect([face2] (const auto& data, const EndpointId&) {
      face2->sendData(data);
    });
    face1->afterReceiveNack.connect([face2] (const auto& nack, const EndpointId&) {
      face2->sendNack(nack);
    });
  }

  [[noreturn]] static void
  onFaceCreationFailed(uint32_t status, const std::string& reason)
  {
    NDN_THROW(std::runtime_error("Failed to create face: [" + to_string(status) + "] " + reason));
  }

private:
  boost::asio::signal_set m_terminationSignalSet;
  face::TcpChannel m_tcpChannel;
  face::UdpChannel m_udpChannel;
  std::vector<std::pair<FaceUri, FaceUri>> m_faceUris;
};

} // namespace nfd::tests

int
main(int argc, char** argv)
{
#ifdef _DEBUG
  std::cerr << "Benchmark compiled in debug mode is unreliable, please compile in release mode.\n";
#endif

  if (argc != 2) {
    std::cerr << "Usage: " << argv[0] << " <config-file>" << std::endl;
    return 2;
  }

  try {
    nfd::tests::FaceBenchmark bench{argv[1]};
#ifdef NFD_HAVE_VALGRIND
    CALLGRIND_START_INSTRUMENTATION;
#endif
    nfd::getGlobalIoService().run();
  }
  catch (const std::exception& e) {
    std::cerr << "ERROR: " << boost::diagnostic_information(e);
    return 1;
  }

  return 0;
}
