// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cobalt/media/blink/webaudiosourceprovider_impl.h"

#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "cobalt/media/base/bind_to_current_loop.h"
#include "third_party/WebKit/public/platform/WebAudioSourceProviderClient.h"

using blink::WebVector;

namespace cobalt {
namespace media {

namespace {

// Simple helper class for Try() locks.  Lock is Try()'d on construction and
// must be checked via the locked() attribute.  If acquisition was successful
// the lock will be released upon destruction.
// TODO(dalecurtis): This should probably move to base/ if others start using
// this pattern.
class AutoTryLock {
 public:
  explicit AutoTryLock(base::Lock& lock)
      : lock_(lock), acquired_(lock_.Try()) {}

  bool locked() const { return acquired_; }

  ~AutoTryLock() {
    if (acquired_) {
      lock_.AssertAcquired();
      lock_.Release();
    }
  }

 private:
  base::Lock& lock_;
  const bool acquired_;
  DISALLOW_COPY_AND_ASSIGN(AutoTryLock);
};

}  // namespace

// TeeFilter is a RenderCallback implementation that allows for a client to get
// a copy of the data being rendered by the |renderer_| on Render(). This class
// also holds on to the necessary audio parameters.
class WebAudioSourceProviderImpl::TeeFilter
    : public AudioRendererSink::RenderCallback {
 public:
  TeeFilter() : renderer_(NULL), channels_(0), sample_rate_(0) {}
  ~TeeFilter() override {}

  void Initialize(AudioRendererSink::RenderCallback* renderer, int channels,
                  int sample_rate) {
    DCHECK(renderer);
    renderer_ = renderer;
    channels_ = channels;
    sample_rate_ = sample_rate;
  }

  // AudioRendererSink::RenderCallback implementation.
  // These are forwarders to |renderer_| and are here to allow for a client to
  // get a copy of the rendered audio by SetCopyAudioCallback().
  int Render(AudioBus* audio_bus, uint32_t frames_delayed,
             uint32_t frames_skipped) OVERRIDE;
  void OnRenderError() OVERRIDE;

  bool IsInitialized() const { return !!renderer_; }
  int channels() const { return channels_; }
  int sample_rate() const { return sample_rate_; }
  void set_copy_audio_bus_callback(const CopyAudioCB& callback) {
    copy_audio_bus_callback_ = callback;
  }

 private:
  AudioRendererSink::RenderCallback* renderer_;
  int channels_;
  int sample_rate_;

  CopyAudioCB copy_audio_bus_callback_;

  DISALLOW_COPY_AND_ASSIGN(TeeFilter);
};

WebAudioSourceProviderImpl::WebAudioSourceProviderImpl(
    const scoped_refptr<SwitchableAudioRendererSink>& sink)
    : volume_(1.0),
      state_(kStopped),
      client_(NULL),
      sink_(sink),
      tee_filter_(new TeeFilter()),
      weak_factory_(this) {}

WebAudioSourceProviderImpl::~WebAudioSourceProviderImpl() {}

void WebAudioSourceProviderImpl::setClient(
    blink::WebAudioSourceProviderClient* client) {
  base::AutoLock auto_lock(sink_lock_);
  if (client && client != client_) {
    // Detach the audio renderer from normal playback.
    sink_->Stop();

    // The client will now take control by calling provideInput() periodically.
    client_ = client;

    set_format_cb_ = BindToCurrentLoop(base::Bind(
        &WebAudioSourceProviderImpl::OnSetFormat, weak_factory_.GetWeakPtr()));

    // If |tee_filter_| is Initialize()d - then run |set_format_cb_| to send
    // |client_| the current format info. Otherwise |set_format_cb_| will get
    // called when Initialize() is called. Note: Always using |set_format_cb_|
    // ensures we have the same locking order when calling into |client_|.
    if (tee_filter_->IsInitialized())
      base::ResetAndReturn(&set_format_cb_).Run();
  } else if (!client && client_) {
    // Restore normal playback.
    client_ = NULL;
    sink_->SetVolume(volume_);
    if (state_ >= kStarted) sink_->Start();
    if (state_ >= kPlaying) sink_->Play();
  }
}

void WebAudioSourceProviderImpl::provideInput(
    const WebVector<float*>& audio_data, size_t number_of_frames) {
  if (!bus_wrapper_ ||
      static_cast<size_t>(bus_wrapper_->channels()) != audio_data.size()) {
    bus_wrapper_ = AudioBus::CreateWrapper(static_cast<int>(audio_data.size()));
  }

  const int incoming_number_of_frames = static_cast<int>(number_of_frames);
  bus_wrapper_->set_frames(incoming_number_of_frames);
  for (size_t i = 0; i < audio_data.size(); ++i)
    bus_wrapper_->SetChannelData(static_cast<int>(i), audio_data[i]);

  // Use a try lock to avoid contention in the real-time audio thread.
  AutoTryLock auto_try_lock(sink_lock_);
  if (!auto_try_lock.locked() || state_ != kPlaying) {
    // Provide silence if we failed to acquire the lock or the source is not
    // running.
    bus_wrapper_->Zero();
    return;
  }

  DCHECK(client_);
  DCHECK_EQ(tee_filter_->channels(), bus_wrapper_->channels());
  const int frames = tee_filter_->Render(bus_wrapper_.get(), 0, 0);
  if (frames < incoming_number_of_frames)
    bus_wrapper_->ZeroFramesPartial(frames, incoming_number_of_frames - frames);

  bus_wrapper_->Scale(volume_);
}

void WebAudioSourceProviderImpl::Initialize(const AudioParameters& params,
                                            RenderCallback* renderer) {
  base::AutoLock auto_lock(sink_lock_);
  DCHECK_EQ(state_, kStopped);

  tee_filter_->Initialize(renderer, params.channels(), params.sample_rate());

  sink_->Initialize(params, tee_filter_.get());

  if (!set_format_cb_.is_null()) base::ResetAndReturn(&set_format_cb_).Run();
}

void WebAudioSourceProviderImpl::Start() {
  base::AutoLock auto_lock(sink_lock_);
  DCHECK(tee_filter_);
  DCHECK_EQ(state_, kStopped);
  state_ = kStarted;
  if (!client_) sink_->Start();
}

void WebAudioSourceProviderImpl::Stop() {
  base::AutoLock auto_lock(sink_lock_);
  state_ = kStopped;
  if (!client_) sink_->Stop();
}

void WebAudioSourceProviderImpl::Play() {
  base::AutoLock auto_lock(sink_lock_);
  DCHECK_EQ(state_, kStarted);
  state_ = kPlaying;
  if (!client_) sink_->Play();
}

void WebAudioSourceProviderImpl::Pause() {
  base::AutoLock auto_lock(sink_lock_);
  DCHECK(state_ == kPlaying || state_ == kStarted);
  state_ = kStarted;
  if (!client_) sink_->Pause();
}

bool WebAudioSourceProviderImpl::SetVolume(double volume) {
  base::AutoLock auto_lock(sink_lock_);
  volume_ = volume;
  if (!client_) sink_->SetVolume(volume);
  return true;
}

media::OutputDeviceInfo WebAudioSourceProviderImpl::GetOutputDeviceInfo() {
  base::AutoLock auto_lock(sink_lock_);
  return sink_->GetOutputDeviceInfo();
}

bool WebAudioSourceProviderImpl::CurrentThreadIsRenderingThread() {
  NOTIMPLEMENTED();
  return false;
}

void WebAudioSourceProviderImpl::SwitchOutputDevice(
    const std::string& device_id, const url::Origin& security_origin,
    const OutputDeviceStatusCB& callback) {
  base::AutoLock auto_lock(sink_lock_);
  if (client_)
    callback.Run(media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
  else
    sink_->SwitchOutputDevice(device_id, security_origin, callback);
}

void WebAudioSourceProviderImpl::SetCopyAudioCallback(
    const CopyAudioCB& callback) {
  DCHECK(!callback.is_null());

  // Use |sink_lock_| to protect |tee_filter_| too since they go in lockstep.
  base::AutoLock auto_lock(sink_lock_);

  DCHECK(tee_filter_);
  tee_filter_->set_copy_audio_bus_callback(callback);
}

void WebAudioSourceProviderImpl::ClearCopyAudioCallback() {
  DCHECK(tee_filter_);
  tee_filter_->set_copy_audio_bus_callback(CopyAudioCB());
}

int WebAudioSourceProviderImpl::RenderForTesting(AudioBus* audio_bus) {
  return tee_filter_->Render(audio_bus, 0, 0);
}

void WebAudioSourceProviderImpl::OnSetFormat() {
  base::AutoLock auto_lock(sink_lock_);
  if (!client_) return;

  // Inform Blink about the audio stream format.
  client_->setFormat(tee_filter_->channels(), tee_filter_->sample_rate());
}

int WebAudioSourceProviderImpl::TeeFilter::Render(AudioBus* audio_bus,
                                                  uint32_t frames_delayed,
                                                  uint32_t frames_skipped) {
  DCHECK(IsInitialized());

  const int num_rendered_frames =
      renderer_->Render(audio_bus, frames_delayed, frames_skipped);

  if (!copy_audio_bus_callback_.is_null()) {
    std::unique_ptr<AudioBus> bus_copy =
        AudioBus::Create(audio_bus->channels(), audio_bus->frames());
    audio_bus->CopyTo(bus_copy.get());
    copy_audio_bus_callback_.Run(std::move(bus_copy), frames_delayed,
                                 sample_rate_);
  }

  return num_rendered_frames;
}

void WebAudioSourceProviderImpl::TeeFilter::OnRenderError() {
  DCHECK(IsInitialized());
  renderer_->OnRenderError();
}

}  // namespace media
}  // namespace cobalt
