/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_VOICE_ENGINE_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_
#define WEBRTC_VOICE_ENGINE_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_

#include <map>

#include "webrtc/api/optional.h"
#include "webrtc/modules/include/module_common_types.h"

namespace webrtc {

namespace rtcp {
class TransportFeedback;
}

struct PacketFeedback;

class TransportFeedbackPacketLossTracker final {
 public:
  // * We count up to |max_window_size_ms| from the sent
  //   time of the latest acked packet for the calculation of the metrics.
  // * PLR (packet-loss-rate) is reliably computable once the statuses of
  //   |plr_min_num_acked_packets| packets are known.
  // * RPLR (recoverable-packet-loss-rate) is reliably computable once the
  //   statuses of |rplr_min_num_acked_pairs| pairs are known.
  TransportFeedbackPacketLossTracker(int64_t max_window_size_ms,
                                     size_t plr_min_num_acked_packets,
                                     size_t rplr_min_num_acked_pairs);

  void OnPacketAdded(uint16_t seq_num, int64_t send_time_ms);

  void OnPacketFeedbackVector(
      const std::vector<PacketFeedback>& packet_feedbacks_vector);

  // Returns the packet loss rate, if the window has enough packet statuses to
  // reliably compute it. Otherwise, returns empty.
  rtc::Optional<float> GetPacketLossRate() const;

  // Returns the first-order-FEC recoverable packet loss rate, if the window has
  // enough status pairs to reliably compute it. Otherwise, returns empty.
  rtc::Optional<float> GetRecoverablePacketLossRate() const;

  // Verifies that the internal states are correct. Only used for tests.
  void Validate() const;

 private:
  // When a packet is sent, we memorize its association with the stream by
  // marking it as (sent-but-so-far-) unacked. If we ever receive a feedback
  // that reports it as received/lost, we update the state and
  // metrics accordingly.

  enum class PacketStatus { Unacked = 0, Received = 1, Lost = 2 };
  struct SentPacket {
    SentPacket(int64_t send_time_ms, PacketStatus status)
        : send_time_ms(send_time_ms), status(status) {}
    int64_t send_time_ms;
    PacketStatus status;
  };
  typedef std::map<uint16_t, SentPacket> SentPacketStatusMap;
  typedef SentPacketStatusMap::const_iterator ConstPacketStatusIterator;

  void Reset();

  // ReferenceSequenceNumber() provides a sequence number that defines the
  // order of packet reception info stored in |packet_status_window_|. In
  // particular, given any sequence number |x|,
  // (2^16 + x - ref_seq_num_) % 2^16 defines its actual position in
  // |packet_status_window_|.
  uint16_t ReferenceSequenceNumber() const;
  uint16_t NewestSequenceNumber() const;
  void UpdatePacketStatus(SentPacketStatusMap::iterator it,
                          PacketStatus new_status);
  void RemoveOldestPacketStatus();

  void UpdateMetrics(ConstPacketStatusIterator it,
                     bool apply /* false = undo */);
  void UpdatePlr(ConstPacketStatusIterator it, bool apply /* false = undo */);
  void UpdateRplr(ConstPacketStatusIterator it, bool apply /* false = undo */);

  ConstPacketStatusIterator PreviousPacketStatus(
      ConstPacketStatusIterator it) const;
  ConstPacketStatusIterator NextPacketStatus(
      ConstPacketStatusIterator it) const;

  const int64_t max_window_size_ms_;
  size_t acked_packets_;

  SentPacketStatusMap packet_status_window_;
  // |ref_packet_status_| points to the oldest item in |packet_status_window_|.
  ConstPacketStatusIterator ref_packet_status_;

  // Packet-loss-rate calculation (lost / all-known-packets).
  struct PlrState {
    explicit PlrState(size_t min_num_acked_packets)
        : min_num_acked_packets_(min_num_acked_packets) {
      Reset();
    }
    void Reset() {
      num_received_packets_ = 0;
      num_lost_packets_ = 0;
    }
    rtc::Optional<float> GetMetric() const;
    const size_t min_num_acked_packets_;
    size_t num_received_packets_;
    size_t num_lost_packets_;
  } plr_state_;

  // Recoverable packet loss calculation (first-order-FEC recoverable).
  struct RplrState {
    explicit RplrState(size_t min_num_acked_pairs)
        : min_num_acked_pairs_(min_num_acked_pairs) {
      Reset();
    }
    void Reset() {
      num_acked_pairs_ = 0;
      num_recoverable_losses_ = 0;
    }
    rtc::Optional<float> GetMetric() const;
    // Recoverable packets are those which were lost, but immediately followed
    // by a properly received packet. If that second packet carried FEC,
    // the data from the former (lost) packet could be recovered.
    // The RPLR is calculated as the fraction of such pairs (lost-received) out
    // of all pairs of consecutive acked packets.
    const size_t min_num_acked_pairs_;
    size_t num_acked_pairs_;
    size_t num_recoverable_losses_;
  } rplr_state_;
};

}  // namespace webrtc

#endif  // WEBRTC_VOICE_ENGINE_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_
