/*
 *  Copyright (c) 2019 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 MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
#define MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_

#include <set>

#include "absl/types/optional.h"
#include "modules/include/module_common_types.h"
#include "modules/video_coding/packet.h"
#include "rtc_base/numerics/sequence_number_util.h"
#include "rtc_base/synchronization/sequence_checker.h"

namespace webrtc {

class LossNotificationController {
 public:
  LossNotificationController(KeyFrameRequestSender* key_frame_request_sender,
                             LossNotificationSender* loss_notification_sender);
  ~LossNotificationController();

  // An RTP packet was received from the network.
  void OnReceivedPacket(const VCMPacket& packet);

  // A frame was assembled from packets previously received.
  // (Should be called even if the frame was composed of a single packet.)
  void OnAssembledFrame(uint16_t first_seq_num,
                        uint16_t frame_id,
                        bool discardable,
                        rtc::ArrayView<const uint16_t> frame_dependency_diffs);

 private:
  void DiscardOldInformation();

  bool AllDependenciesDecodable(
      int64_t unwrapped_frame_id,
      rtc::ArrayView<const uint16_t> frame_dependency_diffs) const;

  // When the loss of a packet or the non-decodability of a frame is detected,
  // produces a key frame request or a loss notification.
  // 1. |last_received_seq_num| is the last received sequence number.
  // 2. |decodability_flag| refers to the frame associated with the last packet.
  //    It is set to |true| if and only if all of that frame's dependencies are
  //    known to be decodable, and the frame itself is not yet known to be
  //    unassemblable (i.e. no earlier parts of it were lost).
  //    Clarifications:
  //    a. In a multi-packet frame, the first packet reveals the frame's
  //       dependencies, but it is not yet known whether all parts of the
  //       current frame will be received.
  //    b. In a multi-packet frame, if the first packet is missed, the
  //       dependencies are unknown, but it is known that the frame itself
  //       is unassemblable.
  void HandleLoss(uint16_t last_received_seq_num, bool decodability_flag);

  KeyFrameRequestSender* const key_frame_request_sender_
      RTC_GUARDED_BY(sequence_checker_);

  LossNotificationSender* const loss_notification_sender_
      RTC_GUARDED_BY(sequence_checker_);

  SeqNumUnwrapper<uint16_t> frame_id_unwrapper_
      RTC_GUARDED_BY(sequence_checker_);

  // Tracked to avoid processing repeated frames (buggy/malicious remote).
  absl::optional<int64_t> last_received_unwrapped_frame_id_
      RTC_GUARDED_BY(sequence_checker_);

  // Tracked to avoid processing repeated packets.
  absl::optional<uint16_t> last_received_seq_num_
      RTC_GUARDED_BY(sequence_checker_);

  // Tracked in order to correctly report the potential-decodability of
  // multi-packet frames.
  bool current_frame_potentially_decodable_ RTC_GUARDED_BY(sequence_checker_);

  // Loss notifications contain the sequence number of the first packet of
  // the last decodable-and-non-discardable frame. Since this is a bit of
  // a mouthful, last_decodable_non_discardable_.first_seq_num is used,
  // which hopefully is a bit easier for human beings to parse
  // than |first_seq_num_of_last_decodable_non_discardable_|.
  struct FrameInfo {
    explicit FrameInfo(uint16_t first_seq_num) : first_seq_num(first_seq_num) {}
    uint16_t first_seq_num;
  };
  absl::optional<FrameInfo> last_decodable_non_discardable_
      RTC_GUARDED_BY(sequence_checker_);

  // Track which frames are decodable. Later frames are also decodable if
  // all of their dependencies can be found in this container.
  // (Naturally, later frames must also be assemblable to be decodable.)
  std::set<int64_t> decodable_unwrapped_frame_ids_
      RTC_GUARDED_BY(sequence_checker_);

  SequenceChecker sequence_checker_;
};

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
