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

#include "ash/webui/personalization_app/personalization_app_ui.h"

#include <string>

#include "ash/constants/ash_features.h"
#include "ash/public/cpp/ambient/ambient_backend_controller.h"
#include "ash/public/cpp/ambient/ambient_client.h"
#include "ash/public/cpp/wallpaper/wallpaper_controller.h"
#include "ash/rgb_keyboard/rgb_keyboard_manager.h"
#include "ash/shell.h"
#include "ash/webui/grit/ash_personalization_app_resources.h"
#include "ash/webui/grit/ash_personalization_app_resources_map.h"
#include "ash/webui/personalization_app/personalization_app_ambient_provider.h"
#include "ash/webui/personalization_app/personalization_app_keyboard_backlight_provider.h"
#include "ash/webui/personalization_app/personalization_app_theme_provider.h"
#include "ash/webui/personalization_app/personalization_app_url_constants.h"
#include "ash/webui/personalization_app/personalization_app_user_provider.h"
#include "ash/webui/personalization_app/personalization_app_wallpaper_provider.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chromeos/constants/chromeos_features.h"
#include "chromeos/strings/grit/chromeos_strings.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/url_constants.h"
#include "services/network/public/mojom/content_security_policy.mojom-shared.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/resources/grit/webui_resources.h"
#include "ui/webui/color_change_listener/color_change_handler.h"
#include "ui/webui/mojo_web_ui_controller.h"

namespace ash::personalization_app {

namespace {

std::u16string GetGooglePhotosURL() {
  return u"https://photos.google.com";
}

bool IsAmbientModeAllowed() {
  return ash::AmbientClient::Get() &&
         ash::AmbientClient::Get()->IsAmbientModeAllowed();
}

AmbientBackendController* GetAmbientBackendController() {
  AmbientBackendController* ambient_backend_controller =
      AmbientBackendController::Get();
  DCHECK(ambient_backend_controller);
  return ambient_backend_controller;
}

void AddResources(content::WebUIDataSource* source) {
  source->AddResourcePath("", IDR_ASH_PERSONALIZATION_APP_INDEX_HTML);
  source->AddResourcePaths(base::make_span(
      kAshPersonalizationAppResources, kAshPersonalizationAppResourcesSize));
  source->AddResourcePath("test_loader.html", IDR_WEBUI_TEST_LOADER_HTML);
  source->AddResourcePath("test_loader.js", IDR_WEBUI_JS_TEST_LOADER_JS);
  source->AddResourcePath("test_loader_util.js",
                          IDR_WEBUI_JS_TEST_LOADER_UTIL_JS);

#if !DCHECK_IS_ON()
  // Add a default path to avoid crashes when not debugging.
  source->SetDefaultResource(IDR_ASH_PERSONALIZATION_APP_INDEX_HTML);
#endif  // !DCHECK_IS_ON()
}

void AddStrings(content::WebUIDataSource* source) {
  static constexpr webui::LocalizedString kLocalizedStrings[] = {
      {"personalizationTitle",
       IDS_PERSONALIZATION_APP_PERSONALIZATION_HUB_TITLE},
      {"wallpaperLabel", IDS_PERSONALIZATION_APP_WALLPAPER_LABEL},
      {"defaultWallpaper", IDS_PERSONALIZATION_APP_DEFAULT_WALLPAPER},
      {"back", IDS_PERSONALIZATION_APP_BACK_BUTTON},
      {"currentlySet", IDS_PERSONALIZATION_APP_CURRENTLY_SET},
      {"descriptionDialogOpen",
       IDS_PERSONALIZATION_APP_WALLPAPER_DESCRIPTION_DIALOG_OPEN},
      {"descriptionDialogClose",
       IDS_PERSONALIZATION_APP_WALLPAPER_DESCRIPTION_DIALOG_CLOSE},
      {"myImagesLabel", IDS_PERSONALIZATION_APP_MY_IMAGES},
      {"wallpaperCollections", IDS_PERSONALIZATION_APP_WALLPAPER_COLLECTIONS},
      {"center", IDS_PERSONALIZATION_APP_CENTER},
      {"fill", IDS_PERSONALIZATION_APP_FILL},
      {"changeDaily", IDS_PERSONALIZATION_APP_CHANGE_DAILY},
      {"ariaLabelChangeDaily", IDS_PERSONALIZATION_APP_ARIA_LABEL_CHANGE_DAILY},
      {"refresh", IDS_PERSONALIZATION_APP_REFRESH},
      {"ariaLabelRefresh", IDS_PERSONALIZATION_APP_ARIA_LABEL_REFRESH},
      {"dailyRefresh", IDS_PERSONALIZATION_APP_DAILY_REFRESH},
      {"unknownImageAttribution",
       IDS_PERSONALIZATION_APP_UNKNOWN_IMAGE_ATTRIBUTION},
      {"wallpaperNetworkError",
       IDS_PERSONALIZATION_APP_WALLPAPER_NETWORK_ERROR},
      {"ariaLabelLoading", IDS_PERSONALIZATION_APP_ARIA_LABEL_LOADING},
      // Using old wallpaper app error string pending final revision.
      // TODO(b/195609442)
      {"setWallpaperError", IDS_PERSONALIZATION_APP_SET_WALLPAPER_ERROR},
      {"loadWallpaperError", IDS_PERSONALIZATION_APP_LOAD_WALLPAPER_ERROR},
      {"dismiss", IDS_PERSONALIZATION_APP_DISMISS},
      {"ariaLabelViewFullScreen",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_VIEW_FULL_SCREEN},
      {"exitFullscreen", IDS_PERSONALIZATION_APP_EXIT_FULL_SCREEN},
      {"ariaLabelExitFullscreen",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_EXIT_FULL_SCREEN},
      {"setAsWallpaper", IDS_PERSONALIZATION_APP_SET_AS_WALLPAPER},
      {"zeroImages", IDS_PERSONALIZATION_APP_NO_IMAGES},
      {"oneImage", IDS_PERSONALIZATION_APP_ONE_IMAGE},
      {"multipleImages", IDS_PERSONALIZATION_APP_MULTIPLE_IMAGES},
      {"managedSetting", IDS_PERSONALIZATION_APP_MANAGED_SETTING},
      {"ariaLabelChangeWallpaper",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_CHANGE_WALLPAPER},
      {"ariaLabelHome", IDS_PERSONALIZATION_APP_ARIA_LABEL_HOME},

      // Theme related strings.
      {"themeLabel", IDS_PERSONALIZATION_APP_THEME_LABEL},
      {"dynamicColorLabel", IDS_PERSONALIZATION_APP_THEME_DYNAMIC_COLOR_LABEL},
      {"dynamicColorDescription",
       IDS_PERSONALIZATION_APP_THEME_DYNAMIC_COLOR_DESCRIPTION},
      {"colorSchemeTonalSpot",
       IDS_PERSONALIZATION_APP_THEME_COLOR_SCHEME_TONAL_SPOT},
      {"colorSchemeNeutral",
       IDS_PERSONALIZATION_APP_THEME_COLOR_SCHEME_NEUTRAL},
      {"colorSchemeVibrant",
       IDS_PERSONALIZATION_APP_THEME_COLOR_SCHEME_VIBRANT},
      {"colorSchemeExpressive",
       IDS_PERSONALIZATION_APP_THEME_COLOR_SCHEME_EXPRESSIVE},
      {"staticColorGoogleBlue",
       IDS_PERSONALIZATION_APP_THEME_STATIC_COLOR_GOOGLE_BLUE},
      {"staticColorLightPink",
       IDS_PERSONALIZATION_APP_THEME_STATIC_COLOR_LIGHT_PINK},
      {"staticColorDarkGreen",
       IDS_PERSONALIZATION_APP_THEME_STATIC_COLOR_DARK_GREEN},
      {"staticColorLightPurple",
       IDS_PERSONALIZATION_APP_THEME_STATIC_COLOR_LIGHT_PURPLE},
      {"darkColorMode", IDS_PERSONALIZATION_APP_THEME_DARK_COLOR_MODE},
      {"lightColorMode", IDS_PERSONALIZATION_APP_THEME_LIGHT_COLOR_MODE},
      {"autoColorMode", IDS_PERSONALIZATION_APP_THEME_AUTO_COLOR_MODE},
      {"ariaLabelEnableDarkColorMode",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_ENABLE_DARK_COLOR_MODE},
      {"ariaLabelEnableLightColorMode",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_ENABLE_LIGHT_COLOR_MODE},
      {"ariaLabelEnableAutoColorMode",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_ENABLE_AUTO_COLOR_MODE},
      {"tooltipAutoColorMode", IDS_PERSONALIZATION_APP_TOOLTIP_AUTO_COLOR_MODE},

      // User/avatar related strings.
      {"avatarLabel", IDS_PERSONALIZATION_APP_AVATAR_LABEL},
      {"takeWebcamPhoto", IDS_PERSONALIZATION_APP_AVATAR_TAKE_PHOTO},
      {"takeWebcamVideo", IDS_PERSONALIZATION_APP_AVATAR_TAKE_VIDEO},
      {"webcamCaptureInProgress",
       IDS_PERSONALIZATION_APP_AVATAR_CAPTURE_IN_PROGRESS},
      {"confirmWebcamPhoto", IDS_PERSONALIZATION_APP_AVATAR_CONFIRM_PHOTO},
      {"confirmWebcamVideo", IDS_PERSONALIZATION_APP_AVATAR_CONFIRM_VIDEO},
      {"rejectWebcamPhoto", IDS_PERSONALIZATION_APP_AVATAR_REJECT_PHOTO},
      {"ariaLabelChangeAvatar",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_CHANGE_AVATAR},
      {"ariaLabelGoToAccountSettings",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_GO_TO_ACCOUNT_SETTINGS},
      {"googleProfilePhoto",
       IDS_PERSONALIZATION_APP_AVATAR_GOOGLE_PROFILE_PHOTO},
      {"chooseAFile", IDS_PERSONALIZATION_APP_AVATAR_CHOOSE_A_FILE},
      {"lastExternalImageTitle",
       IDS_PERSONALIZATION_APP_AVATAR_LAST_EXTERNAL_IMAGE},
      {"ariaLabelCurrentAvatar",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_CURRENT_AVATAR},
      {"ariaAnnounceAvatarChanged",
       IDS_PERSONALIZATION_APP_ARIA_ANNOUNCE_AVATAR_CHANGED},
      {"ariaLabelCloseCamera",
       IDS_PERSONALIZATION_APP_AVATAR_ARIA_LABEL_CLOSE_CAMERA},
      {"ariaLabelWebcamVideo",
       IDS_PERSONALIZATION_APP_AVATAR_ARIA_LABEL_WEBCAM_VIDEO},
      {"avatarNetworkError", IDS_PERSONALIZATION_APP_AVATAR_NETWORK_ERROR},

      // Ambient mode related string.
      {"screensaverLabel", IDS_PERSONALIZATION_APP_SCREENSAVER_LABEL},
      {"screenSaverPreviewButton",
       IDS_PERSONALIZATION_APP_SCREENSAVER_PREVIEW_BUTTON},
      {"screenSaverPreviewButtonAriaLabel",
       IDS_PERSONALIZATION_APP_SCREENSAVER_PREVIEW_BUTTON_ARIA_LABEL},
      {"screenSaverPreviewDownloading",
       IDS_PERSONALIZATION_APP_SCREENSAVER_PREVIEW_DOWNLOADING},
      {"screenSaverPreviewDownloadingAriaLabel",
       IDS_PERSONALIZATION_APP_SCREENSAVER_PREVIEW_DOWNLOADING_ARIA_LABEL},
      {"ambientModePageDescription",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_PAGE_DESCRIPTION},
      {"ambientModeOn", IDS_PERSONALIZATION_APP_AMBIENT_MODE_ON},
      {"ambientModeOff", IDS_PERSONALIZATION_APP_AMBIENT_MODE_OFF},
      {"ambientModeTopicSourceTitle",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_TITLE},
      {"ambientModeTopicSourceGooglePhotos",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS},
      {"ambientModeTopicSourceGooglePhotosDescription",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC},
      {"ambientModeTopicSourceGooglePhotosDescriptionNoAlbum",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_GOOGLE_PHOTOS_DESC_NO_ALBUM},
      {"ambientModeTopicSourceArtGallery",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY},
      {"ambientModeTopicSourceArtGalleryDescription",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_ART_GALLERY_DESCRIPTION},
      {"ambientModeTopicSourceVideo",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_VIDEO},
      {"ambientModeTopicSourceVideoDescription",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_VIDEO_DESCRIPTION},
      {"ambientModeTopicSourceSelectedRow",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_SELECTED_ROW},
      {"ambientModeTopicSourceUnselectedRow",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TOPIC_SOURCE_UNSELECTED_ROW},
      {"ambientModeWeatherTitle",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_WEATHER_TITLE},
      {"ambientModeAriaDescriptionWeather",
       IDS_PERSONALIZATION_APP_ARIA_DESCRIPTION_AMBIENT_MODE_WEATHER},
      {"ambientModeWeatherUnitFahrenheit",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_WEATHER_UNIT_FAHRENHEIT},
      {"ambientModeWeatherUnitCelsius",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_WEATHER_UNIT_CELSIUS},
      {"ambientModeAlbumsSubpageRecentHighlightsDesc",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_RECENT_DESC},
      {"ambientModeAlbumsSubpagePhotosNumPluralDesc",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_PHOTOS_NUM_PLURAL},
      {"ambientModeAlbumsSubpagePhotosNumSingularDesc",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_PHOTOS_NUM_SINGULAR},
      {"ambientModeAlbumsSubpageAlbumSelected",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_SELECTED},
      {"ambientModeAlbumsSubpageAlbumUnselected",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_ALBUM_UNSELECTED},
      {"ambientModeLastArtAlbumMessage",
       IDS_PERONSONALIZATION_APP_AMBIENT_MODE_LAST_ART_ALBUM_MESSAGE},
      {"ambientModeArtAlbumDialogCloseButtonLabel",
       IDS_PERONSONALIZATION_APP_AMBIENT_MODE_ART_ALBUM_DIALOG_CLOSE_BUTTON_LABEL},
      {"ambientModeAnimationTitle",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_TITLE},
      {"ambientModeAnimationSlideshowLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_SLIDESHOW_LABEL},
      {"ambientModeAnimationFeelTheBreezeLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_FEEL_THE_BREEZE_LABEL},
      {"ambientModeAnimationFloatOnByLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_FLOAT_ON_BY_LABEL},
      {"ambientModeAnimationVideoLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ANIMATION_VIDEO_LABEL},
      {"ambientModeZeroStateMessage",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_ZERO_STATE_MESSAGE},
      {"ambientModeMultipleAlbumsDesc",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_MULTIPLE_ALBUMS_DESC},
      {"ambientModeMainPageZeroStateMessage",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_MAIN_PAGE_ZERO_STATE_MESSAGE},
      {"ambientModeMainPageZeroStateMessageV2",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_MAIN_PAGE_ZERO_STATE_MESSAGE_V2},
      {"ambientModeMainPageEnterpriseUserMessage",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_MAIN_PAGE_ENTERPRISE_USER_MESSAGE},
      {"ambientModeTurnOnLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_TURN_ON_LABEL},
      {"ambientModeLearnMoreLabel",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_LEARN_MORE_LABEL},
      {"ariaLabelChangeScreensaver",
       IDS_PERSONALIZATION_APP_ARIA_LABEL_CHANGE_SCREENSAVER},
      {"ambientModeNetworkError",
       IDS_PERSONALIZATION_APP_AMBIENT_MODE_NETWORK_ERROR},

      // Keyboard backlight strings
      {"keyboardBacklightTitle",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_TITLE},
      {"wallpaperColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_LABEL},
      {"wallpaperColorTooltipText",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_TOOLTIP_TEXT},
      {"whiteColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WHITE_COLOR_LABEL},
      {"redColor", IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_RED_COLOR_LABEL},
      {"yellowColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_YELLOW_COLOR_LABEL},
      {"greenColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_GREEN_COLOR_LABEL},
      {"blueColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_BLUE_COLOR_LABEL},
      {"indigoColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_INDIGO_COLOR_LABEL},
      {"purpleColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_PURPLE_COLOR_LABEL},
      {"rainbowColor",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_RAINBOW_COLOR_LABEL},
      {"wallpaperColorNudgeText",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_NUDGE_TEXT},
      {"zoneCustomize",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_ZONE_CUSTOMIZATION_BUTTON},
      {"dismissButtonText",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_ZONE_CUSTOMIZATION_DISMISS_BUTTON},
      {"wallpaperColorDescription",
       IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_WALLPAPER_COLOR_DESCRIPTION},
      {"zoneTitle", IDS_PERSONALIZATION_APP_KEYBOARD_BACKLIGHT_ZONE_TITLE},
      {"keyboardZonesTitle", IDS_PERSONALIZATION_APP_KEYBOARD_ZONES_TITLE},

      // Google Photos strings
      // TODO(b/229149314): Finalize error and retry strings.
      {"googlePhotosLabel", IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS},
      {"googlePhotosError", IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_ERROR},
      {"googlePhotosTryAgain", IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_TRY_AGAIN},
      {"googlePhotosAlbumShared",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_ALBUM_SHARED},
      {"googlePhotosSharedAlbumDialogTitle",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_SHARED_ALBUM_DIALOG_TITLE},
      {"googlePhotosSharedAlbumDialogContent",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_SHARED_ALBUM_DIALOG_CONTENT},
      {"googlePhotosSharedAlbumDialogCloseButton",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_SHARED_ALBUM_DIALOG_CLOSE_BUTTON},
      {"googlePhotosSharedAlbumDialogAcceptButton",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_SHARED_ALBUM_DIALOG_ACCEPT_BUTTON},
      {"googlePhotosAlbumsTabLabel",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_ALBUMS_TAB},
      {"googlePhotosPhotosTabLabel",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_PHOTOS_TAB},
      {"googlePhotosZeroStateMessage",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_ZERO_STATE_MESSAGE},
      {"googlePhotosAlbumZeroStateMessage",
       IDS_PERSONALIZATION_APP_GOOGLE_PHOTOS_ALBUM_ZERO_STATE_MESSAGE},

      //  Time of day Wallpaper/Screen saver strings
      {"timeOfDayWallpaperDialogTitle",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_WALLPAPER_DIALOG_TITLE},
      {"timeOfDayWallpaperDialogContent",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_WALLPAPER_DIALOG_CONTENT},
      {"timeOfDayWallpaperDialogBackButton",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_WALLPAPER_DIALOG_BACK_BUTTON},
      {"timeOfDayWallpaperDialogConfirmButton",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_WALLPAPER_DIALOG_CONFIRM_BUTTON},
      {"timeOfDayBannerTitle",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_BANNER_TITLE},
      {"timeOfDayBannerDescription",
       IDS_PERSONALIZATION_APP_TIME_OF_DAY_BANNER_DESCRIPTION}};

  source->AddLocalizedStrings(kLocalizedStrings);

  source->AddString("googlePhotosURL", GetGooglePhotosURL());

  source->AddString("timeOfDayBannerImageUrl",
                    GetAmbientBackendController()->GetPromoBannerUrl());

  source->AddString(
      "ambientModeAlbumsSubpageGooglePhotosTitle",
      l10n_util::GetStringFUTF16(
          IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_TITLE,
          GetGooglePhotosURL()));
  source->AddString(
      "ambientModeAlbumsSubpageGooglePhotosNoAlbum",
      l10n_util::GetStringFUTF16(
          IDS_PERSONALIZATION_APP_AMBIENT_MODE_ALBUMS_SUBPAGE_GOOGLE_PHOTOS_NO_ALBUM,
          GetGooglePhotosURL()));

  source->UseStringsJs();
  source->EnableReplaceI18nInJS();
}

bool ShouldHandleWebUIRequest(const std::string& path) {
  return base::StartsWith(path, "wallpaper.jpg");
}

}  // namespace

PersonalizationAppUI::PersonalizationAppUI(
    content::WebUI* web_ui,
    std::unique_ptr<PersonalizationAppAmbientProvider> ambient_provider,
    std::unique_ptr<PersonalizationAppKeyboardBacklightProvider>
        keyboard_backlight_provider,
    std::unique_ptr<PersonalizationAppThemeProvider> theme_provider,
    std::unique_ptr<PersonalizationAppUserProvider> user_provider,
    std::unique_ptr<PersonalizationAppWallpaperProvider> wallpaper_provider)
    : ui::MojoWebUIController(web_ui),
      ambient_provider_(std::move(ambient_provider)),
      keyboard_backlight_provider_(std::move(keyboard_backlight_provider)),
      theme_provider_(std::move(theme_provider)),
      user_provider_(std::move(user_provider)),
      wallpaper_provider_(std::move(wallpaper_provider)) {
  DCHECK(wallpaper_provider_);

  content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
      web_ui->GetWebContents()->GetBrowserContext(),
      kChromeUIPersonalizationAppHost);

  // Supply a custom wallpaper image.
  source->SetRequestFilter(
      base::BindRepeating(&ShouldHandleWebUIRequest),
      base::BindRepeating(&PersonalizationAppUI::HandleWebUIRequest,
                          weak_ptr_factory_.GetWeakPtr()));

  source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::ScriptSrc,
      "script-src chrome://resources chrome://test chrome://webui-test "
      "'self';");

  // TODO(crbug.com/1400799): Enable TrustedTypes.
  source->DisableTrustedTypesCSP();

  AddResources(source);
  AddStrings(source);
  AddBooleans(source);
  AddIntegers(source);
}

PersonalizationAppUI::~PersonalizationAppUI() = default;

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<personalization_app::mojom::AmbientProvider>
        receiver) {
  ambient_provider_->BindInterface(std::move(receiver));
}

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<personalization_app::mojom::KeyboardBacklightProvider>
        receiver) {
  keyboard_backlight_provider_->BindInterface(std::move(receiver));
}

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<personalization_app::mojom::ThemeProvider> receiver) {
  theme_provider_->BindInterface(std::move(receiver));
}

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<personalization_app::mojom::WallpaperProvider>
        receiver) {
  wallpaper_provider_->BindInterface(std::move(receiver));
}

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<personalization_app::mojom::UserProvider> receiver) {
  user_provider_->BindInterface(std::move(receiver));
}

void PersonalizationAppUI::BindInterface(
    mojo::PendingReceiver<color_change_listener::mojom::PageHandler> receiver) {
  DCHECK(chromeos::features::IsJellyEnabled());
  color_provider_handler_ = std::make_unique<ui::ColorChangeHandler>(
      web_ui()->GetWebContents(), std::move(receiver));
}

void PersonalizationAppUI::AddBooleans(content::WebUIDataSource* source) {
  source->AddBoolean("isGooglePhotosIntegrationEnabled",
                     wallpaper_provider_->IsEligibleForGooglePhotos());

  source->AddBoolean("isGooglePhotosSharedAlbumsEnabled",
                     features::IsWallpaperGooglePhotosSharedAlbumsEnabled());

  source->AddBoolean("isAmbientModeAllowed", IsAmbientModeAllowed());

  source->AddBoolean(
      "isRgbKeyboardSupported",
      features::IsRgbKeyboardEnabled() &&
          Shell::Get()->rgb_keyboard_manager()->IsRgbKeyboardSupported());

  source->AddBoolean("isScreenSaverDurationEnabled",
                     features::IsScreenSaverDurationEnabled());

  source->AddBoolean("isScreenSaverPreviewEnabled",
                     features::IsScreenSaverPreviewEnabled());

  source->AddBoolean("isPersonalizationJellyEnabled",
                     features::IsPersonalizationJellyEnabled());

  source->AddBoolean("isUserAvatarCustomizationSelectorsEnabled",
                     user_provider_->IsCustomizationSelectorsPrefEnabled());

  source->AddBoolean("isTimeOfDayScreenSaverEnabled",
                     features::IsTimeOfDayScreenSaverEnabled());
}

void PersonalizationAppUI::AddIntegers(content::WebUIDataSource* source) {
  source->AddInteger("keyboardBacklightZoneCount",
                     features::IsMultiZoneRgbKeyboardEnabled()
                         ? Shell::Get()->rgb_keyboard_manager()->GetZoneCount()
                         : 0);
}

void PersonalizationAppUI::HandleWebUIRequest(
    const std::string& path,
    content::WebUIDataSource::GotDataCallback callback) {
  DCHECK(base::Contains(path, "?key="))
      << "wallpaper key must be provided to prevent browser cache collisions";
  wallpaper_provider_->GetWallpaperAsJpegBytes(std::move(callback));
}

WEB_UI_CONTROLLER_TYPE_IMPL(PersonalizationAppUI)

}  // namespace ash::personalization_app