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

#include "chrome/browser/speech/tts_controller_delegate_impl.h"

#include <stddef.h>

#include <string>
#include <utility>

#include "base/json/json_reader.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/tts_controller.h"
#include "third_party/blink/public/mojom/speech/speech_synthesis.mojom.h"
#include "ui/base/l10n/l10n_util.h"

namespace {

std::optional<content::TtsControllerDelegate::PreferredVoiceId>
PreferredVoiceIdFromString(const base::Value::Dict& pref,
                           std::string_view pref_key) {
  const std::string* voice_id =
      pref.FindStringByDottedPath(l10n_util::GetLanguage(pref_key));
  if (!voice_id || voice_id->empty())
    return std::nullopt;

  std::optional<base::Value> json =
      base::JSONReader::Read(*voice_id, base::JSON_PARSE_CHROMIUM_EXTENSIONS);
  std::string name;
  std::string id;
  if (json && json->is_dict()) {
    const base::Value::Dict& dict = json->GetDict();
    const std::string* name_str = dict.FindString("name");
    if (name_str)
      name = *name_str;
    const std::string* id_str = dict.FindString("extension");
    if (id_str)
      id = *id_str;
  }

  return std::optional<content::TtsControllerDelegate::PreferredVoiceId>(
      {std::move(name), std::move(id)});
}

}  // namespace

//
// TtsControllerDelegateImpl
//

// static
TtsControllerDelegateImpl* TtsControllerDelegateImpl::GetInstance() {
  return base::Singleton<TtsControllerDelegateImpl>::get();
}

TtsControllerDelegateImpl::TtsControllerDelegateImpl() = default;

TtsControllerDelegateImpl::~TtsControllerDelegateImpl() = default;

std::unique_ptr<content::TtsControllerDelegate::PreferredVoiceIds>
TtsControllerDelegateImpl::GetPreferredVoiceIdsForUtterance(
    content::TtsUtterance* utterance) {
  const base::Value::Dict* lang_to_voice_pref = GetLangToVoicePref(utterance);
  if (!lang_to_voice_pref)
    return nullptr;

  std::unique_ptr<PreferredVoiceIds> preferred_ids =
      std::make_unique<PreferredVoiceIds>();

  if (!utterance->GetLang().empty()) {
    preferred_ids->lang_voice_id = PreferredVoiceIdFromString(
        *lang_to_voice_pref, l10n_util::GetLanguage(utterance->GetLang()));
  }

  const std::string app_lang = g_browser_process->GetApplicationLocale();
  preferred_ids->locale_voice_id = PreferredVoiceIdFromString(
      *lang_to_voice_pref, l10n_util::GetLanguage(app_lang));

  preferred_ids->any_locale_voice_id =
      PreferredVoiceIdFromString(*lang_to_voice_pref, "noLanguageCode");
  return preferred_ids;
}

void TtsControllerDelegateImpl::UpdateUtteranceDefaultsFromPrefs(
    content::TtsUtterance* utterance,
    double* rate,
    double* pitch,
    double* volume) {
  // Update pitch, rate and volume from user prefs if not set explicitly
  // on this utterance.
  const PrefService* prefs = GetPrefService(utterance);
  if (*rate == blink::mojom::kSpeechSynthesisDoublePrefNotSet) {
    *rate = prefs ? prefs->GetDouble(prefs::kTextToSpeechRate)
                  : blink::mojom::kSpeechSynthesisDefaultRate;
  }
  if (*pitch == blink::mojom::kSpeechSynthesisDoublePrefNotSet) {
    *pitch = prefs ? prefs->GetDouble(prefs::kTextToSpeechPitch)
                   : blink::mojom::kSpeechSynthesisDefaultPitch;
  }
  if (*volume == blink::mojom::kSpeechSynthesisDoublePrefNotSet) {
    *volume = prefs ? prefs->GetDouble(prefs::kTextToSpeechVolume)
                    : blink::mojom::kSpeechSynthesisDefaultVolume;
  }
}

const PrefService* TtsControllerDelegateImpl::GetPrefService(
    content::TtsUtterance* utterance) {
  // The utterance->GetBrowserContext() is null in tests.
  if (!utterance->GetBrowserContext())
    return nullptr;

  const Profile* profile =
      Profile::FromBrowserContext(utterance->GetBrowserContext());
  return profile ? profile->GetPrefs() : nullptr;
}

const base::Value::Dict* TtsControllerDelegateImpl::GetLangToVoicePref(
    content::TtsUtterance* utterance) {
  const PrefService* prefs = GetPrefService(utterance);
  return prefs == nullptr
             ? nullptr
             : &prefs->GetDict(prefs::kTextToSpeechLangToVoiceName);
}
