/*
 *  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/sequenced_task_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(sequenced_task_checker_);

  LossNotificationSender* const loss_notification_sender_
      RTC_GUARDED_BY(sequenced_task_checker_);

  SeqNumUnwrapper<uint16_t> frame_id_unwrapper_
      RTC_GUARDED_BY(sequenced_task_checker_);

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

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

  // Tracked in order to correctly report the potential-decodability of
  // multi-packet frames.
  bool current_frame_potentially_decodable_
      RTC_GUARDED_BY(sequenced_task_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(sequenced_task_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(sequenced_task_checker_);

  rtc::SequencedTaskChecker sequenced_task_checker_;
};

}  // namespace webrtc

#endif  // MODULES_VIDEO_CODING_LOSS_NOTIFICATION_CONTROLLER_H_
