/*
 *  Copyright 2011 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 PC_PEERCONNECTIONFACTORY_H_
#define PC_PEERCONNECTIONFACTORY_H_

#include <memory>
#include <string>

#include "api/mediastreaminterface.h"
#include "api/peerconnectioninterface.h"
#include "pc/channelmanager.h"
#include "rtc_base/rtccertificategenerator.h"
#include "rtc_base/scoped_ref_ptr.h"
#include "rtc_base/thread.h"

namespace rtc {
class BasicNetworkManager;
class BasicPacketSocketFactory;
}

namespace webrtc {

class RtcEventLog;

class PeerConnectionFactory : public PeerConnectionFactoryInterface {
 public:
  // Use the overloads of CreateVideoSource that take raw VideoCapturer
  // pointers from PeerConnectionFactoryInterface.
  // TODO(deadbeef): Remove this using statement once those overloads are
  // removed.
  using PeerConnectionFactoryInterface::CreateVideoSource;

  void SetOptions(const Options& options) override;

  // Deprecated, use version without constraints.
  rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
      const PeerConnectionInterface::RTCConfiguration& configuration,
      const MediaConstraintsInterface* constraints,
      std::unique_ptr<cricket::PortAllocator> allocator,
      std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
      PeerConnectionObserver* observer) override;

  virtual rtc::scoped_refptr<PeerConnectionInterface> CreatePeerConnection(
      const PeerConnectionInterface::RTCConfiguration& configuration,
      std::unique_ptr<cricket::PortAllocator> allocator,
      std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator,
      PeerConnectionObserver* observer) override;

  bool Initialize();

  rtc::scoped_refptr<MediaStreamInterface>
      CreateLocalMediaStream(const std::string& label) override;

  virtual rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
      const cricket::AudioOptions& options) override;
  // Deprecated, use version without constraints.
  rtc::scoped_refptr<AudioSourceInterface> CreateAudioSource(
      const MediaConstraintsInterface* constraints) override;

  virtual rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
      std::unique_ptr<cricket::VideoCapturer> capturer) override;
  // This version supports filtering on width, height and frame rate.
  // For the "constraints=null" case, use the version without constraints.
  // TODO(hta): Design a version without MediaConstraintsInterface.
  // https://bugs.chromium.org/p/webrtc/issues/detail?id=5617
  rtc::scoped_refptr<VideoTrackSourceInterface> CreateVideoSource(
      std::unique_ptr<cricket::VideoCapturer> capturer,
      const MediaConstraintsInterface* constraints) override;

  rtc::scoped_refptr<VideoTrackInterface> CreateVideoTrack(
      const std::string& id,
      VideoTrackSourceInterface* video_source) override;

  rtc::scoped_refptr<AudioTrackInterface>
      CreateAudioTrack(const std::string& id,
                       AudioSourceInterface* audio_source) override;

  bool StartAecDump(rtc::PlatformFile file, int64_t max_size_bytes) override;
  void StopAecDump() override;
  // TODO(ivoc) Remove after Chrome is updated.
  bool StartRtcEventLog(rtc::PlatformFile file) override { return false; }
  // TODO(ivoc) Remove after Chrome is updated.
  bool StartRtcEventLog(rtc::PlatformFile file,
                        int64_t max_size_bytes) override {
    return false;
  }
  // TODO(ivoc) Remove after Chrome is updated.
  void StopRtcEventLog() override {}

  virtual cricket::TransportController* CreateTransportController(
      cricket::PortAllocator* port_allocator,
      bool redetermine_role_on_ice_restart);
  virtual cricket::ChannelManager* channel_manager();
  virtual rtc::Thread* signaling_thread();
  virtual rtc::Thread* worker_thread();
  virtual rtc::Thread* network_thread();
  const Options& options() const { return options_; }

 protected:
  PeerConnectionFactory(
      rtc::Thread* network_thread,
      rtc::Thread* worker_thread,
      rtc::Thread* signaling_thread,
      AudioDeviceModule* default_adm,
      rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory,
      rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory,
      cricket::WebRtcVideoEncoderFactory* video_encoder_factory,
      cricket::WebRtcVideoDecoderFactory* video_decoder_factory,
      rtc::scoped_refptr<AudioMixer> audio_mixer,
      std::unique_ptr<cricket::MediaEngineInterface> media_engine,
      std::unique_ptr<webrtc::CallFactoryInterface> call_factory,
      std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory);
  virtual ~PeerConnectionFactory();

 private:
  std::unique_ptr<RtcEventLog> CreateRtcEventLog_w();
  std::unique_ptr<Call> CreateCall_w(RtcEventLog* event_log);

  bool wraps_current_thread_;
  rtc::Thread* network_thread_;
  rtc::Thread* worker_thread_;
  rtc::Thread* signaling_thread_;
  std::unique_ptr<rtc::Thread> owned_network_thread_;
  std::unique_ptr<rtc::Thread> owned_worker_thread_;
  Options options_;
  // External Audio device used for audio playback.
  rtc::scoped_refptr<AudioDeviceModule> default_adm_;
  rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
  rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
  std::unique_ptr<cricket::ChannelManager> channel_manager_;
  // External Video encoder factory. This can be NULL if the client has not
  // injected any. In that case, video engine will use the internal SW encoder.
  std::unique_ptr<cricket::WebRtcVideoEncoderFactory> video_encoder_factory_;
  // External Video decoder factory. This can be NULL if the client has not
  // injected any. In that case, video engine will use the internal SW decoder.
  std::unique_ptr<cricket::WebRtcVideoDecoderFactory> video_decoder_factory_;
  std::unique_ptr<rtc::BasicNetworkManager> default_network_manager_;
  std::unique_ptr<rtc::BasicPacketSocketFactory> default_socket_factory_;
  // External audio mixer. This can be NULL. In that case, internal audio mixer
  // will be created and used.
  rtc::scoped_refptr<AudioMixer> external_audio_mixer_;
  std::unique_ptr<cricket::MediaEngineInterface> media_engine_;
  std::unique_ptr<webrtc::CallFactoryInterface> call_factory_;
  std::unique_ptr<RtcEventLogFactoryInterface> event_log_factory_;
};

}  // namespace webrtc

#endif  // PC_PEERCONNECTIONFACTORY_H_
