/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2019, 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 <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::string detail;

      detail += "TrafficPercentage=" + to_string(m_trafficPercentage) + ", ";
      detail += "Name=" + m_name + ", ";
      if (m_nameAppendBytes)
        detail += "NameAppendBytes=" + to_string(*m_nameAppendBytes) + ", ";
      if (m_nameAppendSeqNum)
        detail += "NameAppendSequenceNumber=" + to_string(*m_nameAppendSeqNum) + ", ";
      detail += "MustBeFresh=" + to_string(m_mustBeFresh) + ", ";
      if (m_nonceDuplicationPercentage > 0)
        detail += "NonceDuplicationPercentage=" + to_string(m_nonceDuplicationPercentage) + ", ";
      if (m_interestLifetime >= 0_ms)
        detail += "InterestLifetime=" + to_string(m_interestLifetime.count()) + ", ";
      if (m_nextHopFaceId > 0)
        detail += "NextHopFaceId=" + to_string(m_nextHopFaceId) + ", ";
      if (m_expectedContent)
        detail += "ExpectedContent=" + *m_expectedContent + ", ";
      if (detail.length() >= 2)
        detail = detail.substr(0, detail.length() - 2); // Removing suffix ", "

      logger.log(detail, 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 == "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_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.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(reinterpret_cast<const char*>(data.getContent().value()),
                                  data.getContent().value_size());
      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();
}
