/*
 *  Copyright 2020 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 API_FRAME_TRANSFORMER_INTERFACE_H_
#define API_FRAME_TRANSFORMER_INTERFACE_H_

#include <cstdint>
#include <memory>
#include <optional>
#include <string>

#include "api/array_view.h"
#include "api/ref_count.h"
#include "api/scoped_refptr.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_frame_metadata.h"
#include "rtc_base/system/rtc_export.h"

namespace webrtc {

// Owns the frame payload data.
class TransformableFrameInterface {
 public:
  // Only a known list of internal implementations of transformable frames are
  // permitted to allow internal downcasting. This is enforced via the
  // internally-constructable Passkey.
  // TODO: bugs.webrtc.org/339815768 - Remove this passkey once the
  // downcasts are removed.
  class Passkey;
  RTC_EXPORT explicit TransformableFrameInterface(Passkey);

  TransformableFrameInterface(TransformableFrameInterface&&) = default;
  TransformableFrameInterface& operator=(TransformableFrameInterface&&) =
      default;

  virtual ~TransformableFrameInterface() = default;

  // Returns the frame payload data. The data is valid until the next non-const
  // method call.
  virtual rtc::ArrayView<const uint8_t> GetData() const = 0;

  // Copies `data` into the owned frame payload data.
  virtual void SetData(rtc::ArrayView<const uint8_t> data) = 0;

  virtual uint8_t GetPayloadType() const = 0;
  virtual uint32_t GetSsrc() const = 0;
  virtual uint32_t GetTimestamp() const = 0;
  virtual void SetRTPTimestamp(uint32_t timestamp) = 0;

  // TODO(https://bugs.webrtc.org/373365537): Remove this once its usage is
  // removed from blink.
  virtual std::optional<Timestamp> GetCaptureTimeIdentifier() const {
    return std::nullopt;
  }

  // TODO(https://bugs.webrtc.org/14878): Change this to pure virtual after it
  // is implemented everywhere.
  virtual std::optional<Timestamp> GetPresentationTimestamp() const {
    return std::nullopt;
  }

  enum class Direction {
    kUnknown,
    kReceiver,
    kSender,
  };
  // TODO(crbug.com/1250638): Remove this distinction between receiver and
  // sender frames to allow received frames to be directly re-transmitted on
  // other PeerConnectionss.
  virtual Direction GetDirection() const { return Direction::kUnknown; }
  virtual std::string GetMimeType() const = 0;
};

class TransformableVideoFrameInterface : public TransformableFrameInterface {
 public:
  RTC_EXPORT explicit TransformableVideoFrameInterface(Passkey passkey);
  virtual ~TransformableVideoFrameInterface() = default;
  virtual bool IsKeyFrame() const = 0;

  virtual VideoFrameMetadata Metadata() const = 0;

  virtual void SetMetadata(const VideoFrameMetadata&) = 0;
};

// Extends the TransformableFrameInterface to expose audio-specific information.
class TransformableAudioFrameInterface : public TransformableFrameInterface {
 public:
  RTC_EXPORT explicit TransformableAudioFrameInterface(Passkey passkey);
  virtual ~TransformableAudioFrameInterface() = default;

  virtual rtc::ArrayView<const uint32_t> GetContributingSources() const = 0;

  virtual const std::optional<uint16_t> SequenceNumber() const = 0;

  // TODO(crbug.com/391114797): Delete this function.
  virtual std::optional<uint64_t> AbsoluteCaptureTimestamp() const = 0;

  enum class FrameType { kEmptyFrame, kAudioFrameSpeech, kAudioFrameCN };

  // TODO(crbug.com/1456628): Change this to pure virtual after it
  // is implemented everywhere.
  virtual FrameType Type() const { return FrameType::kEmptyFrame; }

  // Audio level in -dBov. Values range from 0 to 127, representing 0 to -127
  // dBov. 127 represents digital silence. Only present on remote frames if
  // the audio level header extension was included.
  virtual std::optional<uint8_t> AudioLevel() const = 0;

  // Timestamp at which the packet has been first seen on the network interface.
  // Only defined for received audio packet.
  virtual std::optional<Timestamp> ReceiveTime() const = 0;

  // Timestamp at which the frame was captured in the capturer system.
  // The timestamp is expressed in the capturer system's clock relative to the
  // NTP epoch (January 1st 1970 00:00 UTC)
  // Accessible only if the absolute capture timestamp header extension is
  // enabled.
  virtual std::optional<Timestamp> CaptureTime() const = 0;

  // Offset between the sender system's clock and the capturer system's clock.
  // Can be used to express the capture time in the local system's clock as
  // long as the local system can determine the offset between its local clock
  // and the sender system's clock.
  // Accessible only if the absolute capture timestamp header extension is
  // enabled.
  virtual std::optional<TimeDelta> SenderCaptureTimeOffset() const = 0;
};

// Objects implement this interface to be notified with the transformed frame.
class TransformedFrameCallback : public RefCountInterface {
 public:
  virtual void OnTransformedFrame(
      std::unique_ptr<TransformableFrameInterface> frame) = 0;

  // Request to no longer be called on each frame, instead having frames be
  // sent directly to OnTransformedFrame without additional work.
  // TODO(crbug.com/1502781): Make pure virtual once all mocks have
  // implementations.
  virtual void StartShortCircuiting() {}

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

// Transforms encoded frames. The transformed frame is sent in a callback using
// the TransformedFrameCallback interface (see above).
class FrameTransformerInterface : public RefCountInterface {
 public:
  // Transforms `frame` using the implementing class' processing logic.
  virtual void Transform(
      std::unique_ptr<TransformableFrameInterface> transformable_frame) = 0;

  virtual void RegisterTransformedFrameCallback(
      rtc::scoped_refptr<TransformedFrameCallback>) {}
  virtual void RegisterTransformedFrameSinkCallback(
      rtc::scoped_refptr<TransformedFrameCallback>,
      uint32_t /* ssrc */) {}
  virtual void UnregisterTransformedFrameCallback() {}
  virtual void UnregisterTransformedFrameSinkCallback(uint32_t /* ssrc */) {}

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

// An interface implemented by classes that can host a transform.
// Currently this is implemented by the RTCRtpSender and RTCRtpReceiver.
class FrameTransformerHost {
 public:
  virtual ~FrameTransformerHost() {}
  virtual void SetFrameTransformer(
      rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) = 0;
  // TODO: bugs.webrtc.org/15929 - To be added:
  // virtual AddIncomingMediaType(RtpCodec codec) = 0;
  // virtual AddOutgoingMediaType(RtpCodec codec) = 0;
};

//------------------------------------------------------------------------------
// Implementation details follow
//------------------------------------------------------------------------------
class TransformableFrameInterface::Passkey {
 public:
  ~Passkey() = default;

 private:
  // Explicit list of allowed internal implmentations of
  // TransformableFrameInterface.
  friend class TransformableOutgoingAudioFrame;
  friend class TransformableIncomingAudioFrame;
  friend class TransformableVideoSenderFrame;
  friend class TransformableVideoReceiverFrame;

  friend class MockTransformableFrame;
  friend class MockTransformableAudioFrame;
  friend class MockTransformableVideoFrame;
  Passkey() = default;
};

}  // namespace webrtc

#endif  // API_FRAME_TRANSFORMER_INTERFACE_H_
