/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  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_FACE_LP_RELIABILITY_HPP
#define NFD_DAEMON_FACE_LP_RELIABILITY_HPP

#include "core/rtt-estimator.hpp"
#include "core/scheduler.hpp"

#include <ndn-cxx/lp/packet.hpp>
#include <ndn-cxx/lp/sequence.hpp>

#include <queue>

namespace nfd {
namespace face {

class GenericLinkService;

/** \brief provides for reliable sending and receiving of link-layer packets
 *  \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2
 */
class LpReliability : noncopyable
{
public:
  struct Options
  {
    /** \brief enables link-layer reliability
     */
    bool isEnabled = false;

    /** \brief maximum number of retransmissions for an LpPacket
     */
    size_t maxRetx = 3;

    /** \brief period between sending pending Acks in an IDLE packet
     */
    time::nanoseconds idleAckTimerPeriod = time::milliseconds(5);

    /** \brief a fragment is considered lost if this number of fragments with greater sequence
     *         numbers are acknowledged
     */
    size_t seqNumLossThreshold = 3;
  };

  LpReliability(const Options& options, GenericLinkService* linkService);

  /** \brief set options for reliability
   */
  void
  setOptions(const Options& options);

  /** \return GenericLinkService that owns this instance
   *
   *  This is only used for logging, and may be nullptr.
   */
  const GenericLinkService*
  getLinkService() const;

  /** \brief observe outgoing fragment(s) of a network packet
   *  \param frags fragments of network packet
   */
  void
  observeOutgoing(const std::vector<lp::Packet>& frags);

  /** \brief extract and parse all Acks and add Ack for contained Fragment (if any) to AckQueue
   *  \param pkt incoming LpPacket
   */
  void
  processIncomingPacket(const lp::Packet& pkt);

  /** \brief called by GenericLinkService to attach Acks onto an outgoing LpPacket
   *  \param pkt outgoing LpPacket to attach Acks to
   *  \param mtu MTU of the Transport
   */
  void
  piggyback(lp::Packet& pkt, ssize_t mtu);

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  /** \brief start the idle Ack timer
   *
   * This timer requests an IDLE packet to acknowledge pending fragments not already piggybacked.
   * It is called regularly on a period configured in Options::idleAckTimerPeriod. This allows Acks
   * to be returned to the sender, even if the link goes idle.
   */
  void
  startIdleAckTimer();

  /** \brief cancel the idle Ack timer
   */
  void
  stopIdleAckTimer();

private:
  /** \brief find and mark as lost fragments where a configurable number of Acks have been received
   *         for greater sequence numbers
   *  \param ackSeq sequence number of received Ack
   *  \return vector containing sequence numbers marked lost by this mechanism
   */
  std::vector<lp::Sequence>
  findLostLpPackets(lp::Sequence ackSeq);

  /** \brief resend (or declare as lost) a lost fragment
   */
  void
  onLpPacketLost(lp::Sequence seq);

  class UnackedFrag;
  class NetPkt;

  /** \brief remove the fragment with the given sequence number from the map of unacknowledged
   *         fragments as well as its associated network packet
   *  \param fragIt iterator to fragment to be removed
   *
   *  If the given sequence marks the beginning of the send window, the window will be incremented.
   *  If the associated network packet has been fully transmitted, it will be removed.
   */
  void
  onLpPacketAcknowledged(std::map<lp::Sequence, UnackedFrag>::iterator fragIt,
                         std::map<lp::Sequence, NetPkt>::iterator netPktIt);

  std::map<lp::Sequence, NetPkt>::iterator
  getNetPktByFrag(lp::Sequence seq);

private:
  /** \brief contains a sent fragment that has not been acknowledged and associated data
   */
  class UnackedFrag
  {
  public:
    // Allows implicit conversion from an lp::Packet
    UnackedFrag(lp::Packet pkt);

  public:
    lp::Packet pkt;
    scheduler::ScopedEventId rtoTimer;
    time::steady_clock::TimePoint sendTime;
    size_t retxCount;
    size_t nGreaterSeqAcks; //!< number of Acks received for sequences greater than this fragment
    bool wasTimedOutBySeq; //!< whether this fragment has been timed out by the sequence number mechanic
  };

  /** \brief contains a network-layer packet with unacknowledged fragments
   */
  class NetPkt
  {
  public:
    NetPkt();

  public:
    std::set<lp::Sequence> unackedFrags;
    bool didRetx;
  };

PUBLIC_WITH_TESTS_ELSE_PRIVATE:
  Options m_options;
  GenericLinkService* m_linkService;
  std::map<lp::Sequence, UnackedFrag> m_unackedFrags;
  std::map<lp::Sequence, UnackedFrag>::iterator m_firstUnackedFrag;
  std::map<lp::Sequence, NetPkt> m_netPkts;
  std::queue<lp::Sequence> m_ackQueue;
  scheduler::ScopedEventId m_idleAckTimer;
  bool m_isIdleAckTimerRunning;
  RttEstimator m_rto;
};

} // namespace face
} // namespace nfd

#endif // NFD_DAEMON_FACE_LP_RELIABILITY_HPP
