/*
 *  Copyright 2014 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 WEBRTC_API_PEERCONNECTIONFACTORYPROXY_H_
#define WEBRTC_API_PEERCONNECTIONFACTORYPROXY_H_

#include <memory>
#include <string>
#include <utility>

#include "webrtc/api/peerconnectioninterface.h"
#include "webrtc/api/proxy.h"
#include "webrtc/base/bind.h"

namespace webrtc {

BEGIN_SIGNALING_PROXY_MAP(PeerConnectionFactory)
  PROXY_METHOD1(void, SetOptions, const Options&)
  // Can't use PROXY_METHOD5 because unique_ptr must be moved.
  // TODO(tommi,hbos): Use of templates to support unique_ptr?
  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
      const PeerConnectionInterface::RTCConfiguration& a1,
      const MediaConstraintsInterface* a2,
      std::unique_ptr<cricket::PortAllocator> a3,
      std::unique_ptr<DtlsIdentityStoreInterface> a4,
      PeerConnectionObserver* a5) override {
    return signaling_thread_
        ->Invoke<rtc::scoped_refptr<PeerConnectionInterface>>(
            rtc::Bind(&PeerConnectionFactoryProxy::CreatePeerConnection_ot,
                      this, a1, a2, a3.release(), a4.release(), a5));
  }
  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
      const PeerConnectionInterface::RTCConfiguration& a1,
      std::unique_ptr<cricket::PortAllocator> a3,
      std::unique_ptr<DtlsIdentityStoreInterface> a4,
      PeerConnectionObserver* a5) override {
    return signaling_thread_
        ->Invoke<rtc::scoped_refptr<PeerConnectionInterface>>(
            rtc::Bind(&PeerConnectionFactoryProxy::CreatePeerConnection_ot,
                      this, a1, a3.release(), a4.release(), a5));
  }
  PROXY_METHOD1(rtc::scoped_refptr<MediaStreamInterface>,
                CreateLocalMediaStream, const std::string&)
  PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>,
                CreateAudioSource, const MediaConstraintsInterface*)
  PROXY_METHOD1(rtc::scoped_refptr<AudioSourceInterface>,
                CreateAudioSource,
                const cricket::AudioOptions&)
  PROXY_METHOD2(rtc::scoped_refptr<VideoTrackSourceInterface>,
                CreateVideoSource,
                cricket::VideoCapturer*,
                const MediaConstraintsInterface*)
  PROXY_METHOD1(rtc::scoped_refptr<VideoTrackSourceInterface>,
                CreateVideoSource,
                cricket::VideoCapturer*)
  PROXY_METHOD2(rtc::scoped_refptr<VideoTrackInterface>,
                CreateVideoTrack,
                const std::string&,
                VideoTrackSourceInterface*)
  PROXY_METHOD2(rtc::scoped_refptr<AudioTrackInterface>,
                CreateAudioTrack, const std::string&,  AudioSourceInterface*)
  PROXY_METHOD2(bool, StartAecDump, rtc::PlatformFile, int64_t)
  PROXY_METHOD0(void, StopAecDump)
  PROXY_METHOD1(bool, StartRtcEventLog, rtc::PlatformFile)
  PROXY_METHOD2(bool, StartRtcEventLog, rtc::PlatformFile, int64_t)
  PROXY_METHOD0(void, StopRtcEventLog)

 private:
  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection_ot(
      const PeerConnectionInterface::RTCConfiguration& a1,
      const MediaConstraintsInterface* a2,
      cricket::PortAllocator* a3,
      DtlsIdentityStoreInterface* a4,
      PeerConnectionObserver* a5) {
    std::unique_ptr<cricket::PortAllocator> ptr_a3(a3);
    std::unique_ptr<DtlsIdentityStoreInterface> ptr_a4(a4);
    return c_->CreatePeerConnection(a1, a2, std::move(ptr_a3),
                                    std::move(ptr_a4), a5);
  }

  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection_ot(
      const PeerConnectionInterface::RTCConfiguration& a1,
      cricket::PortAllocator* a3,
      DtlsIdentityStoreInterface* a4,
      PeerConnectionObserver* a5) {
    std::unique_ptr<cricket::PortAllocator> ptr_a3(a3);
    std::unique_ptr<DtlsIdentityStoreInterface> ptr_a4(a4);
    return c_->CreatePeerConnection(a1, std::move(ptr_a3), std::move(ptr_a4),
                                    a5);
  }
  END_SIGNALING_PROXY()

}  // namespace webrtc

#endif  // WEBRTC_API_PEERCONNECTIONFACTORYPROXY_H_
