// Copyright 2013 The Chromium Authors
// 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 <memory>

#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/simple_thread.h"
#include "media/base/audio_glitch_info.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_ = std::make_unique<AudioHash>();
  }

  void Start() {
    stop_event_->Reset();
    thread_ = std::make_unique<base::DelegateSimpleThread>(
        this, "ClocklessAudioSink");
    thread_->Start();
  }

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

  const AudioHash& GetAudioHash() const {
    DCHECK(audio_hash_);
    return *audio_hash_;
  }

 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(), {}, 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;
      }
    }
  }

  raw_ptr<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),
      is_optimized_for_hw_params_(true) {}

ClocklessAudioSink::~ClocklessAudioSink() = default;

void ClocklessAudioSink::Initialize(const AudioParameters& params,
                                    RenderCallback* callback) {
  DCHECK(!initialized_);
  thread_ =
      std::make_unique<ClocklessAudioSinkThread>(params, callback, hashing_);
  initialized_ = true;
}

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

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

void ClocklessAudioSink::Flush() {}

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_;
}

void ClocklessAudioSink::GetOutputDeviceInfoAsync(OutputDeviceInfoCB info_cb) {
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(std::move(info_cb), device_info_));
}

bool ClocklessAudioSink::IsOptimizedForHardwareParameters() {
  return is_optimized_for_hw_params_;
}

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

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

const AudioHash& ClocklessAudioSink::GetAudioHashForTesting() const {
  return thread_->GetAudioHash();
}

void ClocklessAudioSink::SetIsOptimizedForHardwareParametersForTesting(
    bool value) {
  is_optimized_for_hw_params_ = value;
}

}  // namespace media
