/* -*- 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);

private:
  void
  extendLifetime(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
