/* -*- 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/common.hpp"
#include "core/rtt-estimator.hpp"
#include "core/scheduler.hpp"

#include "face-log.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
