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

#include <cstdint>
#include <functional>
#include <limits>
#include <map>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "api/call/transport.h"
#include "api/crypto/crypto_options.h"
#include "api/crypto/frame_decryptor_interface.h"
#include "api/frame_transformer_interface.h"
#include "api/rtp_headers.h"
#include "api/rtp_packet_infos.h"
#include "api/scoped_refptr.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/recordable_encoded_frame.h"
#include "api/video/video_content_type.h"
#include "api/video/video_frame.h"
#include "api/video/video_sink_interface.h"
#include "api/video/video_timing.h"
#include "api/video_codecs/sdp_video_format.h"
#include "call/receive_stream.h"
#include "call/rtp_config.h"
#include "common_video/frame_counts.h"
#include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"

namespace webrtc {

class RtpPacketSinkInterface;
class VideoDecoderFactory;

class VideoReceiveStreamInterface : public MediaReceiveStreamInterface {
 public:
  // Class for handling moving in/out recording state.
  struct RecordingState {
    RecordingState() = default;
    explicit RecordingState(
        std::function<void(const RecordableEncodedFrame&)> callback)
        : callback(std::move(callback)) {}

    // Callback stored from the VideoReceiveStreamInterface. The
    // VideoReceiveStreamInterface client should not interpret the attribute.
    std::function<void(const RecordableEncodedFrame&)> callback;
    // Memento of when a keyframe request was last sent. The
    // VideoReceiveStreamInterface client should not interpret the attribute.
    std::optional<int64_t> last_keyframe_request_ms;
  };

  // TODO(mflodman) Move all these settings to VideoDecoder and move the
  // declaration to common_types.h.
  struct Decoder {
    Decoder(SdpVideoFormat video_format, int payload_type);
    Decoder();
    Decoder(const Decoder&);
    ~Decoder();

    bool operator==(const Decoder& other) const;

    std::string ToString() const;

    SdpVideoFormat video_format;

    // Received RTP packets with this payload type will be sent to this decoder
    // instance.
    int payload_type = 0;
  };

  struct Stats {
    Stats();
    ~Stats();
    std::string ToString(int64_t time_ms,
                         std::optional<Stats> previous_stats) const;

    int network_frame_rate = 0;
    int decode_frame_rate = 0;
    int render_frame_rate = 0;
    uint32_t frames_rendered = 0;

    // Decoder stats.
    std::optional<std::string> decoder_implementation_name;
    std::optional<bool> power_efficient_decoder;
    int decode_ms = 0;
    int max_decode_ms = 0;
    int current_delay_ms = 0;
    int target_delay_ms = 0;
    int jitter_buffer_ms = 0;
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbufferdelay
    TimeDelta jitter_buffer_delay = TimeDelta::Zero();
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbuffertargetdelay
    TimeDelta jitter_buffer_target_delay = TimeDelta::Zero();
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbufferemittedcount
    uint64_t jitter_buffer_emitted_count = 0;
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-jitterbufferminimumdelay
    TimeDelta jitter_buffer_minimum_delay = TimeDelta::Zero();
    int min_playout_delay_ms = 0;
    int render_delay_ms = 10;
    int64_t interframe_delay_max_ms = -1;
    // Frames dropped due to decoding failures or if the system is too slow.
    // https://www.w3.org/TR/webrtc-stats/#dom-rtcvideoreceiverstats-framesdropped
    uint32_t frames_dropped = 0;
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-framesdecoded
    uint32_t frames_decoded = 0;
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-keyframesdecoded
    uint32_t key_frames_decoded = 0;
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime
    TimeDelta total_decode_time = TimeDelta::Zero();
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay
    TimeDelta total_processing_delay = TimeDelta::Zero();

    // Counted when inserted into the frame buffer, before decoding.
    FrameCounts received_frame_counts;

    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalassemblytime
    TimeDelta total_assembly_time = TimeDelta::Zero();
    uint32_t frames_assembled_from_multiple_packets = 0;

    // Total inter frame delay in seconds.
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalinterframedelay
    double total_inter_frame_delay = 0;
    // Total squared inter frame delay in seconds^2.
    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalsqauredinterframedelay
    double total_squared_inter_frame_delay = 0;
    int64_t first_frame_received_to_decoded_ms = -1;
    std::optional<uint64_t> qp_sum;

    // Corruption score, indicating the probability of corruption. Its value is
    // between 0 and 1, where 0 means no corruption and 1 means that the
    // compressed frame is corrupted.
    // However, note that the corruption score may not accurately reflect
    // corruption. E.g. even if the corruption score is 0, the compressed frame
    // may still be corrupted and vice versa.
    std::optional<double> corruption_score_sum;
    std::optional<double> corruption_score_squared_sum;
    // Number of frames the `corruption_score` was calculated on. This is
    // usually not the same as `frames_decoded`.
    uint32_t corruption_score_count = 0;

    int current_payload_type = -1;

    int total_bitrate_bps = 0;

    int width = 0;
    int height = 0;

    uint32_t freeze_count = 0;
    uint32_t pause_count = 0;
    uint32_t total_freezes_duration_ms = 0;
    uint32_t total_pauses_duration_ms = 0;

    VideoContentType content_type = VideoContentType::UNSPECIFIED;

    // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-estimatedplayouttimestamp
    std::optional<int64_t> estimated_playout_ntp_timestamp_ms;
    int sync_offset_ms = std::numeric_limits<int>::max();

    uint32_t ssrc = 0;
    std::string c_name;
    RtpReceiveStats rtp_stats;
    RtcpPacketTypeCounter rtcp_packet_type_counts;
    std::optional<RtpReceiveStats> rtx_rtp_stats;

    // Timing frame info: all important timestamps for a full lifetime of a
    // single 'timing frame'.
    std::optional<webrtc::TimingFrameInfo> timing_frame_info;

    // Remote outbound stats derived by the received RTCP sender reports.
    // https://w3c.github.io/webrtc-stats/#remoteoutboundrtpstats-dict*
    std::optional<Timestamp> last_sender_report_timestamp;
    // TODO: bugs.webrtc.org/370535296 - Remove the utc timestamp when linked
    // issue is fixed.
    std::optional<Timestamp> last_sender_report_utc_timestamp;
    std::optional<Timestamp> last_sender_report_remote_utc_timestamp;
    uint32_t sender_reports_packets_sent = 0;
    uint64_t sender_reports_bytes_sent = 0;
    uint64_t sender_reports_reports_count = 0;
    // Non-sender RTT (RRTR/DLRR), surfaced into
    // RTCRemoteOutboundRtpStreamStats for recvonly endpoints.
    std::optional<TimeDelta> round_trip_time;
    TimeDelta total_round_trip_time = TimeDelta::Zero();
    int round_trip_time_measurements = 0;
  };

  struct Config {
   public:
    Config() = delete;
    Config(const Config&) = delete;
    Config& operator=(const Config&) = delete;
    Config(Config&&);
    Config(Transport* rtcp_send_transport,
           VideoDecoderFactory* decoder_factory = nullptr,
           absl::AnyInvocable<void(const RtpPacketInfos&, Timestamp) const>
               on_frame_delivered_callback = nullptr);
    Config& operator=(Config&&);
    ~Config();

    // Mostly used by tests. Avoid creating copies if you can.
    // Note that this method will not copy move-only fields.
    Config Copy() const;

    std::string ToString() const;

    // Decoders for every payload that we can receive.
    std::vector<Decoder> decoders;

    // Ownership stays with WebrtcVideoEngine (delegated from PeerConnection).
    VideoDecoderFactory* decoder_factory = nullptr;

    // Receive-stream specific RTP settings.
    struct Rtp : public ReceiveStreamRtpConfig {
      Rtp();
      Rtp(const Rtp&);
      ~Rtp();
      std::string ToString() const;

      // See NackConfig for description.
      NackConfig nack;

      // See RtcpMode for description.
      RtcpMode rtcp_mode = RtcpMode::kCompound;

      // Extended RTCP settings.
      struct RtcpXr {
        // True if RTCP Receiver Reference Time Report Block extension
        // (RFC 3611) should be enabled.
        bool receiver_reference_time_report = false;
      } rtcp_xr;

      // How to request keyframes from a remote sender. Applies only if lntf is
      // disabled.
      KeyFrameReqMethod keyframe_method = KeyFrameReqMethod::kPliRtcp;

      // See LntfConfig for description.
      LntfConfig lntf;

      // Payload types for ULPFEC and RED, respectively.
      int ulpfec_payload_type = -1;
      int red_payload_type = -1;

      // SSRC for retransmissions.
      uint32_t rtx_ssrc = 0;

      // Set if the stream is protected using FlexFEC.
      bool protected_by_flexfec = false;

      // Optional callback sink to support additional packet handlers such as
      // FlexFec.
      RtpPacketSinkInterface* packet_sink_ = nullptr;

      // Map from rtx payload type -> media payload type.
      // For RTX to be enabled, both an SSRC and this mapping are needed.
      std::map<int, int> rtx_associated_payload_types;

      // Payload types that should be depacketized using raw depacketizer
      // (payload header will not be parsed and must not be present, additional
      // meta data is expected to be present in generic frame descriptor
      // RTP header extension).
      std::set<int> raw_payload_types;
    } rtp;

    // Transport for outgoing packets (RTCP).
    Transport* rtcp_send_transport = nullptr;

    // Must always be set.
    VideoSinkInterface<VideoFrame>* renderer = nullptr;

    // Expected delay needed by the renderer, i.e. the frame will be delivered
    // this many milliseconds, if possible, earlier than the ideal render time.
    int render_delay_ms = 10;

    // If false, pass frames on to the renderer as soon as they are
    // available.
    bool enable_prerenderer_smoothing = true;

    // Identifier for an A/V synchronization group. Empty string to disable.
    // TODO(pbos): Synchronize streams in a sync group, not just video streams
    // to one of the audio streams.
    std::string sync_group;

    // An optional custom frame decryptor that allows the entire frame to be
    // decrypted in whatever way the caller choses. This is not required by
    // default.
    scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor;

    // Per PeerConnection cryptography options.
    CryptoOptions crypto_options;

    scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer;

    // Callback invoked on the first received packet for this stream. Note that
    // this is a move-only callback and is not copied when calling Copy().
    absl::AnyInvocable<void(uint32_t ssrc) &&> on_first_packet;

    // Callback invoked when a frame has been delivered. Note that this is a
    // move-only callback and is not copied when calling Copy().
    absl::AnyInvocable<void(const RtpPacketInfos&, Timestamp) const>
        on_frame_delivered_callback;
  };

  // TODO(pbos): Add info on currently-received codec to Stats.
  virtual Stats GetStats() const = 0;

  // Sets a base minimum for the playout delay. Base minimum delay sets lower
  // bound on minimum delay value determining lower bound on playout delay.
  //
  // Returns true if value was successfully set, false overwise.
  virtual bool SetBaseMinimumPlayoutDelayMs(int delay_ms) = 0;

  // Returns current value of base minimum delay in milliseconds.
  virtual int GetBaseMinimumPlayoutDelayMs() const = 0;

  // Sets and returns recording state. The old state is moved out
  // of the video receive stream and returned to the caller, and `state`
  // is moved in. If the state's callback is set, it will be called with
  // recordable encoded frames as they arrive.
  // If `generate_key_frame` is true, the method will generate a key frame.
  // When the function returns, it's guaranteed that all old callouts
  // to the returned callback has ceased.
  // Note: the client should not interpret the returned state's attributes, but
  // instead treat it as opaque data.
  virtual RecordingState SetAndGetRecordingState(RecordingState state,
                                                 bool generate_key_frame) = 0;

  // Cause eventual generation of a key frame from the sender.
  virtual void GenerateKeyFrame() = 0;

  // Sets or clears a flexfec RTP sink. This affects `rtp.packet_sink_` and
  // `rtp.protected_by_flexfec` parts of the configuration. Must be called on
  // the packet delivery thread.
  // TODO(bugs.webrtc.org/11993): Packet delivery thread today means `worker
  // thread` but will be `network thread`.
  virtual void SetFlexFecProtection(RtpPacketSinkInterface* flexfec_sink) = 0;

  // Turns on/off loss notifications. Must be called on the packet delivery
  // thread.
  virtual void SetLossNotificationEnabled(bool enabled) = 0;

  // Modify `rtp.nack.rtp_history_ms` post construction. Setting this value
  // to 0 disables nack.
  // Must be called on the packet delivery thread.
  virtual void SetNackHistory(TimeDelta history) = 0;

  virtual void SetProtectionPayloadTypes(int red_payload_type,
                                         int ulpfec_payload_type) = 0;

  virtual void SetRtcpXr(Config::Rtp::RtcpXr rtcp_xr) = 0;

  virtual void SetAssociatedPayloadTypes(
      std::map<int, int> associated_payload_types) = 0;

  virtual void SetDecoders(std::vector<Decoder> decoders) = 0;

  virtual void SetRawPayloadTypes(std::set<int> raw_payload_types) = 0;

  virtual void UpdateRtxSsrc(uint32_t ssrc) = 0;

 protected:
  ~VideoReceiveStreamInterface() override {}
};

}  // namespace webrtc

#endif  // CALL_VIDEO_RECEIVE_STREAM_H_
