/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022, 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/face.hpp>
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/lp/tags.hpp>
#include <ndn-cxx/util/backports.hpp>
#include <ndn-cxx/util/random.hpp>

#include <limits>
#include <sstream>
#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>

namespace po = boost::program_options;

namespace ndn {

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(to_string(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 #" + 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&&...) { this->stop(); });

    boost::asio::deadline_timer timer(m_ioService,
                                      boost::posix_time::millisec(m_interestInterval.count()));
    timer.async_wait([this, &timer] (auto&&...) { this->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 " + 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 " + 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;
    optional<std::size_t> m_nameAppendBytes;
    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;
    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()
  {
    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++) {
      m_logger.log("Traffic Pattern Type #" + to_string(patternId + 1), false, true);
      m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
      m_logger.log("Total Interests Sent        = " +
                   to_string(m_trafficPatterns[patternId].m_nInterestsSent), false, true);
      m_logger.log("Total Responses Received    = " +
                   to_string(m_trafficPatterns[patternId].m_nInterestsReceived), false, true);
      m_logger.log("Total Nacks Received        = " +
                   to_string(m_trafficPatterns[patternId].m_nNacks), false, true);
      loss = 0;
      if (m_trafficPatterns[patternId].m_nInterestsSent > 0) {
        loss = (m_trafficPatterns[patternId].m_nInterestsSent -
                m_trafficPatterns[patternId].m_nInterestsReceived);
        loss *= 100.0;
        loss /= m_trafficPatterns[patternId].m_nInterestsSent;
      }
      m_logger.log("Total Interest Loss         = " + to_string(loss) + "%", false, true);
      average = 0;
      inconsistency = 0;
      if (m_trafficPatterns[patternId].m_nInterestsReceived > 0) {
        average = (m_trafficPatterns[patternId].m_totalInterestRoundTripTime /
                   m_trafficPatterns[patternId].m_nInterestsReceived);
        inconsistency = m_trafficPatterns[patternId].m_nContentInconsistencies;
        inconsistency *= 100.0 / m_trafficPatterns[patternId].m_nInterestsReceived;
      }
      m_logger.log("Total Data Inconsistency    = " + to_string(inconsistency) + "%", false, true);
      m_logger.log("Total Round Trip Time       = " +
                   to_string(m_trafficPatterns[patternId].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 = random::generateWord32();
    while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
      randomNonce = 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(random::getRandomNumberEngine())];
  }

  static name::Component
  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());

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

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

    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(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(make_shared<lp::NextHopFaceIdTag>(pattern.m_nextHopFaceId));

    return interest;
  }

  void
  onData(const Data& data, int globalRef, int localRef, std::size_t patternId,
         const time::steady_clock::TimePoint& sentTime)
  {
    auto logLine = "Data Received      - PatternType=" + to_string(patternId + 1) +
                   ", GlobalID=" + to_string(globalRef) +
                   ", LocalID=" + 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 Interest& interest, const lp::Nack& nack,
         int globalRef, int localRef, std::size_t patternId)
  {
    auto logLine = "Interest Nack'd    - PatternType=" + to_string(patternId + 1) +
                   ", GlobalID=" + to_string(globalRef) +
                   ", LocalID=" + 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 Interest& interest, int globalRef, int localRef, int patternId)
  {
    auto logLine = "Interest Timed Out - PatternType=" + to_string(patternId + 1) +
                   ", GlobalID=" + to_string(globalRef) +
                   ", LocalID=" + 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(random::getRandomNumberEngine());

    int cumulativePercentage = 0;
    std::size_t patternId = 0;
    for (; patternId < m_trafficPatterns.size(); patternId++) {
      cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
      if (trafficKey <= cumulativePercentage) {
        auto interest = prepareInterest(patternId);
        try {
          m_nInterestsSent++;
          m_trafficPatterns[patternId].m_nInterestsSent++;
          auto sentTime = time::steady_clock::now();
          m_face.expressInterest(interest,
                                 bind(&NdnTrafficClient::onData, this, _2, m_nInterestsSent,
                                      m_trafficPatterns[patternId].m_nInterestsSent, patternId, sentTime),
                                 bind(&NdnTrafficClient::onNack, this, _1, _2, m_nInterestsSent,
                                      m_trafficPatterns[patternId].m_nInterestsSent, patternId),
                                 bind(&NdnTrafficClient::onTimeout, this, _1, m_nInterestsSent,
                                      m_trafficPatterns[patternId].m_nInterestsSent, patternId));

          if (!m_wantQuiet) {
            auto logLine = "Sending Interest   - PatternType=" + to_string(patternId + 1) +
                           ", GlobalID=" + to_string(m_nInterestsSent) +
                           ", LocalID=" + to_string(m_trafficPatterns[patternId].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&&...) { this->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&&...) { this->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;
  Face m_face;

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

  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_hasError = false;
};

} // namespace ndn

static void
usage(std::ostream& os, const std::string& 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;
  }

  ndn::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 <= ndn::time::milliseconds::zero()) {
      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();
}
