// 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 "media/audio/clockless_audio_sink.h"

#include "base/bind.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/simple_thread.h"
#include "media/base/audio_hash.h"

namespace media {

// Internal to ClocklessAudioSink. Class is used to call Render() on a seperate
// thread, running as fast as it can read the data.
class ClocklessAudioSinkThread : public base::DelegateSimpleThread::Delegate {
 public:
  ClocklessAudioSinkThread(const AudioParameters& params,
                           AudioRendererSink::RenderCallback* callback,
                           bool hashing)
      : callback_(callback),
        audio_bus_(AudioBus::Create(params)),
        stop_event_(new base::WaitableEvent(
            base::WaitableEvent::ResetPolicy::AUTOMATIC,
            base::WaitableEvent::InitialState::NOT_SIGNALED)) {
    if (hashing)
      audio_hash_.reset(new AudioHash());
  }

  void Start() {
    stop_event_->Reset();
    thread_.reset(new base::DelegateSimpleThread(this, "ClocklessAudioSink"));
    thread_->Start();
  }

  // Generate a signal to stop calling Render().
  base::TimeDelta Stop() {
    stop_event_->Signal();
    thread_->Join();
    return playback_time_;
  }

  std::string GetAudioHash() {
    DCHECK(audio_hash_);
    return audio_hash_->ToString();
  }

 private:
   // Call Render() repeatedly, keeping track of the rendering time.
  void Run() override {
     base::TimeTicks start;
     while (!stop_event_->IsSignaled()) {
       const int frames_received = callback_->Render(
           base::TimeDelta(), base::TimeTicks::Now(), 0, audio_bus_.get());
       DCHECK_GE(frames_received, 0);
       if (audio_hash_)
         audio_hash_->Update(audio_bus_.get(), frames_received);
       if (!frames_received) {
         // No data received, so let other threads run to provide data.
         base::PlatformThread::YieldCurrentThread();
       } else if (start.is_null()) {
         // First time we processed some audio, so record the starting time.
         start = base::TimeTicks::Now();
       } else {
         // Keep track of the last time data was rendered.
         playback_time_ = base::TimeTicks::Now() - start;
       }
     }
   }

  AudioRendererSink::RenderCallback* callback_;
  std::unique_ptr<AudioBus> audio_bus_;
  std::unique_ptr<base::WaitableEvent> stop_event_;
  std::unique_ptr<base::DelegateSimpleThread> thread_;
  base::TimeDelta playback_time_;
  std::unique_ptr<AudioHash> audio_hash_;
};

ClocklessAudioSink::ClocklessAudioSink()
    : ClocklessAudioSink(OutputDeviceInfo()) {}

ClocklessAudioSink::ClocklessAudioSink(const OutputDeviceInfo& device_info)
    : device_info_(device_info),
      initialized_(false),
      playing_(false),
      hashing_(false) {}

ClocklessAudioSink::~ClocklessAudioSink() {}

void ClocklessAudioSink::Initialize(const AudioParameters& params,
                                    RenderCallback* callback) {
  DCHECK(!initialized_);
  thread_.reset(new ClocklessAudioSinkThread(params, callback, hashing_));
  initialized_ = true;
}

void ClocklessAudioSink::Start() {
  DCHECK(initialized_);
  DCHECK(!playing_);
}

void ClocklessAudioSink::Stop() {
  if (initialized_)
    Pause();
}

void ClocklessAudioSink::Play() {
  DCHECK(initialized_);

  if (playing_)
    return;

  playing_ = true;
  thread_->Start();
}

void ClocklessAudioSink::Pause() {
  DCHECK(initialized_);

  if (!playing_)
    return;

  playing_ = false;
  playback_time_ = thread_->Stop();
}

bool ClocklessAudioSink::SetVolume(double volume) {
  // Audio is always muted.
  return volume == 0.0;
}

OutputDeviceInfo ClocklessAudioSink::GetOutputDeviceInfo() {
  return device_info_;
}

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

void ClocklessAudioSink::StartAudioHashForTesting() {
  DCHECK(!initialized_);
  hashing_ = true;
}

std::string ClocklessAudioSink::GetAudioHashForTesting() {
  return thread_ && hashing_ ? thread_->GetAudioHash() : std::string();
}

}  // namespace media
