/*
 *  Copyright 2017 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 ORTC_RTPTRANSPORTADAPTER_H_
#define ORTC_RTPTRANSPORTADAPTER_H_

#include <memory>
#include <vector>

#include "api/ortc/srtptransportinterface.h"
#include "api/rtcerror.h"
#include "media/base/streamparams.h"
#include "ortc/rtptransportcontrolleradapter.h"
#include "pc/channel.h"
#include "pc/rtptransport.h"
#include "pc/rtptransportinternal.h"
#include "pc/srtptransport.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/sigslot.h"

namespace webrtc {
// This class is a wrapper over an RtpTransport or an SrtpTransport. The base
// class RtpTransportInternalAdapter keeps a raw pointer, |transport_|, of the
// transport object and implements both the public SrtpTransportInterface and
// RtpTransport internal interface by calling the |transport_| underneath.
//
// This adapter can be used as an unencrypted RTP transport or an SrtpTransport
// with RtpSenderAdapter, RtpReceiverAdapter, and RtpTransportControllerAdapter.
//
// TODO(deadbeef): When BaseChannel is split apart into separate
// "RtpTransport"/"RtpTransceiver"/"RtpSender"/"RtpReceiver" objects, this
// adapter object can be removed.
class RtpTransportAdapter : public RtpTransportInternalAdapter {
 public:
  // |rtp| can't be null. |rtcp| can if RTCP muxing is used immediately (meaning
  // |rtcp_parameters.mux| is also true).
  static RTCErrorOr<std::unique_ptr<RtpTransportInterface>> CreateProxied(
      const RtpTransportParameters& rtcp_parameters,
      PacketTransportInterface* rtp,
      PacketTransportInterface* rtcp,
      RtpTransportControllerAdapter* rtp_transport_controller);

  static RTCErrorOr<std::unique_ptr<SrtpTransportInterface>> CreateSrtpProxied(
      const RtpTransportParameters& rtcp_parameters,
      PacketTransportInterface* rtp,
      PacketTransportInterface* rtcp,
      RtpTransportControllerAdapter* rtp_transport_controller);

  ~RtpTransportAdapter() override;

  // RtpTransportInterface implementation.
  PacketTransportInterface* GetRtpPacketTransport() const override {
    return rtp_packet_transport_;
  }
  PacketTransportInterface* GetRtcpPacketTransport() const override {
    return rtcp_packet_transport_;
  }
  RTCError SetParameters(const RtpTransportParameters& parameters) override;
  RtpTransportParameters GetParameters() const override { return parameters_; }

  // SRTP specific implementation.
  RTCError SetSrtpSendKey(const cricket::CryptoParams& params) override;
  RTCError SetSrtpReceiveKey(const cricket::CryptoParams& params) override;

  // Methods used internally by OrtcFactory.
  RtpTransportControllerAdapter* rtp_transport_controller() {
    return rtp_transport_controller_;
  }
  void TakeOwnershipOfRtpTransportController(
      std::unique_ptr<RtpTransportControllerInterface> controller);

  // Used by RtpTransportControllerAdapter to tell when it should stop
  // returning this transport from GetTransports().
  sigslot::signal1<RtpTransportAdapter*> SignalDestroyed;

  bool IsSrtpActive() const override { return transport_->IsSrtpActive(); }

  bool IsSrtpTransport() const { return srtp_transport_ != nullptr; }

 protected:
  RtpTransportAdapter* GetInternal() override { return this; }

 private:
  RtpTransportAdapter(const RtcpParameters& rtcp_params,
                      PacketTransportInterface* rtp,
                      PacketTransportInterface* rtcp,
                      RtpTransportControllerAdapter* rtp_transport_controller,
                      bool is_srtp_transport);

  void OnReadyToSend(bool ready) { SignalReadyToSend(ready); }

  void OnPacketReceived(bool rtcp,
                        rtc::CopyOnWriteBuffer* packet,
                        const rtc::PacketTime& time) {
    SignalPacketReceived(rtcp, packet, time);
  }

  void OnWritableState(bool writable) { SignalWritableState(writable); }

  PacketTransportInterface* rtp_packet_transport_ = nullptr;
  PacketTransportInterface* rtcp_packet_transport_ = nullptr;
  RtpTransportControllerAdapter* const rtp_transport_controller_ = nullptr;
  // Non-null if this class owns the transport controller.
  std::unique_ptr<RtpTransportControllerInterface>
      owned_rtp_transport_controller_;
  RtpTransportParameters parameters_;

  // Only one of them is non-null;
  std::unique_ptr<RtpTransport> unencrypted_rtp_transport_;
  std::unique_ptr<SrtpTransport> srtp_transport_;

  rtc::Thread* network_thread_ = nullptr;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtpTransportAdapter);
};

}  // namespace webrtc

#endif  // ORTC_RTPTRANSPORTADAPTER_H_
