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

#include "components/live_caption/live_caption_controller.h"

#include <memory>

#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/functional/callback_forward.h"
#include "base/metrics/histogram_functions.h"
#include "build/build_config.h"
#include "components/live_caption/caption_bubble_context.h"
#include "components/live_caption/caption_bubble_controller.h"
#include "components/live_caption/caption_util.h"
#include "components/live_caption/pref_names.h"
#include "components/live_caption/views/caption_bubble.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/soda/constants.h"
#include "components/soda/soda_installer.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "media/base/media_switches.h"
#include "ui/native_theme/native_theme.h"

namespace {

const char* const kCaptionStylePrefsToObserve[] = {
    prefs::kAccessibilityCaptionsTextSize,
    prefs::kAccessibilityCaptionsTextFont,
    prefs::kAccessibilityCaptionsTextColor,
    prefs::kAccessibilityCaptionsTextOpacity,
    prefs::kAccessibilityCaptionsBackgroundColor,
    prefs::kAccessibilityCaptionsTextShadow,
    prefs::kAccessibilityCaptionsBackgroundOpacity};

}  // namespace

namespace captions {

LiveCaptionController::LiveCaptionController(
    PrefService* profile_prefs,
    PrefService* global_prefs,
    const std::string& application_locale,
    content::BrowserContext* browser_context,
    base::RepeatingCallback<void()> create_ui_callback_for_testing)
    : profile_prefs_(profile_prefs),
      global_prefs_(global_prefs),
      browser_context_(browser_context),
      application_locale_(application_locale) {
  if (create_ui_callback_for_testing) {
    create_ui_callback_for_testing_ = std::move(create_ui_callback_for_testing);
  }

  base::UmaHistogramBoolean("Accessibility.LiveCaption.FeatureEnabled2",
                            IsLiveCaptionFeatureSupported());

  // Hidden behind a feature flag.
  if (!IsLiveCaptionFeatureSupported()) {
    return;
  }

  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  pref_change_registrar_->Init(profile_prefs_);
  auto* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line &&
      command_line->HasSwitch(switches::kEnableLiveCaptionPrefForTesting)) {
    profile_prefs_->SetBoolean(prefs::kLiveCaptionEnabled, true);
  }

  pref_change_registrar_->Add(
      prefs::kLiveCaptionEnabled,
      base::BindRepeating(&LiveCaptionController::OnLiveCaptionEnabledChanged,
                          base::Unretained(this)));
  pref_change_registrar_->Add(
      prefs::kLiveCaptionLanguageCode,
      base::BindRepeating(&LiveCaptionController::OnLiveCaptionLanguageChanged,
                          base::Unretained(this)));

  enabled_ = IsLiveCaptionEnabled();
  base::UmaHistogramBoolean("Accessibility.LiveCaption2", enabled_);
  MaybeSetLiveCaptionLanguage();

  if (enabled_) {
    StartLiveCaption();
  }
}

LiveCaptionController::~LiveCaptionController() {
  if (enabled_) {
    enabled_ = false;
    StopLiveCaption();
  }
}

// static
void LiveCaptionController::RegisterProfilePrefs(
    user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(
      prefs::kLiveCaptionBubbleExpanded, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      prefs::kLiveCaptionEnabled, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
  registry->RegisterBooleanPref(
      prefs::kLiveCaptionMaskOffensiveWords, false,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  // Initially default the language to en-US. The language
  // preference value will be set to a default language when Live Caption is
  // enabled for the first time.
  registry->RegisterStringPref(prefs::kLiveCaptionLanguageCode,
                               speech::kUsEnglishLocale,
                               user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

  registry->RegisterListPref(
      prefs::kLiveCaptionMediaFoundationRendererErrorSilenced,
      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);

#if BUILDFLAG(IS_CHROMEOS)
  // Flags for User Microphone Captioning are only available on ash.
  registry->RegisterBooleanPref(prefs::kLiveCaptionUserMicrophoneEnabled,
                                false);
  registry->RegisterStringPref(prefs::kUserMicrophoneCaptionLanguageCode,
                               speech::kUsEnglishLocale);
#endif
}

void LiveCaptionController::OnLiveCaptionEnabledChanged() {
  bool enabled = IsLiveCaptionEnabled();
  if (enabled == enabled_) {
    return;
  }
  enabled_ = enabled;

  if (enabled) {
    StartLiveCaption();
  } else {
    StopLiveCaption();
    speech::SodaInstaller::GetInstance()->SetUninstallTimer(profile_prefs_,
                                                            global_prefs_);
  }
}

void LiveCaptionController::OnLiveCaptionLanguageChanged() {
  if (enabled_) {
    const auto language_code = GetLanguageCode();
    auto* soda_installer = speech::SodaInstaller::GetInstance();
    // Only trigger an install when the language is not already installed.
    if (!soda_installer->IsSodaInstalled(
            speech::GetLanguageCode(language_code))) {
      soda_installer->InstallLanguage(language_code, global_prefs_);
    }
  }
}

bool LiveCaptionController::IsLiveCaptionEnabled() {
#if BUILDFLAG(IS_CHROMEOS)
  return enabled_for_babel_orca_ ||
         profile_prefs_->GetBoolean(prefs::kLiveCaptionEnabled);
#else
  return profile_prefs_->GetBoolean(prefs::kLiveCaptionEnabled);
#endif
}

void LiveCaptionController::StartLiveCaption() {
  DCHECK(enabled_);
  // The SodaInstaller determines whether SODA is already on the device and
  // whether or not to download. Once SODA is on the device and ready, the
  // SODAInstaller calls OnSodaInstalled on its observers. The UI is created at
  // that time.
  if (speech::SodaInstaller::GetInstance()->IsSodaInstalled(
          speech::GetLanguageCode(GetLanguageCode()))) {
    CreateUI();
  } else {
    speech::SodaInstaller::GetInstance()->AddObserver(this);
    speech::SodaInstaller::GetInstance()->Init(profile_prefs_, global_prefs_);
  }
}

void LiveCaptionController::StopLiveCaption() {
  DCHECK(!enabled_);
  speech::SodaInstaller::GetInstance()->RemoveObserver(this);
  DestroyUI();
}

void LiveCaptionController::OnSodaInstalled(
    speech::LanguageCode language_code) {
  // Live Caption should always be enabled when this is called. If Live Caption
  // has been disabled, then this should not be observing the SodaInstaller
  // anymore.
  DCHECK(enabled_);
  bool is_language_code_for_live_caption =
      prefs::IsLanguageCodeForLiveCaption(language_code, profile_prefs_);

#if BUILDFLAG(IS_CHROMEOS)
  bool is_language_code_for_babel_orca =
      prefs::IsLanguageCodeForMicrophoneCaption(language_code, profile_prefs_);

  if ((enabled_for_babel_orca_ && is_language_code_for_babel_orca) ||
      is_language_code_for_live_caption) {
    speech::SodaInstaller::GetInstance()->RemoveObserver(this);
    CreateUI();
  }
#else
  if (is_language_code_for_live_caption) {
    speech::SodaInstaller::GetInstance()->RemoveObserver(this);
    CreateUI();
  }
#endif
}

void LiveCaptionController::OnSodaInstallError(
    speech::LanguageCode language_code,
    speech::SodaInstaller::ErrorCode error_code) {
  // Check that language code matches the selected language for Live Caption or
  // is LanguageCode::kNone (signifying the SODA binary failed).
  if (!prefs::IsLanguageCodeForLiveCaption(language_code, profile_prefs_) &&
      language_code != speech::LanguageCode::kNone) {
    return;
  }
  if (!base::FeatureList::IsEnabled(media::kLiveCaptionMultiLanguage)) {
    profile_prefs_->SetBoolean(prefs::kLiveCaptionEnabled, false);
  }
}

void LiveCaptionController::CreateUI() {
  if (is_ui_constructed_) {
    return;
  }

  is_ui_constructed_ = true;

  // In the unit test we don't need to verify the caption bubble displays
  // properly, that's covered by the browser test and we don't want To
  // initialize all of the dependencies necessary.  Instead we will
  // let the test know that we were called after checking that
  // the ui wasn't already constructed and use that event to assert
  // the correct behavior.
  if (create_ui_callback_for_testing_) {
    create_ui_callback_for_testing_.Run();
    return;
  }

  caption_bubble_controller_ =
      CaptionBubbleController::Create(profile_prefs_, application_locale_);
  caption_bubble_controller_->UpdateCaptionStyle(caption_style_);

  // Observe native theme changes for caption style updates.
  ui::NativeTheme::GetInstanceForWeb()->AddObserver(this);

  // Observe caption style prefs.
  for (const char* const pref_name : kCaptionStylePrefsToObserve) {
    DCHECK(!pref_change_registrar_->IsObserved(pref_name));
    pref_change_registrar_->Add(
        pref_name,
        base::BindRepeating(&LiveCaptionController::OnCaptionStyleUpdated,
                            base::Unretained(this)));
  }
  OnCaptionStyleUpdated();
}

void LiveCaptionController::DestroyUI() {
  if (!is_ui_constructed_) {
    return;
  }
  is_ui_constructed_ = false;

  // See comment in CreateUI above, we don't want to destroy
  // a UI we never created in tests.
  if (create_ui_callback_for_testing_) {
    return;
  }

  caption_bubble_controller_.reset(nullptr);

  // Remove native theme observer.
  ui::NativeTheme::GetInstanceForWeb()->RemoveObserver(this);

  // Remove prefs to observe.
  for (const char* const pref_name : kCaptionStylePrefsToObserve) {
    DCHECK(pref_change_registrar_->IsObserved(pref_name));
    pref_change_registrar_->Remove(pref_name);
  }
}

const std::string LiveCaptionController::GetLanguageCode() const {
#if BUILDFLAG(IS_CHROMEOS)
  if (enabled_for_babel_orca_) {
    return prefs::GetUserMicrophoneCaptionLanguage(profile_prefs_);
  }
#endif

  return prefs::GetLiveCaptionLanguageCode(profile_prefs_);
}

bool LiveCaptionController::DispatchTranscription(
    CaptionBubbleContext* caption_bubble_context,
    const media::SpeechRecognitionResult& result) {
  if (!caption_bubble_controller_) {
    return false;
  }
  return caption_bubble_controller_->OnTranscription(caption_bubble_context,
                                                     result);
}

void LiveCaptionController::OnError(
    CaptionBubbleContext* caption_bubble_context,
    CaptionBubbleErrorType error_type,
    OnErrorClickedCallback error_clicked_callback,
    OnDoNotShowAgainClickedCallback error_silenced_callback) {
  if (!caption_bubble_controller_) {
    CreateUI();
  }
  caption_bubble_controller_->OnError(caption_bubble_context, error_type,
                                      std::move(error_clicked_callback),
                                      std::move(error_silenced_callback));
}

void LiveCaptionController::OnAudioStreamEnd(
    CaptionBubbleContext* caption_bubble_context) {
  if (!caption_bubble_controller_) {
    return;
  }
  caption_bubble_controller_->OnAudioStreamEnd(caption_bubble_context);
}

void LiveCaptionController::OnLanguageIdentificationEvent(
    CaptionBubbleContext* caption_bubble_context,
    const media::mojom::LanguageIdentificationEventPtr& event) {
  // TODO(crbug.com/40167928): Implement the UI for language identification.
  if (caption_bubble_controller_) {
    return caption_bubble_controller_->OnLanguageIdentificationEvent(
        caption_bubble_context, event);
  }
}

#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
void LiveCaptionController::OnToggleFullscreen(
    CaptionBubbleContext* caption_bubble_context) {
  if (!enabled_) {
    return;
  }
  // The easiest way to move the Live Caption UI to the right workspace is to
  // simply destroy and recreate the UI. The UI will automatically be created
  // in the workspace of the browser window that is transmitting captions.
  DestroyUI();
  CreateUI();
}
#endif

#if BUILDFLAG(IS_CHROMEOS)
void LiveCaptionController::ToggleLiveCaptionForBabelOrca(bool enabled) {
  enabled_for_babel_orca_ = enabled;
  OnLiveCaptionEnabledChanged();
}
#endif

void LiveCaptionController::OnCaptionStyleUpdated() {
  // Metrics are recorded when passing the caption prefs to the browser, so do
  // not duplicate them here.
  caption_style_ = GetCaptionStyleFromUserSettings(profile_prefs_,
                                                   false /* record_metrics */);
  caption_bubble_controller_->UpdateCaptionStyle(caption_style_);
}

void LiveCaptionController::MaybeSetLiveCaptionLanguage() {
  // If the current Live Caption language is not installed,
  // reset the Live Caption language code to the application locale or preferred
  // language if available.
  if (speech::SodaInstaller::GetInstance() &&
      profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode) ==
          speech::kUsEnglishLocale &&
      speech::SodaInstaller::GetInstance()
          ->GetLanguagePath(
              profile_prefs_->GetString(prefs::kLiveCaptionLanguageCode))
          .empty()) {
    speech::SodaInstaller::GetInstance()->UnregisterLanguage(
        speech::kUsEnglishLocale, global_prefs_);
    speech::SodaInstaller::GetInstance()->RegisterLanguage(
        speech::GetDefaultLiveCaptionLanguage(application_locale_,
                                              profile_prefs_),
        global_prefs_);
    profile_prefs_->SetString(prefs::kLiveCaptionLanguageCode,
                              speech::GetDefaultLiveCaptionLanguage(
                                  application_locale_, profile_prefs_));
  }
}

}  // namespace captions
