/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2016,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD 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.
 *
 * NFD 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
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
#define NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP

#include "fw/rtt-estimator.hpp"
#include "fw/strategy-info.hpp"
#include "table/measurements-accessor.hpp"

namespace nfd {
namespace fw {
namespace asf {

class RttStats
{
public:
  typedef time::duration<double, boost::micro> Rtt;

  RttStats();

  void
  addRttMeasurement(RttEstimator::Duration& durationRtt);

  void
  recordTimeout()
  {
    m_rtt = RTT_TIMEOUT;
  }

  Rtt
  getRtt() const
  {
    return m_rtt;
  }

  Rtt
  getSrtt() const
  {
    return m_srtt;
  }

  RttEstimator::Duration
  computeRto() const
  {
    return m_rttEstimator.computeRto();
  }

private:
  static Rtt
  computeSrtt(Rtt previousSrtt, Rtt currentRtt);

public:
  static const Rtt RTT_TIMEOUT;
  static const Rtt RTT_NO_MEASUREMENT;

private:
  Rtt m_srtt;
  Rtt m_rtt;
  RttEstimator m_rttEstimator;

  static const double ALPHA;
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/** \brief Strategy information for each face in a namespace
*/
class FaceInfo
{
public:
  class Error : public std::runtime_error
  {
  public:
    explicit
    Error(const std::string& what)
      : std::runtime_error(what)
    {
    }
  };

  FaceInfo();

  ~FaceInfo();

  void
  setTimeoutEvent(const scheduler::EventId& id, const ndn::Name& interestName);

  void
  setMeasurementExpirationEventId(const scheduler::EventId& id)
  {
    m_measurementExpirationId = id;
  }

  const scheduler::EventId&
  getMeasurementExpirationEventId()
  {
    return m_measurementExpirationId;
  }

  void
  cancelTimeoutEvent(const ndn::Name& prefix);

  bool
  isTimeoutScheduled() const
  {
    return m_isTimeoutScheduled;
  }

  void
  recordRtt(const shared_ptr<pit::Entry> pitEntry, const Face& inFace);

  void
  recordTimeout(const ndn::Name& interestName);

  bool
  isTimeout() const
  {
    return getRtt() == RttStats::RTT_TIMEOUT;
  }

  RttEstimator::Duration
  computeRto() const
  {
    return m_rttStats.computeRto();
  }

  RttStats::Rtt
  getRtt() const
  {
    return m_rttStats.getRtt();
  }

  RttStats::Rtt
  getSrtt() const
  {
    return m_rttStats.getSrtt();
  }

  bool
  hasSrttMeasurement() const
  {
    return getSrtt() != RttStats::RTT_NO_MEASUREMENT;
  }

private:
  void
  cancelTimeoutEvent();

  bool
  doesNameMatchLastInterest(const ndn::Name& name);

private:
  RttStats m_rttStats;
  ndn::Name m_lastInterestName;

  // Timeout associated with measurement
  scheduler::EventId m_measurementExpirationId;

  // RTO associated with Interest
  scheduler::EventId m_timeoutEventId;
  bool m_isTimeoutScheduled;
};

typedef std::unordered_map<face::FaceId, FaceInfo> FaceInfoTable;

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/** \brief stores stategy information about each face in this namespace
 */
class NamespaceInfo : public StrategyInfo
{
public:
  NamespaceInfo();

  static constexpr int
  getTypeId()
  {
    return 1030;
  }

  FaceInfo&
  getOrCreateFaceInfo(const fib::Entry& fibEntry, const Face& face);

  FaceInfo*
  getFaceInfo(const fib::Entry& fibEntry, const Face& face);

  void
  expireFaceInfo(nfd::face::FaceId faceId);

  void
  extendFaceInfoLifetime(FaceInfo& info, const Face& face);

  FaceInfo&
  get(nfd::face::FaceId faceId)
  {
    return m_fit.at(faceId);
  }

  FaceInfoTable::iterator
  find(nfd::face::FaceId faceId)
  {
    return m_fit.find(faceId);
  }

  FaceInfoTable::iterator
  end()
  {
    return m_fit.end();
  }

  const FaceInfoTable::iterator
  insert(nfd::face::FaceId faceId)
  {
    const auto& pair = m_fit.insert(std::make_pair(faceId, FaceInfo()));
    return pair.first;
  }

  bool
  isProbingDue() const
  {
    return m_isProbingDue;
  }

  void
  setIsProbingDue(bool isProbingDue)
  {
    m_isProbingDue = isProbingDue;
  }

  bool
  isFirstProbeScheduled() const
  {
    return m_hasFirstProbeBeenScheduled;
  }

  void
  setHasFirstProbeBeenScheduled(bool hasBeenScheduled)
  {
    m_hasFirstProbeBeenScheduled = hasBeenScheduled;
  }

private:
  FaceInfoTable m_fit;

  bool m_isProbingDue;
  bool m_hasFirstProbeBeenScheduled;
};

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/** \brief Helper class to retrieve and create strategy measurements
 */
class AsfMeasurements : noncopyable
{
public:
  explicit
  AsfMeasurements(MeasurementsAccessor& measurements);

  FaceInfo*
  getFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face);

  FaceInfo&
  getOrCreateFaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest, const Face& face);

  shared_ptr<NamespaceInfo>
  getNamespaceInfo(const ndn::Name& prefix);

  NamespaceInfo&
  getOrCreateNamespaceInfo(const fib::Entry& fibEntry, const ndn::Interest& interest);

  void
  extendLifetime(shared_ptr<measurements::Entry> me);

public:
  static constexpr time::microseconds MEASUREMENTS_LIFETIME = time::seconds(300);

private:
  MeasurementsAccessor& m_measurements;
};

} // namespace asf
} // namespace fw
} // namespace nfd

#endif // NFD_DAEMON_FW_ASF_MEASUREMENTS_HPP
