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

#include "content/browser/speech/speech_synthesis_impl.h"

#include "content/browser/media/audio_stream_monitor.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/browser/speech/tts_utterance_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/web_contents.h"

namespace content {
namespace {

using AudibleCB = base::RepeatingCallback<
    std::unique_ptr<AudioStreamMonitor::AudibleClientRegistration>()>;

// The lifetime of instances of this class is manually bound to the lifetime of
// the associated TtsUtterance.
class EventThunk : public UtteranceEventDelegate {
 public:
  EventThunk(mojo::PendingRemote<blink::mojom::SpeechSynthesisClient> client,
             AudibleCB audible_cb)
      : client_(std::move(client)), audible_cb_(std::move(audible_cb)) {}
  ~EventThunk() override = default;

  // UtteranceEventDelegate methods:
  void OnTtsEvent(TtsUtterance* utterance,
                  TtsEventType event_type,
                  int char_index,
                  int char_length,
                  const std::string& error_message) override {
    // These values are unsigned in the web speech API, so -1 cannot be used as
    // a sentinel value. Use 0 instead to match web standards.
    char_index = std::max(char_index, 0);
    char_length = std::max(char_length, 0);

    switch (event_type) {
      case TTS_EVENT_START:
        audible_client_ = audible_cb_.Run();
        client_->OnStartedSpeaking();
        break;
      case TTS_EVENT_END:
        audible_client_.reset();
        client_->OnFinishedSpeaking(
            blink::mojom::SpeechSynthesisErrorCode::kNoError);
        break;
      case TTS_EVENT_INTERRUPTED:
        audible_client_.reset();
        client_->OnFinishedSpeaking(
            blink::mojom::SpeechSynthesisErrorCode::kInterrupted);
        break;
      case TTS_EVENT_CANCELLED:
        audible_client_.reset();
        client_->OnFinishedSpeaking(
            blink::mojom::SpeechSynthesisErrorCode::kCancelled);
        break;
      case TTS_EVENT_WORD:
        client_->OnEncounteredWordBoundary(char_index, char_length);
        break;
      case TTS_EVENT_SENTENCE:
        client_->OnEncounteredSentenceBoundary(char_index, 0);
        break;
      case TTS_EVENT_MARKER:
        // The web platform API does not support this event.
        break;
      case TTS_EVENT_ERROR:
        audible_client_.reset();
        // The web platform API does not support error text.
        client_->OnEncounteredSpeakingError();
        break;
      case TTS_EVENT_PAUSE:
        audible_client_.reset();
        client_->OnPausedSpeaking();
        break;
      case TTS_EVENT_RESUME:
        audible_client_ = audible_cb_.Run();
        client_->OnResumedSpeaking();
        break;
    }
  }

 private:
  mojo::Remote<blink::mojom::SpeechSynthesisClient> client_;
  AudibleCB audible_cb_;
  std::unique_ptr<AudioStreamMonitor::AudibleClientRegistration>
      audible_client_;
};

void SendVoiceListToObserver(
    blink::mojom::SpeechSynthesisVoiceListObserver* observer,
    const std::vector<VoiceData>& voices) {
  std::vector<blink::mojom::SpeechSynthesisVoicePtr> out_voices;
  out_voices.resize(voices.size());
  for (size_t i = 0; i < voices.size(); ++i) {
    blink::mojom::SpeechSynthesisVoicePtr& out_voice = out_voices[i];
    out_voice = blink::mojom::SpeechSynthesisVoice::New();
    out_voice->voice_uri = voices[i].name;
    out_voice->name = voices[i].name;
    out_voice->lang = voices[i].lang;
    out_voice->is_local_service = !voices[i].remote;
    out_voice->is_default = (i == 0);
  }
  observer->OnSetVoiceList(std::move(out_voices));
}

}  // namespace

SpeechSynthesisImpl::SpeechSynthesisImpl(BrowserContext* browser_context,
                                         RenderFrameHostImpl* rfh)
    : browser_context_(browser_context),
      web_contents_(WebContents::FromRenderFrameHost((rfh))),
      frame_id_(rfh->GetGlobalId()) {
  DCHECK(browser_context_);
  DCHECK(web_contents_);
  TtsController::GetInstance()->AddVoicesChangedDelegate(this);
}

SpeechSynthesisImpl::~SpeechSynthesisImpl() {
  TtsController::GetInstance()->RemoveVoicesChangedDelegate(this);

  // NOTE: Some EventThunk instances may outlive this class, and that's okay.
  // They have their lifetime bound to their associated TtsUtterance instance,
  // and the TtsController manages the lifetime of those.
}

void SpeechSynthesisImpl::AddReceiver(
    mojo::PendingReceiver<blink::mojom::SpeechSynthesis> receiver) {
  receiver_set_.Add(this, std::move(receiver));
}

void SpeechSynthesisImpl::AddVoiceListObserver(
    mojo::PendingRemote<blink::mojom::SpeechSynthesisVoiceListObserver>
        pending_observer) {
  mojo::Remote<blink::mojom::SpeechSynthesisVoiceListObserver> observer(
      std::move(pending_observer));

  std::vector<VoiceData> voices;
  TtsController::GetInstance()->GetVoices(browser_context_, GURL(), &voices);
  SendVoiceListToObserver(observer.get(), voices);

  observer_set_.Add(std::move(observer));
}

void SpeechSynthesisImpl::Speak(
    blink::mojom::SpeechSynthesisUtterancePtr utterance,
    mojo::PendingRemote<blink::mojom::SpeechSynthesisClient> client) {
  if (web_contents_->IsAudioMuted())
    return;

  std::unique_ptr<TtsUtterance> tts_utterance =
      std::make_unique<TtsUtteranceImpl>(browser_context_, web_contents_);
  tts_utterance->SetText(utterance->text);
  tts_utterance->SetLang(utterance->lang);
  tts_utterance->SetVoiceName(utterance->voice);
  tts_utterance->SetShouldClearQueue(false);
  tts_utterance->SetContinuousParameters(utterance->rate, utterance->pitch,
                                         utterance->volume);

  // See comments on EventThunk about how lifetime of this instance is managed.
  tts_utterance->SetEventDelegate(std::make_unique<EventThunk>(
      std::move(client),
      base::BindRepeating(
          &AudioStreamMonitor::RegisterAudibleClient,
          base::Unretained(static_cast<WebContentsImpl*>(web_contents_)
                               ->audio_stream_monitor()),
          frame_id_)));

  TtsController::GetInstance()->SpeakOrEnqueue(std::move(tts_utterance));
}

void SpeechSynthesisImpl::Pause() {
  TtsController::GetInstance()->Pause();
}

void SpeechSynthesisImpl::Resume() {
  TtsController::GetInstance()->Resume();
}

void SpeechSynthesisImpl::Cancel() {
  TtsController::GetInstance()->Stop();
}

void SpeechSynthesisImpl::OnVoicesChanged() {
  std::vector<VoiceData> voices;
  TtsController::GetInstance()->GetVoices(browser_context_, GURL(), &voices);
  for (auto& observer : observer_set_)
    SendVoiceListToObserver(observer.get(), voices);
}

}  // namespace content
