/* -*- 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 "core/version.hpp"

#include <boost/date_time/posix_time/posix_time.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:V")) != -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;
      case 'V':
        std::cout << "ndnping " << tools::VERSION << std::endl;
        return 0;
      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);
}
