/*
 *  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 AUDIO_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_
#define AUDIO_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_

#include <map>
#include <vector>

#include "api/optional.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  // AUDIO_TRANSPORT_FEEDBACK_PACKET_LOSS_TRACKER_H_
