/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2015,  Arizona Board of Regents.
 *
 * This file is part of ndn-tools (Named Data Networking Essential Tools).
 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
 *
 * ndn-tools 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.
 *
 * ndn-tools 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
 * ndn-tools, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * Copyright (C) 2014 Arizona Board of Regents
 *
 * This file is part of ndn-tlv-ping (Ping Application for Named Data Networking).
 *
 * ndn-tlv-ping is a 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.
 *
 * ndn-tlv-ping 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
 * ndn-tlv-ping, e.g., in LICENSE file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
 */

#include <ndn-cxx/face.hpp>
#include <ndn-cxx/name.hpp>

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

namespace ndn {
namespace ping {

class NdnPing : boost::noncopyable
{
public:
  explicit
  NdnPing(char* programName)
    : m_programName(programName)
    , m_isAllowCachingSet(false)
    , m_isPrintTimestampSet(false)
    , m_hasError(false)
    , m_totalPings(-1)
    , m_startPingNumber(-1)
    , m_pingsSent(0)
    , m_pingsReceived(0)
    , m_pingInterval(getPingMinimumInterval())
    , m_clientIdentifier(0)
    , m_pingTimeoutThreshold(getPingTimeoutThreshold())
    , m_outstanding(0)
    , m_face(m_ioService)
  {
  }

  class PingStatistics : boost::noncopyable
  {
  public:
    explicit
    PingStatistics()
      : m_sentPings(0)
      , m_receivedPings(0)
      , m_pingStartTime(time::steady_clock::now())
      , m_minimumRoundTripTime(std::numeric_limits<double>::max())
      , m_averageRoundTripTimeData(0)
      , m_standardDeviationRoundTripTimeData(0)
    {
    }

    void
    addToPingStatistics(time::nanoseconds roundTripNanoseconds)
    {
      double roundTripTime = roundTripNanoseconds.count() / 1000000.0;
      if (roundTripTime < m_minimumRoundTripTime)
        m_minimumRoundTripTime = roundTripTime;
      if (roundTripTime > m_maximumRoundTripTime)
        m_maximumRoundTripTime = roundTripTime;

      m_averageRoundTripTimeData += roundTripTime;
      m_standardDeviationRoundTripTimeData += roundTripTime * roundTripTime;
    }

  public:
    int m_sentPings;
    int m_receivedPings;
    time::steady_clock::TimePoint m_pingStartTime;
    double m_minimumRoundTripTime;
    double m_maximumRoundTripTime;
    double m_averageRoundTripTimeData;
    double m_standardDeviationRoundTripTimeData;

  };

  void
  usage()
  {
    std::cout << "\n Usage:\n " << m_programName << " ndn:/name/prefix [options]\n"
        " Ping a NDN name prefix using Interests with name"
        " ndn:/name/prefix/ping/number.\n"
        " The numbers in the Interests are randomly generated unless specified.\n"
        "   [-i interval]   - set ping interval in seconds (minimum "
        << getPingMinimumInterval().count() << " milliseconds)\n"
        "   [-c count]      - set total number of pings\n"
        "   [-n number]     - set the starting number, the number is incremented by 1"
        " after each Interest\n"
        "   [-p identifier] - add identifier to the Interest names before the"
        " numbers to avoid conflict\n"
        "   [-a]            - allow routers to return stale Data from cache\n"
        "   [-t]            - print timestamp with messages\n"
        "   [-h]            - print this message and exit\n\n";
    exit(1);
  }

  time::milliseconds
  getPingMinimumInterval()
  {
    return time::milliseconds(1000);
  }

  time::milliseconds
  getPingTimeoutThreshold()
  {
    return time::milliseconds(4000);
  }

  void
  setTotalPings(int totalPings)
  {
    if (totalPings <= 0)
      usage();

    m_totalPings = totalPings;
  }

  void
  setPingInterval(int pingInterval)
  {
    if (pingInterval < getPingMinimumInterval().count())
      usage();

    m_pingInterval = time::milliseconds(pingInterval);
  }

  void
  setStartPingNumber(int64_t startPingNumber)
  {
    if (startPingNumber < 0)
      usage();

    m_startPingNumber = startPingNumber;
  }

  void
  setAllowCaching()
  {
    m_isAllowCachingSet = true;
  }

  void
  setPrintTimestamp()
  {
    m_isPrintTimestampSet = true;
  }

  void
  setClientIdentifier(char* clientIdentifier)
  {
    m_clientIdentifier = clientIdentifier;

    if (strlen(clientIdentifier) == 0)
      usage();

    while (*clientIdentifier != '\0') {
      if (isalnum(*clientIdentifier) == 0)
        usage();
      clientIdentifier++;
    }
  }

  void
  setPrefix(char* prefix)
  {
    m_prefix = prefix;
  }

  bool
  hasError() const
  {
    return m_hasError;
  }


  void
  onData(const ndn::Interest& interest,
         Data& data,
         time::steady_clock::TimePoint timePoint)
  {
    std::string pingReference = interest.getName().toUri();
    m_pingsReceived++;
    m_pingStatistics.m_receivedPings++;
    time::nanoseconds roundTripTime = time::steady_clock::now() - timePoint;

    if (m_isPrintTimestampSet)
      std::cout << time::toIsoString(time::system_clock::now())  << " - ";
    std::cout << "Content From " << m_prefix;
    std::cout << " - Ping Reference = " <<
      interest.getName().getSubName(interest.getName().size()-1).toUri().substr(1);
    std::cout << "  \t- Round Trip Time = " <<
      roundTripTime.count() / 1000000.0 << " ms" << std::endl;

    m_pingStatistics.addToPingStatistics(roundTripTime);
    this->finish();
  }

  void
  onTimeout(const ndn::Interest& interest)
  {
    if (m_isPrintTimestampSet)
      std::cout << time::toIsoString(time::system_clock::now())  << " - ";
    std::cout << "Timeout From " << m_prefix;
    std::cout << " - Ping Reference = " <<
      interest.getName().getSubName(interest.getName().size()-1).toUri().substr(1);
    std::cout << std::endl;

    this->finish();
  }

  void
  printPingStatistics()
  {
    std::cout << "\n\n=== " << " Ping Statistics For "<< m_prefix <<" ===" << std::endl;
    std::cout << "Sent=" << m_pingStatistics.m_sentPings;
    std::cout << ", Received=" << m_pingStatistics.m_receivedPings;
    double packetLossRate = m_pingStatistics.m_sentPings - m_pingStatistics.m_receivedPings;
    packetLossRate /= m_pingStatistics.m_sentPings;
    std::cout << ", Packet Loss=" << packetLossRate * 100.0 << "%";
    if (m_pingStatistics.m_sentPings != m_pingStatistics.m_receivedPings)
      m_hasError = true;
    std::cout << ", Total Time=" << m_pingStatistics.m_averageRoundTripTimeData << " ms\n";
    if (m_pingStatistics.m_receivedPings > 0) {
      double averageRoundTripTime =
        m_pingStatistics.m_averageRoundTripTimeData / m_pingStatistics.m_receivedPings;
      double standardDeviationRoundTripTime =
        m_pingStatistics.m_standardDeviationRoundTripTimeData / m_pingStatistics.m_receivedPings;
      standardDeviationRoundTripTime -= averageRoundTripTime * averageRoundTripTime;
      standardDeviationRoundTripTime = std::sqrt(standardDeviationRoundTripTime);
      std::cout << "Round Trip Time (Min/Max/Avg/MDev) = (";
      std::cout << m_pingStatistics.m_minimumRoundTripTime << "/";
      std::cout << m_pingStatistics.m_maximumRoundTripTime << "/";
      std::cout << averageRoundTripTime << "/";
      std::cout << standardDeviationRoundTripTime << ") ms\n";
    }
    std::cout << std::endl;
  }

  void
  performPing(boost::asio::deadline_timer* deadlineTimer)
  {
    if ((m_totalPings < 0) || (m_pingsSent < m_totalPings)) {
      m_pingsSent++;
      m_pingStatistics.m_sentPings++;

      //Perform Ping
      char pingNumberString[20];
      Name pingPacketName(m_prefix);
      pingPacketName.append("ping");
      if (m_clientIdentifier != 0)
        pingPacketName.append(m_clientIdentifier);
      std::memset(pingNumberString, 0, 20);
      if (m_startPingNumber < 0)
        m_startPingNumber = std::rand();
      sprintf(pingNumberString, "%lld", static_cast<long long int>(m_startPingNumber));
      pingPacketName.append(pingNumberString);

      ndn::Interest interest(pingPacketName);

      if (m_isAllowCachingSet)
        interest.setMustBeFresh(false);
      else
        interest.setMustBeFresh(true);

      interest.setInterestLifetime(m_pingTimeoutThreshold);
      interest.setNonce(m_startPingNumber);

      m_startPingNumber++;
 
      try {
        m_face.expressInterest(interest,
                               std::bind(&NdnPing::onData, this, _1, _2,
                                         time::steady_clock::now()),
                               std::bind(&NdnPing::onTimeout, this, _1));
        deadlineTimer->expires_at(deadlineTimer->expires_at() +
                                  boost::posix_time::millisec(m_pingInterval.count()));
        deadlineTimer->async_wait(bind(&NdnPing::performPing,
                                       this,
                                       deadlineTimer));
      }
      catch (std::exception& e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
      }
      ++m_outstanding;
    }
    else {
      this->finish();
    }
  }

  void
  finish()
  {
    if (--m_outstanding >= 0) {
      return;
    }
    m_face.shutdown();
    printPingStatistics();
    m_ioService.stop();
  }

  void
  signalHandler()
  {
    m_face.shutdown();
    printPingStatistics();
    exit(1);
  }

  void
  run()
  {
    std::cout << "\n=== Pinging " << m_prefix  << " ===\n" <<std::endl;

    boost::asio::signal_set signalSet(m_ioService, SIGINT, SIGTERM);
    signalSet.async_wait(bind(&NdnPing::signalHandler, this));

    boost::asio::deadline_timer deadlineTimer(m_ioService,
                                              boost::posix_time::millisec(0));

    deadlineTimer.async_wait(bind(&NdnPing::performPing,
                                  this,
                                  &deadlineTimer));
    try {
      m_face.processEvents();
    }
    catch (std::exception& e) {
      std::cerr << "ERROR: " << e.what() << std::endl;
      m_hasError = true;
      m_ioService.stop();
    }
  }

private:
  char* m_programName;
  bool m_isAllowCachingSet;
  bool m_isPrintTimestampSet;
  bool m_hasError;
  int m_totalPings;
  int64_t m_startPingNumber;
  int m_pingsSent;
  int m_pingsReceived;
  time::milliseconds m_pingInterval;
  char* m_clientIdentifier;
  time::milliseconds m_pingTimeoutThreshold;
  char* m_prefix;
  PingStatistics m_pingStatistics;
  ssize_t m_outstanding;

  boost::asio::io_service m_ioService;
  Face m_face;
};

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

  NdnPing program(argv[0]);
  while ((res = getopt(argc, argv, "htai:c:n:p:")) != -1)
    {
      switch (res) {
      case 'a':
        program.setAllowCaching();
        break;
      case 'c':
        program.setTotalPings(atoi(optarg));
        break;
      case 'h':
        program.usage();
        break;
      case 'i':
        program.setPingInterval(atoi(optarg));
        break;
      case 'n':
        try {
          program.setStartPingNumber(boost::lexical_cast<int64_t>(optarg));
        }
        catch (boost::bad_lexical_cast&) {
          program.usage();
        }
        break;
      case 'p':
        program.setClientIdentifier(optarg);
        break;
      case 't':
        program.setPrintTimestamp();
        break;
      default:
        program.usage();
        break;
      }
    }

  argc -= optind;
  argv += optind;

  if (argv[0] == 0)
    program.usage();

  program.setPrefix(argv[0]);
  program.run();

  std::cout << std::endl;

  if (program.hasError())
    return 1;
  else
    return 0;
}

} // namespace ping
} // namespace ndn

int
main(int argc, char** argv)
{
  return ndn::ping::main(argc, argv);
}
