/*
 *  Copyright 2015 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.
 */

// This file contains interfaces for RtpReceivers
// http://w3c.github.io/webrtc-pc/#rtcrtpreceiver-interface

#ifndef API_RTP_RECEIVER_INTERFACE_H_
#define API_RTP_RECEIVER_INTERFACE_H_

#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "api/crypto/frame_decryptor_interface.h"
#include "api/dtls_transport_interface.h"
#include "api/frame_transformer_interface.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/ref_count.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/sframe/sframe_decryptor_interface.h"
#include "api/sframe/sframe_types.h"
#include "api/transport/rtp/rtp_source.h"
#include "rtc_base/checks.h"
#include "rtc_base/system/rtc_export.h"

namespace webrtc {

class RtpReceiverObserverInterface {
 public:
  // Note: Currently if there are multiple RtpReceivers of the same media type,
  // they will all call OnFirstPacketReceived at once.
  //
  // In the future, it's likely that an RtpReceiver will only call
  // OnFirstPacketReceived when a packet is received specifically for its
  // SSRC/mid.
  virtual void OnFirstPacketReceived(MediaType media_type) = 0;
  // Similar to the above but done whenever the receptiveness changed.
  // TODO: crbug.com/40821064 - make virtual after Chromium roll.
  virtual void OnFirstPacketReceivedAfterReceptiveChange(MediaType media_type) {
  }

  // Triggered on the signaling thread when the received SSRC or CSRC set
  // changes. Frame delivery notifications are posted asynchronously from the
  // media thread to the signaling thread, where observer callbacks are invoked
  // after the receiver's source maps are updated.
  // May also be called synchronously from SetObserver() if sources are already
  // known.
  virtual void OnSourceChanged(bool ssrc_changed, bool csrc_changed) {}

 protected:
  virtual ~RtpReceiverObserverInterface() {}
};

class RTC_EXPORT RtpReceiverInterface : public RefCountInterface,
                                        public FrameTransformerHost {
 public:
  virtual scoped_refptr<MediaStreamTrackInterface> track() const = 0;

  // The dtlsTransport attribute exposes the DTLS transport on which the
  // media is received. It may be null.
  // https://w3c.github.io/webrtc-pc/#dom-rtcrtpreceiver-transport
  // TODO(https://bugs.webrtc.org/907849) remove default implementation
  virtual scoped_refptr<DtlsTransportInterface> dtls_transport() const;

  // The list of streams that `track` is associated with. This is the same as
  // the [[AssociatedRemoteMediaStreams]] internal slot in the spec.
  // https://w3c.github.io/webrtc-pc/#dfn-associatedremotemediastreams
  // TODO(hbos): Make pure virtual as soon as Chromium's mock implements this.
  // TODO(https://crbug.com/webrtc/9480): Remove streams() in favor of
  // stream_ids() as soon as downstream projects are no longer dependent on
  // stream objects.
  virtual std::vector<std::string> stream_ids() const;
  virtual std::vector<scoped_refptr<MediaStreamInterface>> streams() const;

  // Audio or video receiver?
  virtual MediaType media_type() const = 0;

  // Not to be confused with "mid", this is a field we can temporarily use
  // to uniquely identify a receiver until we implement Unified Plan SDP.
  virtual std::string id() const = 0;

  // The WebRTC specification only defines RTCRtpParameters in terms of senders,
  // but this API also applies them to receivers.
  virtual RtpParameters GetParameters() const = 0;
  // TODO(dinosaurav): Delete SetParameters entirely after rolling to Chromium.
  // Currently, doesn't support changing any parameters.
  virtual bool SetParameters(const RtpParameters& /* parameters */) {
    return false;
  }

  // Does not take ownership of observer.
  // Must call SetObserver(nullptr) before the observer is destroyed.
  virtual void SetObserver(RtpReceiverObserverInterface* observer) = 0;

  // Sets the jitter buffer minimum delay until media playout. Actual observed
  // delay may differ depending on the congestion control. `delay_seconds` is a
  // positive value including 0.0 measured in seconds. `nullopt` means default
  // value must be used.
  virtual void SetJitterBufferMinimumDelay(
      std::optional<double> delay_seconds) = 0;

  // TODO(zhihuang): Remove the default implementation once the subclasses
  // implement this. Currently, the only relevant subclass is the
  // content::FakeRtpReceiver in Chromium.
  virtual std::vector<RtpSource> GetSources() const;

  // Sets a user defined frame decryptor that will decrypt the entire frame
  // before it is sent across the network. This will decrypt the entire frame
  // using the user provided decryption mechanism regardless of whether SRTP is
  // enabled or not.
  // TODO(bugs.webrtc.org/12772): Remove.
  virtual void SetFrameDecryptor(
      scoped_refptr<FrameDecryptorInterface> frame_decryptor);

  // Returns a pointer to the frame decryptor set previously by the
  // user. This can be used to update the state of the object.
  // TODO(bugs.webrtc.org/12772): Remove.
  virtual scoped_refptr<FrameDecryptorInterface> GetFrameDecryptor() const;

  // Sets a frame transformer between the depacketizer and the decoder to enable
  // client code to transform received frames according to their own processing
  // logic.
  [[deprecated("Use SetFrameTransformer")]] virtual void
  SetDepacketizerToDecoderFrameTransformer(
      scoped_refptr<FrameTransformerInterface> frame_transformer) {
    SetFrameTransformer(std::move(frame_transformer));
  }

  // Default implementation of SetFrameTransformer.
  // TODO: bugs.webrtc.org/15929 - Make pure virtual.
  void SetFrameTransformer(
      scoped_refptr<FrameTransformerInterface> frame_transformer) override;

  // Creates an internal Sframe decrypter and returns a handle for key
  // management.
  // Default implementation of CreateSframeDecryptorOrError.
  // TODO: issues.webrtc.org/479862368 - make pure virtual when all
  // implementations are updated
  virtual RTCErrorOr<scoped_refptr<SframeDecryptorInterface>>
  CreateSframeDecryptorOrError(SframeCipherSuite cipher_suite) {
    RTC_DCHECK_NOTREACHED();
    return RTCError();
  }

 protected:
  ~RtpReceiverInterface() override = default;
};

}  // namespace webrtc

#endif  // API_RTP_RECEIVER_INTERFACE_H_
