/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (C) 2014-2016  The University of Arizona.
 *
 * 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 <cctype>
#include <cstdlib>
#include <fstream>
#include <string>
#include <unistd.h>
#include <vector>

#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem.hpp>
#include <boost/noncopyable.hpp>

#include <ndn-cxx/exclude.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/name-component.hpp>
#include <ndn-cxx/util/backports.hpp>

#include "logger.hpp"

namespace ndn {

class NdnTrafficClient : boost::noncopyable
{
public:
  explicit
  NdnTrafficClient(const char* programName)
    : m_programName(programName)
    , m_logger("NdnTrafficClient")
    , m_instanceId(to_string(std::rand()))
    , m_hasError(false)
    , m_hasQuietLogging(false)
    , m_interestInterval(getDefaultInterestInterval())
    , m_nMaximumInterests(-1)
    , m_face(m_ioService)
    , m_nInterestsSent(0)
    , m_nInterestsReceived(0)
    , m_nNacks(0)
    , m_nContentInconsistencies(0)
    , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
    , m_maximumInterestRoundTripTime(0)
    , m_totalInterestRoundTripTime(0)
  {
  }

  class InterestTrafficConfiguration
  {
  public:
    InterestTrafficConfiguration()
      : m_trafficPercentage(-1)
      , m_nameAppendBytes(-1)
      , m_nameAppendSequenceNumber(-1)
      , m_minSuffixComponents(-1)
      , m_maxSuffixComponents(-1)
      , m_excludeBeforeBytes(-1)
      , m_excludeAfterBytes(-1)
      , m_childSelector(-1)
      , m_mustBeFresh(-1)
      , m_nonceDuplicationPercentage(-1)
      , m_interestLifetime(getDefaultInterestLifetime())
      , m_nextHopFaceId(0)
      , m_nInterestsSent(0)
      , m_nInterestsReceived(0)
      , m_nNacks(0)
      , m_minimumInterestRoundTripTime(std::numeric_limits<double>::max())
      , m_maximumInterestRoundTripTime(0)
      , m_totalInterestRoundTripTime(0)
      , m_nContentInconsistencies(0)
    {
    }

    static time::milliseconds
    getDefaultInterestLifetime()
    {
      return time::milliseconds(-1);
    }

    void
    printTrafficConfiguration(Logger& logger)
    {
      std::string detail;

      if (m_trafficPercentage > 0)
        detail += "TrafficPercentage=" + to_string(m_trafficPercentage) + ", ";
      if (!m_name.empty())
        detail += "Name=" + m_name + ", ";
      if (m_nameAppendBytes > 0)
        detail += "NameAppendBytes=" + to_string(m_nameAppendBytes) + ", ";
      if (m_nameAppendSequenceNumber > 0)
        detail += "NameAppendSequenceNumber=" + to_string(m_nameAppendSequenceNumber) + ", ";
      if (m_minSuffixComponents >= 0)
        detail += "MinSuffixComponents=" + to_string(m_minSuffixComponents) + ", ";
      if (m_maxSuffixComponents >= 0)
        detail += "MaxSuffixComponents=" + to_string(m_maxSuffixComponents) + ", ";
      if (!m_excludeBefore.empty())
        detail += "ExcludeBefore=" + m_excludeBefore + ", ";
      if (!m_excludeAfter.empty())
        detail += "ExcludeAfter=" + m_excludeAfter + ", ";
      if (m_excludeBeforeBytes > 0)
        detail += "ExcludeBeforeBytes=" + to_string(m_excludeBeforeBytes) + ", ";
      if (m_excludeAfterBytes > 0)
        detail += "ExcludeAfterBytes=" + to_string(m_excludeAfterBytes) + ", ";
      if (m_childSelector >= 0)
        detail += "ChildSelector=" + to_string(m_childSelector) + ", ";
      if (m_mustBeFresh >= 0)
        detail += "MustBeFresh=" + to_string(m_mustBeFresh) + ", ";
      if (m_nonceDuplicationPercentage > 0)
        detail += "NonceDuplicationPercentage=" + to_string(m_nonceDuplicationPercentage) + ", ";
      if (m_interestLifetime >= time::milliseconds(0))
        detail += "InterestLifetime=" + to_string(m_interestLifetime.count()) + ", ";
      if (m_nextHopFaceId > 0)
        detail += "NextHopFaceId=" + to_string(m_nextHopFaceId) + ", ";
      if (!m_expectedContent.empty())
        detail += "ExpectedContent=" + m_expectedContent + ", ";
      if (detail.length() >= 2)
        detail = detail.substr(0, detail.length() - 2); // Removing suffix ", "

      logger.log(detail, false, false);
    }

    bool
    extractParameterValue(const std::string& detail, std::string& parameter, std::string& value)
    {
      std::string allowedCharacters = ":/+._-%";
      std::size_t i = 0;

      parameter = "";
      value = "";
      while (detail[i] != '=' && i < detail.length()) {
        parameter += detail[i];
        i++;
      }
      if (i == detail.length())
        return false;

      i++;
      while ((std::isalnum(detail[i]) ||
              allowedCharacters.find(detail[i]) != std::string::npos) &&
             i < detail.length()) {
        value += detail[i];
        i++;
      }

      if (parameter.empty() || value.empty())
        return false;
      else
        return true;
    }

    bool
    processConfigurationDetail(const std::string& detail, Logger& logger, int lineNumber)
    {
      std::string parameter, value;
      if (extractParameterValue(detail, parameter, value))
        {
          if (parameter == "TrafficPercentage")
            m_trafficPercentage = std::stoi(value);
          else if (parameter == "Name")
            m_name = value;
          else if (parameter == "NameAppendBytes")
            m_nameAppendBytes = std::stoi(value);
          else if (parameter == "NameAppendSequenceNumber")
            m_nameAppendSequenceNumber = std::stoi(value);
          else if (parameter == "MinSuffixComponents")
            m_minSuffixComponents = std::stoi(value);
          else if (parameter == "MaxSuffixComponents")
            m_maxSuffixComponents = std::stoi(value);
          else if (parameter == "ExcludeBefore")
            m_excludeBefore = value;
          else if (parameter == "ExcludeAfter")
            m_excludeAfter = value;
          else if (parameter == "ExcludeBeforeBytes")
            m_excludeBeforeBytes = std::stoi(value);
          else if (parameter == "ExcludeAfterBytes")
            m_excludeAfterBytes = std::stoi(value);
          else if (parameter == "ChildSelector")
            m_childSelector = std::stoi(value);
          else if (parameter == "MustBeFresh")
            m_mustBeFresh = std::stoi(value);
          else if (parameter == "NonceDuplicationPercentage")
            m_nonceDuplicationPercentage = std::stoi(value);
          else if (parameter == "InterestLifetime")
            m_interestLifetime = time::milliseconds(std::stoi(value));
          else if (parameter == "NextHopFaceId")
            m_nextHopFaceId = std::stoi(value);
          else if (parameter == "ExpectedContent")
            m_expectedContent = value;
          else
            logger.log("Line " + to_string(lineNumber) +
                       " \t- Invalid Parameter='" + parameter + "'", false, true);
        }
      else
        {
          logger.log("Line " + to_string(lineNumber) +
                     " \t- Improper Traffic Configuration Line- " + detail, false, true);
          return false;
        }
      return true;
    }

    bool
    checkTrafficDetailCorrectness()
    {
      return true;
    }

  private:
    int m_trafficPercentage;
    std::string m_name;
    int m_nameAppendBytes;
    int m_nameAppendSequenceNumber;
    int m_minSuffixComponents;
    int m_maxSuffixComponents;
    std::string m_excludeBefore;
    std::string m_excludeAfter;
    int m_excludeBeforeBytes;
    int m_excludeAfterBytes;
    int m_childSelector;
    int m_mustBeFresh;
    int m_nonceDuplicationPercentage;
    time::milliseconds m_interestLifetime;
    uint64_t m_nextHopFaceId;
    int m_nInterestsSent;
    int m_nInterestsReceived;
    int m_nNacks;

    //round trip time is stored as milliseconds with fractional
    //sub-millisecond precision
    double m_minimumInterestRoundTripTime;
    double m_maximumInterestRoundTripTime;
    double m_totalInterestRoundTripTime;

    int m_nContentInconsistencies;
    std::string m_expectedContent;

    friend class NdnTrafficClient;
  }; // class InterestTrafficConfiguration

  bool
  hasError() const
  {
    return m_hasError;
  }

  void
  usage() const
  {
    std::cout << "Usage:\n"
              << "  " << m_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 environment variable NDN_TRAFFIC_LOGFOLDER to redirect output to a log file.\n"
              << "\n"
              << "Options:\n"
              << "  [-i interval] - set interest generation interval in milliseconds (default "
              << getDefaultInterestInterval() << ")\n"
              << "  [-c count]    - set total number of interests to be generated\n"
              << "  [-q]          - quiet mode: no interest reception/data generation logging\n"
              << "  [-h]          - print this help text and exit\n";
    exit(EXIT_FAILURE);
  }

  static time::milliseconds
  getDefaultInterestInterval()
  {
    return time::milliseconds(1000);
  }

  void
  setInterestInterval(int interestInterval)
  {
    if (interestInterval <= 0)
      usage();
    m_interestInterval = time::milliseconds(interestInterval);
  }

  void
  setMaximumInterests(int maximumInterests)
  {
    if (maximumInterests <= 0)
      usage();
    m_nMaximumInterests = maximumInterests;
  }

  void
  setConfigurationFile(char* configurationFile)
  {
    m_configurationFile = configurationFile;
  }

  void
  setQuietLogging()
  {
    m_hasQuietLogging = true;
  }

  void
  signalHandler()
  {
    logStatistics();

    m_logger.shutdownLogger();
    m_face.shutdown();
    m_ioService.stop();

    exit(m_hasError ? EXIT_FAILURE : EXIT_SUCCESS);
  }

  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;
    if (m_nInterestsSent > 0)
      loss = (m_nInterestsSent - m_nInterestsReceived) * 100.0 / m_nInterestsSent;
    m_logger.log("Total Interest Loss         = " + to_string(loss) + "%", false, true);
    if (m_nContentInconsistencies != 0 || m_nInterestsSent != m_nInterestsReceived)
      m_hasError = true;

    double average = 0;
    double inconsistency = 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()
  {
    return true;
  }

  void
  parseConfigurationFile()
  {
    std::string patternLine;
    std::ifstream patternFile;
    m_logger.log("Analyzing Traffic Configuration File: " + m_configurationFile, true, true);

    patternFile.open(m_configurationFile.c_str());
    if (patternFile.is_open())
      {
        int lineNumber = 0;
        while (getline(patternFile, patternLine))
          {
            lineNumber++;
            if (std::isalpha(patternLine[0]))
              {
                InterestTrafficConfiguration interestData;
                bool shouldSkipLine = false;
                if (interestData.processConfigurationDetail(patternLine, m_logger, lineNumber))
                  {
                    while (getline(patternFile, patternLine) && std::isalpha(patternLine[0]))
                      {
                        lineNumber++;
                        if (!interestData.processConfigurationDetail(patternLine,
                                                                     m_logger, lineNumber))
                          {
                            shouldSkipLine = true;
                            break;
                          }
                      }
                    lineNumber++;
                  }
                else
                  shouldSkipLine = true;
                if (!shouldSkipLine)
                  {
                    if (interestData.checkTrafficDetailCorrectness())
                      m_trafficPatterns.push_back(interestData);
                  }
              }
          }
        patternFile.close();
        if (!checkTrafficPatternCorrectness())
          {
            m_logger.log("ERROR - Traffic Configuration Provided Is Not Proper- " +
                         m_configurationFile, false, true);
            m_logger.shutdownLogger();
            exit(EXIT_FAILURE);
          }
        m_logger.log("Traffic Configuration File Processing Completed\n", true, false);
        for (std::size_t patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
          {
            m_logger.log("Traffic Pattern Type #" +
                         to_string(patternId + 1), false, false);
            m_trafficPatterns[patternId].printTrafficConfiguration(m_logger);
            m_logger.log("", false, false);
          }
      }
    else
      {
        m_logger.log("ERROR - Unable To Open Traffic Configuration File: " +
                     m_configurationFile, false, true);
        m_logger.shutdownLogger();
        exit(EXIT_FAILURE);
      }
  }

  void
  initializeTrafficConfiguration()
  {
    if (boost::filesystem::exists(boost::filesystem::path(m_configurationFile)))
      {
        if (boost::filesystem::is_regular_file(boost::filesystem::path(m_configurationFile)))
          {
            parseConfigurationFile();
          }
        else
          {
            m_logger.log("ERROR - Traffic Configuration File Is Not A Regular File: " +
                         m_configurationFile, false, true);
            m_logger.shutdownLogger();
            exit(EXIT_FAILURE);
          }
      }
    else
      {
        m_logger.log("ERROR - Traffic Configuration File Does Not Exist: " +
                     m_configurationFile, false, true);
        m_logger.shutdownLogger();
        exit(EXIT_FAILURE);
      }
  }

  uint32_t
  getOldNonce()
  {
    if (m_nonces.size() == 0)
      return getNewNonce();
    int randomNonceIndex = std::rand() % m_nonces.size();
    return m_nonces[randomNonceIndex];
  }

  uint32_t
  getNewNonce()
  {
    //Performance Enhancement
    if (m_nonces.size() > 1000)
      m_nonces.clear();

    uint32_t randomNonce = static_cast<uint32_t>(std::rand());
    while (std::find(m_nonces.begin(), m_nonces.end(), randomNonce) != m_nonces.end())
      randomNonce = static_cast<uint32_t>(std::rand());

    m_nonces.push_back(randomNonce);
    return randomNonce;
  }

  static name::Component
  generateRandomNameComponent(size_t length)
  {
    Buffer buffer(length);
    for (size_t i = 0; i < length; i++) {
      buffer[i] = static_cast<uint8_t>(std::rand() % 256);
    }
    return name::Component(buffer);
  }

  void
  onData(const ndn::Interest& interest,
         const ndn::Data& data,
         int globalReference,
         int localReference,
         int patternId,
         time::steady_clock::TimePoint sentTime)
  {
    std::string logLine = "Data Received      - PatternType=" + to_string(patternId + 1);
    logLine += ", GlobalID=" + to_string(globalReference);
    logLine += ", LocalID=" + to_string(localReference);
    logLine += ", Name=" + interest.getName().toUri();

    m_nInterestsReceived++;
    m_trafficPatterns[patternId].m_nInterestsReceived++;
    if (!m_trafficPatterns[patternId].m_expectedContent.empty())
      {
        std::string receivedContent = reinterpret_cast<const char*>(data.getContent().value());
        int receivedContentLength = data.getContent().value_size();
        receivedContent = receivedContent.substr(0, receivedContentLength);
        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_hasQuietLogging)
      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 >= 0 && globalReference == m_nMaximumInterests)
      {
        logStatistics();
        m_logger.shutdownLogger();
        m_face.shutdown();
        m_ioService.stop();
      }
  }

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

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

    if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests) {
      logStatistics();
      m_logger.shutdownLogger();
      m_face.shutdown();
      m_ioService.stop();
    }
  }

  void
  onTimeout(const ndn::Interest& interest,
            int globalReference,
            int localReference,
            int patternId)
  {
    std::string logLine = "Interest Timed Out - PatternType=" + to_string(patternId + 1);
    logLine += ", GlobalID=" + to_string(globalReference);
    logLine += ", LocalID=" + to_string(localReference);
    logLine += ", Name=" + interest.getName().toUri();
    m_logger.log(logLine, true, false);
    if (m_nMaximumInterests >= 0 && globalReference == m_nMaximumInterests)
      {
        logStatistics();
        m_logger.shutdownLogger();
        m_face.shutdown();
        m_ioService.stop();
      }
  }

  void
  generateTraffic(boost::asio::deadline_timer* timer)
  {
    if (m_nMaximumInterests < 0 || m_nInterestsSent < m_nMaximumInterests)
      {
        int trafficKey = std::rand() % 100;
        int cumulativePercentage = 0;
        std::size_t patternId;
        for (patternId = 0; patternId < m_trafficPatterns.size(); patternId++)
          {
            cumulativePercentage += m_trafficPatterns[patternId].m_trafficPercentage;
            if (trafficKey <= cumulativePercentage)
              {
                Name interestName(m_trafficPatterns[patternId].m_name);
                if (m_trafficPatterns[patternId].m_nameAppendBytes > 0)
                  interestName.append(
                    generateRandomNameComponent(m_trafficPatterns[patternId].m_nameAppendBytes));
                if (m_trafficPatterns[patternId].m_nameAppendSequenceNumber >= 0)
                  {
                    interestName.append(
                      to_string(m_trafficPatterns[patternId].m_nameAppendSequenceNumber));
                    m_trafficPatterns[patternId].m_nameAppendSequenceNumber++;
                  }

                Interest interest(interestName);
                if (m_trafficPatterns[patternId].m_minSuffixComponents >= 0)
                  interest.setMinSuffixComponents(
                    m_trafficPatterns[patternId].m_minSuffixComponents);
                if (m_trafficPatterns[patternId].m_maxSuffixComponents >= 0)
                  interest.setMaxSuffixComponents(
                    m_trafficPatterns[patternId].m_maxSuffixComponents);

                Exclude exclude;
                if (!m_trafficPatterns[patternId].m_excludeBefore.empty() &&
                    !m_trafficPatterns[patternId].m_excludeAfter.empty())
                  {
                    exclude.excludeRange(
                      name::Component(
                        m_trafficPatterns[patternId].m_excludeAfter),
                      name::Component(m_trafficPatterns[patternId].m_excludeBefore));
                    interest.setExclude(exclude);
                  }
                else if (!m_trafficPatterns[patternId].m_excludeBefore.empty())
                  {
                    exclude.excludeBefore(
                      name::Component(m_trafficPatterns[patternId].m_excludeBefore));
                    interest.setExclude(exclude);
                  }
                else if (!m_trafficPatterns[patternId].m_excludeAfter.empty())
                  {
                    exclude.excludeAfter(
                      name::Component(m_trafficPatterns[patternId].m_excludeAfter));
                    interest.setExclude(exclude);
                  }
                if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0 &&
                    m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
                  {
                    exclude.excludeRange(
                      generateRandomNameComponent(
                        m_trafficPatterns[patternId].m_excludeAfterBytes),
                      generateRandomNameComponent(
                        m_trafficPatterns[patternId].m_excludeBeforeBytes));
                    interest.setExclude(exclude);
                  }
                else if (m_trafficPatterns[patternId].m_excludeBeforeBytes > 0)
                  {
                    exclude.excludeBefore(
                      generateRandomNameComponent(
                        m_trafficPatterns[patternId].m_excludeBeforeBytes));
                    interest.setExclude(exclude);
                  }
                else if (m_trafficPatterns[patternId].m_excludeAfterBytes > 0)
                  {
                    exclude.excludeAfter(
                      generateRandomNameComponent(
                        m_trafficPatterns[patternId].m_excludeAfterBytes));
                    interest.setExclude(exclude);
                  }

                if (m_trafficPatterns[patternId].m_childSelector >= 0)
                  interest.setChildSelector(m_trafficPatterns[patternId].m_childSelector);

                if (m_trafficPatterns[patternId].m_mustBeFresh == 0)
                  interest.setMustBeFresh(false);
                else if (m_trafficPatterns[patternId].m_mustBeFresh > 0)
                  interest.setMustBeFresh(true);
                if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage > 0)
                  {
                    int duplicationPercentage = std::rand() % 100;
                    if (m_trafficPatterns[patternId].m_nonceDuplicationPercentage <=
                        duplicationPercentage)
                      interest.setNonce(getOldNonce());
                    else
                      interest.setNonce(getNewNonce());
                  }
                else
                  interest.setNonce(getNewNonce());
                if (m_trafficPatterns[patternId].m_interestLifetime >= time::milliseconds(0))
                  interest.setInterestLifetime(m_trafficPatterns[patternId].m_interestLifetime);

                if (m_trafficPatterns[patternId].m_nextHopFaceId > 0) {
                  interest.setTag(make_shared<lp::NextHopFaceIdTag>(
                    m_trafficPatterns[patternId].m_nextHopFaceId));
                }

                try {
                  m_nInterestsSent++;
                  m_trafficPatterns[patternId].m_nInterestsSent++;
                  time::steady_clock::TimePoint sentTime = time::steady_clock::now();
                  m_face.expressInterest(interest,
                                         bind(&NdnTrafficClient::onData,
                                              this, _1, _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_hasQuietLogging) {
                    std::string 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(bind(&NdnTrafficClient::generateTraffic, this, timer));
                }
                catch (const std::exception& e) {
                  m_logger.log("ERROR: " + std::string(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(bind(&NdnTrafficClient::generateTraffic, this, timer));
          }
      }
  }

  void
  run()
  {
    boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
    signalSet.async_wait(bind(&NdnTrafficClient::signalHandler, this));
    m_logger.initializeLog(m_instanceId);
    initializeTrafficConfiguration();

    if (m_nMaximumInterests == 0)
      {
        logStatistics();
        m_logger.shutdownLogger();
        return;
      }

    boost::asio::deadline_timer deadlineTimer(m_ioService,
      boost::posix_time::millisec(m_interestInterval.count()));
    deadlineTimer.async_wait(bind(&NdnTrafficClient::generateTraffic, this, &deadlineTimer));

    try {
      m_face.processEvents();
    }
    catch (const std::exception& e) {
      m_logger.log("ERROR: " + std::string(e.what()), true, true);
      m_logger.shutdownLogger();
      m_hasError = true;
      m_ioService.stop();
    }
  }

private:
  std::string m_programName;
  Logger m_logger;
  std::string m_instanceId;
  bool m_hasError;
  bool m_hasQuietLogging;
  time::milliseconds m_interestInterval;
  int m_nMaximumInterests;
  std::string m_configurationFile;
  boost::asio::io_service m_ioService;
  Face m_face;
  std::vector<InterestTrafficConfiguration> m_trafficPatterns;
  std::vector<uint32_t> m_nonces;
  int m_nInterestsSent;
  int m_nInterestsReceived;
  int m_nNacks;
  int m_nContentInconsistencies;

  //round trip time is stored as milliseconds with fractional
  //sub-milliseconds precision
  double m_minimumInterestRoundTripTime;
  double m_maximumInterestRoundTripTime;
  double m_totalInterestRoundTripTime;
};

} // namespace ndn

int
main(int argc, char* argv[])
{
  std::srand(std::time(nullptr));

  ndn::NdnTrafficClient client(argv[0]);
  int option;
  while ((option = getopt(argc, argv, "hqi:c:")) != -1) {
    switch (option) {
    case 'h':
      client.usage();
      break;
    case 'i':
      client.setInterestInterval(atoi(optarg));
      break;
    case 'c':
      client.setMaximumInterests(atoi(optarg));
      break;
    case 'q':
      client.setQuietLogging();
      break;
    default:
      client.usage();
      break;
    }
  }

  argc -= optind;
  argv += optind;

  if (!argc)
    client.usage();

  client.setConfigurationFile(argv[0]);
  client.run();

  return client.hasError() ? EXIT_FAILURE : EXIT_SUCCESS;
}
