/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023, Arizona Board of Regents.
 *
 * This program 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.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 */

#include "util.hpp"

#include <ndn-cxx/data.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/interest.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/util/random.hpp>
#include <ndn-cxx/util/time.hpp>

#include <limits>
#include <optional>
#include <sstream>
#include <string_view>
#include <vector>

#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/noncopyable.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/variables_map.hpp>

using namespace ndn::time_literals;
using namespace std::string_literals;

namespace ndntg {

namespace time = ndn::time;

class NdnTrafficClient : boost::noncopyable
{
public:
  explicit
  NdnTrafficClient(const std::string& configFile)
    : m_signalSet(m_ioService, SIGINT, SIGTERM)
    , m_logger("NdnTrafficClient")
    , m_face(m_ioService)
    , m_configurationFile(configFile)
  {
  }

  void
  setMaximumInterests(uint64_t maxInterests)
  {
    m_nMaximumInterests = maxInterests;
  }

  void
  setInterestInterval(time::milliseconds interval)
  {
    BOOST_ASSERT(interval > 0_ms);
    m_interestInterval = interval;
  }

  void
  setQuietLogging()
  {
    m_wantQuiet = true;
  }

  int
  run()
  {
    m_logger.initializeLog(std::to_string(ndn::random::generateWord32()));

    if (!readConfigurationFile(m_configurationFile, m_trafficPatterns, m_logger)) {
      return 2;
    }

    if (!checkTrafficPatternCorrectness()) {
      m_logger.log("ERROR: Traffic configuration provided is not proper", false, true);
      return 2;
    }

    m_logger.log("Traffic configuration file processing completed.\n", true, false);
    for (std::size_t i = 0; i < m_trafficPatterns.size(); i++) {
      m_logger.log("Traffic Pattern Type #" + std::to_string(i + 1), false, false);
      m_trafficPatterns[i].printTrafficConfiguration(m_logger);
      m_logger.log("", false, false);
    }

    if (m_nMaximumInterests == 0) {
      logStatistics();
      return 0;
    }

    m_signalSet.async_wait([this] (auto&&...) { stop(); });

    boost::asio::deadline_timer timer(m_ioService,
                                      boost::posix_time::millisec(m_interestInterval.count()));
    timer.async_wait([this, &timer] (auto&&...) { generateTraffic(timer); });

    try {
      m_face.processEvents();
      return m_hasError ? 1 : 0;
    }
    catch (const std::exception& e) {
      m_logger.log("ERROR: "s + e.what(), true, true);
      m_ioService.stop();
      return 1;
    }
  }

private:
  class InterestTrafficConfiguration
  {
  public:
    void
    printTrafficConfiguration(Logger& logger) const
    {
      std::ostringstream os;

      os << "TrafficPercentage=" << m_trafficPercentage << ", ";
      os << "Name=" << m_name << ", ";
      if (m_nameAppendBytes) {
        os << "NameAppendBytes=" << *m_nameAppendBytes << ", ";
      }
      if (m_nameAppendSeqNum) {
        os << "NameAppendSequenceNumber=" << *m_nameAppendSeqNum << ", ";
      }
      if (m_canBePrefix) {
        os << "CanBePrefix=" << m_canBePrefix << ", ";
      }
      if (m_mustBeFresh) {
        os << "MustBeFresh=" << m_mustBeFresh << ", ";
      }
      if (m_nonceDuplicationPercentage > 0) {
        os << "NonceDuplicationPercentage=" << m_nonceDuplicationPercentage << ", ";
      }
      if (m_interestLifetime >= 0_ms) {
        os << "InterestLifetime=" << m_interestLifetime.count() << ", ";
      }
      if (m_nextHopFaceId > 0) {
        os << "NextHopFaceId=" << m_nextHopFaceId << ", ";
      }
      if (m_expectedContent) {
        os << "ExpectedContent=" << *m_expectedContent << ", ";
      }

      auto str = os.str();
      str = str.substr(0, str.length() - 2); // remove suffix ", "
      logger.log(str, false, false);
    }

    bool
    parseConfigurationLine(const std::string& line, Logger& logger, int lineNumber)
    {
      std::string parameter, value;
      if (!extractParameterAndValue(line, parameter, value)) {
        logger.log("Line " + std::to_string(lineNumber) + " - Invalid syntax: " + line,
                   false, true);
        return false;
      }

      if (parameter == "TrafficPercentage") {
        m_trafficPercentage = std::stoul(value);
      }
      else if (parameter == "Name") {
        m_name = value;
      }
      else if (parameter == "NameAppendBytes") {
        m_nameAppendBytes = std::stoul(value);
      }
      else if (parameter == "NameAppendSequenceNumber") {
        m_nameAppendSeqNum = std::stoull(value);
      }
      else if (parameter == "CanBePrefix") {
        m_canBePrefix = parseBoolean(value);
      }
      else if (parameter == "MustBeFresh") {
        m_mustBeFresh = parseBoolean(value);
      }
      else if (parameter == "NonceDuplicationPercentage") {
        m_nonceDuplicationPercentage = std::stoul(value);
      }
      else if (parameter == "InterestLifetime") {
        m_interestLifetime = time::milliseconds(std::stoul(value));
      }
      else if (parameter == "NextHopFaceId") {
        m_nextHopFaceId = std::stoull(value);
      }
      else if (parameter == "ExpectedContent") {
        m_expectedContent = value;
      }
      else {
        logger.log("Line " + std::to_string(lineNumber) + " - Ignoring unknown parameter: " + parameter,
                   false, true);
      }
      return true;
    }

    bool
    checkTrafficDetailCorrectness() const
    {
      return true;
    }

  public:
    uint8_t m_trafficPercentage = 0;
    std::string m_name;
    std::optional<std::size_t> m_nameAppendBytes;
    std::optional<uint64_t> m_nameAppendSeqNum;
    bool m_canBePrefix = false;
    bool m_mustBeFresh = false;
    uint8_t m_nonceDuplicationPercentage = 0;
    time::milliseconds m_interestLifetime = -1_ms;
    uint64_t m_nextHopFaceId = 0;
    std::optional<std::string> m_expectedContent;

    uint64_t m_nInterestsSent = 0;
    uint64_t m_nInterestsReceived = 0;
    uint64_t m_nNacks = 0;
    uint64_t m_nContentInconsistencies = 0;

    // RTT is stored as milliseconds with fractional sub-milliseconds precision
    double m_minimumInterestRoundTripTime = std::numeric_limits<double>::max();
    double m_maximumInterestRoundTripTime = 0;
    double m_totalInterestRoundTripTime = 0;
  };

  void
  logStatistics()
  {
    using std::to_string;

    m_logger.log("\n\n== Interest Traffic Report ==\n", false, true);
    m_logger.log("Total Traffic Pattern Types = " + to_string(m_trafficPatterns.size()), false, true);
    m_logger.log("Total Interests Sent        = " + to_string(m_nInterestsSent), false, true);
    m_logger.log("Total Responses Received    = " + to_string(m_nInterestsReceived), false, true);
    m_logger.log("Total Nacks Received        = " + to_string(m_nNacks), false, true);

    double loss = 0.0;
    if (m_nInterestsSent > 0) {
      loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
    }
    m_logger.log("Total Interest Loss         = " + to_string(loss) + "%", false, true);

    double average = 0.0;
    double inconsistency = 0.0;
    if (m_nInterestsReceived > 0) {
      average = m_totalInterestRoundTripTime / m_nInterestsReceived;
      inconsistency = m_nContentInconsistencies * 100.0 / m_nInterestsReceived;
    }
    m_logger.log("Total Data Inconsistency    = " + to_string(inconsistency) + "%", false, true);
    m_logger.log("Total Round Trip Time       = " + to_string(m_totalInterestRoundTripTime) + "ms", false, true);
    m_logger.log("Average Round Trip Time     = " + to_string(average) + "ms\n", false, true);

    for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++) {
      const auto& pattern = m_trafficPatterns[patternId];

      m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, true);
      pattern.printTrafficConfiguration(m_logger);
      m_logger.log("Total Interests Sent        = " + to_string(pattern.m_nInterestsSent), false, true);
      m_logger.log("Total Responses Received    = " + to_string(pattern.m_nInterestsReceived), false, true);
      m_logger.log("Total Nacks Received        = " + to_string(pattern.m_nNacks), false, true);

      loss = 0.0;
      if (pattern.m_nInterestsSent > 0) {
        loss = (pattern.m_nInterestsSent - pattern.m_nInterestsReceived) * 100.0 / pattern.m_nInterestsSent;
      }
      m_logger.log("Total Interest Loss         = " + to_string(loss) + "%", false, true);

      average = 0.0;
      inconsistency = 0.0;
      if (pattern.m_nInterestsReceived > 0) {
        average = pattern.m_totalInterestRoundTripTime / pattern.m_nInterestsReceived;
        inconsistency = pattern.m_nContentInconsistencies * 100.0 / pattern.m_nInterestsReceived;
      }
      m_logger.log("Total Data Inconsistency    = " + to_string(inconsistency) + "%", false, true);
      m_logger.log("Total Round Trip Time       = " +
                   to_string(pattern.m_totalInterestRoundTripTime) + "ms", false, true);
      m_logger.log("Average Round Trip Time     = " + to_string(average) + "ms\n", false, true);
    }
  }

  bool
  checkTrafficPatternCorrectness() const
  {
    // TODO
    return true;
  }

  uint32_t
  getNewNonce()
  {
    if (m_nonces.size() >= 1000)
      m_nonces.clear();

    auto randomNonce = ndn::random::generateWord32();
    while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
      randomNonce = ndn::random::generateWord32();

    m_nonces.push_back(randomNonce);
    return randomNonce;
  }

  uint32_t
  getOldNonce()
  {
    if (m_nonces.empty())
      return getNewNonce();

    std::uniform_int_distribution<std::size_t> dist(0, m_nonces.size() - 1);
    return m_nonces[dist(ndn::random::getRandomNumberEngine())];
  }

  static auto
  generateRandomNameComponent(std::size_t length)
  {
    // per ISO C++ std, cannot instantiate uniform_int_distribution with uint8_t
    static std::uniform_int_distribution<unsigned short> dist(std::numeric_limits<uint8_t>::min(),
                                                              std::numeric_limits<uint8_t>::max());

    ndn::Buffer buf(length);
    for (std::size_t i = 0; i < length; i++) {
      buf[i] = static_cast<uint8_t>(dist(ndn::random::getRandomNumberEngine()));
    }
    return ndn::name::Component(buf);
  }

  auto
  prepareInterest(std::size_t patternId)
  {
    ndn::Interest interest;
    auto& pattern = m_trafficPatterns[patternId];

    ndn::Name name(pattern.m_name);
    if (pattern.m_nameAppendBytes > 0) {
      name.append(generateRandomNameComponent(*pattern.m_nameAppendBytes));
    }
    if (pattern.m_nameAppendSeqNum) {
      auto seqNum = *pattern.m_nameAppendSeqNum;
      name.appendSequenceNumber(seqNum);
      pattern.m_nameAppendSeqNum = seqNum + 1;
    }
    interest.setName(name);

    interest.setCanBePrefix(pattern.m_canBePrefix);
    interest.setMustBeFresh(pattern.m_mustBeFresh);

    static std::uniform_int_distribution<> duplicateNonceDist(1, 100);
    if (duplicateNonceDist(ndn::random::getRandomNumberEngine()) <= pattern.m_nonceDuplicationPercentage)
      interest.setNonce(getOldNonce());
    else
      interest.setNonce(getNewNonce());

    if (pattern.m_interestLifetime >= 0_ms)
      interest.setInterestLifetime(pattern.m_interestLifetime);

    if (pattern.m_nextHopFaceId > 0)
      interest.setTag(std::make_shared<ndn::lp::NextHopFaceIdTag>(pattern.m_nextHopFaceId));

    return interest;
  }

  void
  onData(const ndn::Interest&, const ndn::Data& data, int globalRef, int localRef,
         std::size_t patternId, const time::steady_clock::time_point& sentTime)
  {
    auto logLine = "Data Received      - PatternType=" + std::to_string(patternId + 1) +
                   ", GlobalID=" + std::to_string(globalRef) +
                   ", LocalID=" + std::to_string(localRef) +
                   ", Name=" + data.getName().toUri();

    m_nInterestsReceived++;
    m_trafficPatterns[patternId].m_nInterestsReceived++;

    if (m_trafficPatterns[patternId].m_expectedContent) {
      std::string receivedContent = readString(data.getContent());
      if (receivedContent != *m_trafficPatterns[patternId].m_expectedContent) {
        m_nContentInconsistencies++;
        m_trafficPatterns[patternId].m_nContentInconsistencies++;
        logLine += ", IsConsistent=No";
      }
      else {
        logLine += ", IsConsistent=Yes";
      }
    }
    else {
      logLine += ", IsConsistent=NotChecked";
    }
    if (!m_wantQuiet) {
      m_logger.log(logLine, true, false);
    }

    double roundTripTime = (time::steady_clock::now() - sentTime).count() / 1000000.0;
    if (m_minimumInterestRoundTripTime > roundTripTime)
      m_minimumInterestRoundTripTime = roundTripTime;
    if (m_maximumInterestRoundTripTime < roundTripTime)
      m_maximumInterestRoundTripTime = roundTripTime;
    if (m_trafficPatterns[patternId].m_minimumInterestRoundTripTime > roundTripTime)
      m_trafficPatterns[patternId].m_minimumInterestRoundTripTime = roundTripTime;
    if (m_trafficPatterns[patternId].m_maximumInterestRoundTripTime < roundTripTime)
      m_trafficPatterns[patternId].m_maximumInterestRoundTripTime = roundTripTime;
    m_totalInterestRoundTripTime += roundTripTime;
    m_trafficPatterns[patternId].m_totalInterestRoundTripTime += roundTripTime;

    if (m_nMaximumInterests == globalRef) {
      stop();
    }
  }

  void
  onNack(const ndn::Interest& interest, const ndn::lp::Nack& nack,
         int globalRef, int localRef, std::size_t patternId)
  {
    auto logLine = "Interest Nack'd    - PatternType=" + std::to_string(patternId + 1) +
                   ", GlobalID=" + std::to_string(globalRef) +
                   ", LocalID=" + std::to_string(localRef) +
                   ", Name=" + interest.getName().toUri() +
                   ", NackReason=" + boost::lexical_cast<std::string>(nack.getReason());
    m_logger.log(logLine, true, false);

    m_nNacks++;
    m_trafficPatterns[patternId].m_nNacks++;

    if (m_nMaximumInterests == globalRef) {
      stop();
    }
  }

  void
  onTimeout(const ndn::Interest& interest, int globalRef, int localRef, std::size_t patternId)
  {
    auto logLine = "Interest Timed Out - PatternType=" + std::to_string(patternId + 1) +
                   ", GlobalID=" + std::to_string(globalRef) +
                   ", LocalID=" + std::to_string(localRef) +
                   ", Name=" + interest.getName().toUri();
    m_logger.log(logLine, true, false);

    if (m_nMaximumInterests == globalRef) {
      stop();
    }
  }

  void
  generateTraffic(boost::asio::deadline_timer& timer)
  {
    if (m_nMaximumInterests && m_nInterestsSent >= *m_nMaximumInterests) {
      return;
    }

    static std::uniform_int_distribution<> trafficDist(1, 100);
    int trafficKey = trafficDist(ndn::random::getRandomNumberEngine());

    int cumulativePercentage = 0;
    std::size_t patternId = 0;
    for (; patternId < m_trafficPatterns.size(); patternId++) {
      auto& pattern = m_trafficPatterns[patternId];
      cumulativePercentage += pattern.m_trafficPercentage;
      if (trafficKey <= cumulativePercentage) {
        m_nInterestsSent++;
        pattern.m_nInterestsSent++;
        auto interest = prepareInterest(patternId);
        try {
          int globalRef = m_nInterestsSent;
          int localRef = pattern.m_nInterestsSent;
          m_face.expressInterest(interest,
            [=, now = time::steady_clock::now()] (auto&&... args) {
              onData(std::forward<decltype(args)>(args)..., globalRef, localRef, patternId, now);
            },
            [=] (auto&&... args) {
              onNack(std::forward<decltype(args)>(args)..., globalRef, localRef, patternId);
            },
            [=] (auto&&... args) {
              onTimeout(std::forward<decltype(args)>(args)..., globalRef, localRef, patternId);
            });

          if (!m_wantQuiet) {
            auto logLine = "Sending Interest   - PatternType=" + std::to_string(patternId + 1) +
                           ", GlobalID=" + std::to_string(m_nInterestsSent) +
                           ", LocalID=" + std::to_string(pattern.m_nInterestsSent) +
                           ", Name=" + interest.getName().toUri();
            m_logger.log(logLine, true, false);
          }

          timer.expires_at(timer.expires_at() + boost::posix_time::millisec(m_interestInterval.count()));
          timer.async_wait([this, &timer] (auto&&...) { generateTraffic(timer); });
        }
        catch (const std::exception& e) {
          m_logger.log("ERROR: "s + e.what(), true, true);
        }
        break;
      }
    }
    if (patternId == m_trafficPatterns.size()) {
      timer.expires_at(timer.expires_at() + boost::posix_time::millisec(m_interestInterval.count()));
      timer.async_wait([this, &timer] (auto&&...) { generateTraffic(timer); });
    }
  }

  void
  stop()
  {
    if (m_nContentInconsistencies > 0 || m_nInterestsSent != m_nInterestsReceived) {
      m_hasError = true;
    }

    logStatistics();
    m_face.shutdown();
    m_ioService.stop();
  }

private:
  boost::asio::io_service m_ioService;
  boost::asio::signal_set m_signalSet;
  Logger m_logger;
  ndn::Face m_face;

  std::string m_configurationFile;
  std::optional<uint64_t> m_nMaximumInterests;
  time::milliseconds m_interestInterval = 1_s;

  std::vector<InterestTrafficConfiguration> m_trafficPatterns;
  std::vector<uint32_t> m_nonces;
  uint64_t m_nInterestsSent = 0;
  uint64_t m_nInterestsReceived = 0;
  uint64_t m_nNacks = 0;
  uint64_t m_nContentInconsistencies = 0;

  // RTT is stored as milliseconds with fractional sub-milliseconds precision
  double m_minimumInterestRoundTripTime = std::numeric_limits<double>::max();
  double m_maximumInterestRoundTripTime = 0;
  double m_totalInterestRoundTripTime = 0;

  bool m_wantQuiet = false;
  bool m_hasError = false;
};

} // namespace ndntg

namespace po = boost::program_options;

static void
usage(std::ostream& os, std::string_view programName, const po::options_description& desc)
{
  os << "Usage: " << programName << " [options] <Traffic_Configuration_File>\n"
     << "\n"
     << "Generate Interest traffic as per provided Traffic_Configuration_File.\n"
     << "Interests are continuously generated unless a total number is specified.\n"
     << "Set the environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
     << "\n"
     << desc;
}

int
main(int argc, char* argv[])
{
  std::string configFile;

  po::options_description visibleOptions("Options");
  visibleOptions.add_options()
    ("help,h",      "print this help message and exit")
    ("count,c",     po::value<int>(), "total number of Interests to be generated")
    ("interval,i",  po::value<ndn::time::milliseconds::rep>()->default_value(1000),
                    "Interest generation interval in milliseconds")
    ("quiet,q",     po::bool_switch(), "turn off logging of Interest generation/Data reception")
    ;

  po::options_description hiddenOptions;
  hiddenOptions.add_options()
    ("config-file", po::value<std::string>(&configFile))
    ;

  po::positional_options_description posOptions;
  posOptions.add("config-file", -1);

  po::options_description allOptions;
  allOptions.add(visibleOptions).add(hiddenOptions);

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

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

  if (configFile.empty()) {
    usage(std::cerr, argv[0], visibleOptions);
    return 2;
  }

  ndntg::NdnTrafficClient client(configFile);

  if (vm.count("count") > 0) {
    int count = vm["count"].as<int>();
    if (count < 0) {
      std::cerr << "ERROR: the argument for option '--count' cannot be negative" << std::endl;
      return 2;
    }
    client.setMaximumInterests(static_cast<uint64_t>(count));
  }

  if (vm.count("interval") > 0) {
    ndn::time::milliseconds interval(vm["interval"].as<ndn::time::milliseconds::rep>());
    if (interval <= 0_ms) {
      std::cerr << "ERROR: the argument for option '--interval' must be positive" << std::endl;
      return 2;
    }
    client.setInterestInterval(interval);
  }

  if (vm["quiet"].as<bool>()) {
    client.setQuietLogging();
  }

  return client.run();
}
