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

#include "webrtc/api/mediacontroller.h"

#include "webrtc/base/bind.h"
#include "webrtc/base/checks.h"
#include "webrtc/call.h"
#include "webrtc/pc/channelmanager.h"
#include "webrtc/media/base/mediachannel.h"

namespace {

const int kMinBandwidthBps = 30000;
const int kStartBandwidthBps = 300000;
const int kMaxBandwidthBps = 2000000;

class MediaController : public webrtc::MediaControllerInterface,
                        public sigslot::has_slots<> {
 public:
  MediaController(const cricket::MediaConfig& media_config,
                  rtc::Thread* worker_thread,
                  cricket::ChannelManager* channel_manager)
      : worker_thread_(worker_thread),
        media_config_(media_config),
        channel_manager_(channel_manager) {
    RTC_DCHECK(worker_thread);
    worker_thread_->Invoke<void>(
        rtc::Bind(&MediaController::Construct_w, this,
                  channel_manager_->media_engine()));
  }
  ~MediaController() override {
    Close();
  }

  // webrtc::MediaControllerInterface implementation.
  void Close() override {
    worker_thread_->Invoke<void>(rtc::Bind(&MediaController::Close_w, this));
  }
  webrtc::Call* call_w() override {
    RTC_DCHECK(worker_thread_->IsCurrent());
    if (!call_) {
      call_.reset(webrtc::Call::Create(call_config_));
    }
    return call_.get();
  }
  cricket::ChannelManager* channel_manager() const override {
    return channel_manager_;
  }
  const cricket::MediaConfig& config() const override { return media_config_; }

 private:
  void Construct_w(cricket::MediaEngineInterface* media_engine) {
    RTC_DCHECK(worker_thread_->IsCurrent());
    RTC_DCHECK(media_engine);
    call_config_.audio_state = media_engine->GetAudioState();
    call_config_.bitrate_config.min_bitrate_bps = kMinBandwidthBps;
    call_config_.bitrate_config.start_bitrate_bps = kStartBandwidthBps;
    call_config_.bitrate_config.max_bitrate_bps = kMaxBandwidthBps;
  }
  void Close_w() {
    RTC_DCHECK(worker_thread_->IsCurrent());
    call_.reset();
  }

  rtc::Thread* const worker_thread_;
  const cricket::MediaConfig media_config_;
  cricket::ChannelManager* const channel_manager_;
  webrtc::Call::Config call_config_;
  rtc::scoped_ptr<webrtc::Call> call_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MediaController);
};
}  // namespace {

namespace webrtc {

MediaControllerInterface* MediaControllerInterface::Create(
    const cricket::MediaConfig& config,
    rtc::Thread* worker_thread,
    cricket::ChannelManager* channel_manager) {
  return new MediaController(config, worker_thread, channel_manager);
}
}  // namespace webrtc
