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

#include "chrome/browser/search/local_ntp_source.h"

#include "base/base64.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/json/json_string_value_serializer.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/memory/ref_counted_memory.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/background/ntp_background_data.h"
#include "chrome/browser/search/background/ntp_background_service.h"
#include "chrome/browser/search/background/ntp_background_service_factory.h"
#include "chrome/browser/search/instant_io_context.h"
#include "chrome/browser/search/local_files_ntp_source.h"
#include "chrome/browser/search/local_ntp_js_integrity.h"
#include "chrome/browser/search/ntp_features.h"
#include "chrome/browser/search/one_google_bar/one_google_bar_data.h"
#include "chrome/browser/search/one_google_bar/one_google_bar_service.h"
#include "chrome/browser/search/one_google_bar/one_google_bar_service_factory.h"
#include "chrome/browser/search/promos/promo_data.h"
#include "chrome/browser/search/promos/promo_service.h"
#include "chrome/browser/search/promos/promo_service_factory.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/search/search_suggest/search_suggest_data.h"
#include "chrome/browser/search/search_suggest/search_suggest_service.h"
#include "chrome/browser/search/search_suggest/search_suggest_service_factory.h"
#include "chrome/browser/search_engines/template_url_service_factory.h"
#include "chrome/browser/search_provider_logos/logo_service_factory.h"
#include "chrome/browser/themes/theme_properties.h"
#include "chrome/browser/themes/theme_service.h"
#include "chrome/browser/themes/theme_service_factory.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/browser_resources.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/local_ntp_resources.h"
#include "components/google/core/common/google_util.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/search_engines/template_url_service_observer.h"
#include "components/search_provider_logos/logo_common.h"
#include "components/search_provider_logos/logo_observer.h"
#include "components/search_provider_logos/logo_service.h"
#include "components/search_provider_logos/switches.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/sha2.h"
#include "net/base/url_util.h"
#include "net/url_request/url_request.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_features.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/native_theme/native_theme.h"
#include "ui/resources/grit/ui_resources.h"
#include "url/gurl.h"

using search_provider_logos::EncodedLogo;
using search_provider_logos::EncodedLogoCallback;
using search_provider_logos::LogoCallbacks;
using search_provider_logos::LogoCallbackReason;
using search_provider_logos::LogoMetadata;
using search_provider_logos::LogoService;

namespace {

// Signifies a locally constructed resource, i.e. not from grit/.
const int kLocalResource = -1;

const char kConfigDataFilename[] = "config.js";
const char kDoodleScriptFilename[] = "doodle.js";
const char kGoogleUrl[] = "https://www.google.com/";
const char kIntegrityFormat[] = "integrity=\"sha256-%s\"";
const char kMainHtmlFilename[] = "local-ntp.html";
const char kNtpBackgroundCollectionScriptFilename[] =
    "ntp-background-collections.js";
const char kNtpBackgroundImageScriptFilename[] = "ntp-background-images.js";
const char kOneGoogleBarScriptFilename[] = "one-google.js";
const char kPromoScriptFilename[] = "promo.js";
const char kSearchSuggestionsScriptFilename[] = "search-suggestions.js";
const char kThemeCSSFilename[] = "theme.css";

const struct Resource{
  const char* filename;
  int identifier;
  const char* mime_type;
} kResources[] = {
    {"animations.css", IDR_LOCAL_NTP_ANIMATIONS_CSS, "text/css"},
    {"animations.js", IDR_LOCAL_NTP_ANIMATIONS_JS, "application/javascript"},
    {"constants.css", IDR_LOCAL_NTP_CONSTANTS_CSS, "text/css"},
    {"custom-backgrounds.css", IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_CSS,
     "text/css"},
    {"custom-backgrounds.js", IDR_LOCAL_NTP_CUSTOM_BACKGROUNDS_JS,
     "application/javascript"},
    {"doodles.css", IDR_LOCAL_NTP_DOODLES_CSS, "text/css"},
    {"doodles.js", IDR_LOCAL_NTP_DOODLES_JS, "application/javascript"},
    {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"},
    {"images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png"},
    {"local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css"},
    {"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"},
    {"utils.js", IDR_LOCAL_NTP_UTILS_JS, "application/javascript"},
    {"voice.css", IDR_LOCAL_NTP_VOICE_CSS, "text/css"},
    {"voice.js", IDR_LOCAL_NTP_VOICE_JS, "application/javascript"},
    {kConfigDataFilename, kLocalResource, "application/javascript"},
    {kDoodleScriptFilename, kLocalResource, "text/javascript"},
    {kMainHtmlFilename, kLocalResource, "text/html"},
    {kNtpBackgroundCollectionScriptFilename, kLocalResource, "text/javascript"},
    {kNtpBackgroundImageScriptFilename, kLocalResource, "text/javascript"},
    {kOneGoogleBarScriptFilename, kLocalResource, "text/javascript"},
    {kPromoScriptFilename, kLocalResource, "text/javascript"},
    {kSearchSuggestionsScriptFilename, kLocalResource, "text/javascript"},
    {kThemeCSSFilename, kLocalResource, "text/css"},
    // Image may not be a jpeg but the .jpg extension here still works for other
    // filetypes. Special handling for different extensions isn't worth the
    // added complexity.
    {chrome::kChromeSearchLocalNtpBackgroundFilename, kLocalResource,
     "image/jpg"},
};

// This enum must match the numbering for NTPSearchSuggestionsRequestStatus in
// enums.xml. Do not reorder or remove items, and update kMaxValue when new
// items are added.
enum class SearchSuggestionsRequestStatus {
  UNKNOWN_ERROR = 0,
  SENT = 1,
  SIGNED_OUT = 2,
  OPTED_OUT = 3,
  IMPRESSION_CAP = 4,
  FROZEN = 5,
  FATAL_ERROR = 6,

  kMaxValue = FATAL_ERROR
};

// Strips any query parameters from the specified path.
std::string StripParameters(const std::string& path) {
  return path.substr(0, path.find("?"));
}

// Adds a localized string keyed by resource id to the dictionary.
void AddString(base::DictionaryValue* dictionary,
               const std::string& key,
               int resource_id) {
  dictionary->SetString(key, l10n_util::GetStringUTF16(resource_id));
}

// Populates |translated_strings| dictionary for the local NTP. |is_google|
// indicates that this page is the Google local NTP.
std::unique_ptr<base::DictionaryValue> GetTranslatedStrings(bool is_google) {
  auto translated_strings = std::make_unique<base::DictionaryValue>();

  AddString(translated_strings.get(), "thumbnailRemovedNotification",
            IDS_NTP_CONFIRM_MSG_SHORTCUT_REMOVED);
  AddString(translated_strings.get(), "removeThumbnailTooltip",
            IDS_NEW_TAB_REMOVE_THUMBNAIL_TOOLTIP);
  AddString(translated_strings.get(), "undoThumbnailRemove",
            IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE);
  AddString(translated_strings.get(), "restoreThumbnailsShort",
            IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK);
  AddString(translated_strings.get(), "attributionIntro",
            IDS_NEW_TAB_ATTRIBUTION_INTRO);
  AddString(translated_strings.get(), "title", IDS_NEW_TAB_TITLE);
  AddString(translated_strings.get(), "mostVisitedTitle",
            IDS_NEW_TAB_MOST_VISITED);

  if (is_google) {
    AddString(translated_strings.get(), "searchboxPlaceholder",
              IDS_GOOGLE_SEARCH_BOX_EMPTY_HINT_MD);

    // Custom Backgrounds
    AddString(translated_strings.get(), "customizeBackground",
              IDS_NTP_CUSTOM_BG_CUSTOMIZE_BACKGROUND);
    AddString(translated_strings.get(), "connectGooglePhotos",
              IDS_NTP_CUSTOM_BG_GOOGLE_PHOTOS);
    AddString(translated_strings.get(), "defaultWallpapers",
              IDS_NTP_CUSTOM_BG_CHROME_WALLPAPERS);
    AddString(translated_strings.get(), "uploadImage",
              IDS_NTP_CUSTOM_BG_UPLOAD_AN_IMAGE);
    AddString(translated_strings.get(), "restoreDefaultBackground",
              IDS_NTP_CUSTOM_BG_RESTORE_DEFAULT);
    AddString(translated_strings.get(), "selectChromeWallpaper",
              IDS_NTP_CUSTOM_BG_SELECT_A_COLLECTION);
    AddString(translated_strings.get(), "dailyRefresh",
              IDS_NTP_CUSTOM_BG_DAILY_REFRESH);
    AddString(translated_strings.get(), "selectionDone",
              IDS_NTP_CUSTOM_LINKS_DONE);
    AddString(translated_strings.get(), "selectionCancel",
              IDS_NTP_CUSTOM_BG_CANCEL);
    AddString(translated_strings.get(), "selectGooglePhotoAlbum",
              IDS_NTP_CUSTOM_BG_SELECT_GOOGLE_ALBUM);
    AddString(translated_strings.get(), "connectionErrorNoPeriod",
              IDS_NTP_CONNECTION_ERROR_NO_PERIOD);
    AddString(translated_strings.get(), "connectionError",
              IDS_NTP_CONNECTION_ERROR);
    AddString(translated_strings.get(), "moreInfo", IDS_NTP_ERROR_MORE_INFO);
    AddString(translated_strings.get(), "backgroundsUnavailable",
              IDS_NTP_CUSTOM_BG_BACKGROUNDS_UNAVAILABLE);
    AddString(translated_strings.get(), "customizeThisPage",
              IDS_NTP_CUSTOM_BG_CUSTOMIZE_NTP_LABEL);
    AddString(translated_strings.get(), "backLabel",
              IDS_NTP_CUSTOM_BG_BACK_LABEL);
    AddString(translated_strings.get(), "photoLabel",
              IDS_NTP_CUSTOM_BG_GOOGLE_PHOTO_LABEL);
    AddString(translated_strings.get(), "selectedLabel",
              IDS_NTP_CUSTOM_BG_PHOTO_SELECTED);

    // Custom Links
    AddString(translated_strings.get(), "addLinkTitle",
              IDS_NTP_CUSTOM_LINKS_ADD_SHORTCUT_TITLE);
    AddString(translated_strings.get(), "addLinkTooltip",
              IDS_NTP_CUSTOM_LINKS_ADD_SHORTCUT_TOOLTIP);
    AddString(translated_strings.get(), "editLinkTitle",
              IDS_NTP_CUSTOM_LINKS_EDIT_SHORTCUT);
    AddString(translated_strings.get(), "editLinkTooltip",
              IDS_NTP_CUSTOM_LINKS_EDIT_SHORTCUT_TOOLTIP);
    AddString(translated_strings.get(), "nameField", IDS_NTP_CUSTOM_LINKS_NAME);
    AddString(translated_strings.get(), "urlField", IDS_NTP_CUSTOM_LINKS_URL);
    AddString(translated_strings.get(), "linkRemove",
              IDS_NTP_CUSTOM_LINKS_REMOVE);
    AddString(translated_strings.get(), "linkCancel",
              IDS_NTP_CUSTOM_LINKS_CANCEL);
    AddString(translated_strings.get(), "linkDone", IDS_NTP_CUSTOM_LINKS_DONE);
    AddString(translated_strings.get(), "invalidUrl",
              IDS_NTP_CUSTOM_LINKS_INVALID_URL);
    AddString(translated_strings.get(), "linkRemovedMsg",
              IDS_NTP_CONFIRM_MSG_SHORTCUT_REMOVED);
    AddString(translated_strings.get(), "linkEditedMsg",
              IDS_NTP_CONFIRM_MSG_SHORTCUT_EDITED);
    AddString(translated_strings.get(), "linkAddedMsg",
              IDS_NTP_CONFIRM_MSG_SHORTCUT_ADDED);
    AddString(translated_strings.get(), "restoreDefaultLinks",
              IDS_NTP_CONFIRM_MSG_RESTORE_DEFAULTS);
    AddString(translated_strings.get(), "linkCantCreate",
              IDS_NTP_CUSTOM_LINKS_CANT_CREATE);
    AddString(translated_strings.get(), "linkCantEdit",
              IDS_NTP_CUSTOM_LINKS_CANT_EDIT);
    AddString(translated_strings.get(), "linkCantRemove",
              IDS_NTP_CUSTOM_LINKS_CANT_REMOVE);

    // Doodle Sharing
    AddString(translated_strings.get(), "shareDoodle",
              IDS_NTP_DOODLE_SHARE_LABEL);
    AddString(translated_strings.get(), "shareClose",
              IDS_NTP_DOODLE_SHARE_DIALOG_CLOSE_LABEL);
    AddString(translated_strings.get(), "shareFacebook",
              IDS_NTP_DOODLE_SHARE_DIALOG_FACEBOOK_LABEL);
    AddString(translated_strings.get(), "shareTwitter",
              IDS_NTP_DOODLE_SHARE_DIALOG_TWITTER_LABEL);
    AddString(translated_strings.get(), "shareMail",
              IDS_NTP_DOODLE_SHARE_DIALOG_MAIL_LABEL);
    AddString(translated_strings.get(), "copyLink",
              IDS_NTP_DOODLE_SHARE_DIALOG_COPY_LABEL);
    AddString(translated_strings.get(), "shareLink",
              IDS_NTP_DOODLE_SHARE_DIALOG_LINK_LABEL);

    // Voice Search
    AddString(translated_strings.get(), "audioError",
              IDS_NEW_TAB_VOICE_AUDIO_ERROR);
    AddString(translated_strings.get(), "details", IDS_NEW_TAB_VOICE_DETAILS);
    AddString(translated_strings.get(), "clickToViewDoodle",
              IDS_CLICK_TO_VIEW_DOODLE);
    AddString(translated_strings.get(), "fakeboxMicrophoneTooltip",
              IDS_TOOLTIP_MIC_SEARCH);
    AddString(translated_strings.get(), "languageError",
              IDS_NEW_TAB_VOICE_LANGUAGE_ERROR);
    AddString(translated_strings.get(), "learnMore", IDS_LEARN_MORE);
    AddString(translated_strings.get(), "listening",
              IDS_NEW_TAB_VOICE_LISTENING);
    AddString(translated_strings.get(), "networkError",
              IDS_NEW_TAB_VOICE_NETWORK_ERROR);
    AddString(translated_strings.get(), "noTranslation",
              IDS_NEW_TAB_VOICE_NO_TRANSLATION);
    AddString(translated_strings.get(), "noVoice", IDS_NEW_TAB_VOICE_NO_VOICE);
    AddString(translated_strings.get(), "permissionError",
              IDS_NEW_TAB_VOICE_PERMISSION_ERROR);
    AddString(translated_strings.get(), "ready", IDS_NEW_TAB_VOICE_READY);
    AddString(translated_strings.get(), "tryAgain",
              IDS_NEW_TAB_VOICE_TRY_AGAIN);
    AddString(translated_strings.get(), "waiting", IDS_NEW_TAB_VOICE_WAITING);
    AddString(translated_strings.get(), "otherError",
              IDS_NEW_TAB_VOICE_OTHER_ERROR);
  }

  return translated_strings;
}

std::string GetThemeCSS(Profile* profile) {
  SkColor background_color =
      ThemeService::GetThemeProviderForProfile(profile)
          .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);

  return base::StringPrintf("html { background-color: #%02X%02X%02X; }",
                            SkColorGetR(background_color),
                            SkColorGetG(background_color),
                            SkColorGetB(background_color));
}

std::string ReadBackgroundImageData(const base::FilePath& profile_path) {
  std::string data_string;
  base::ReadFileToString(
      profile_path.AppendASCII(chrome::kChromeSearchLocalNtpBackgroundFilename),
      &data_string);
  return data_string;
}

void ServeBackgroundImageData(
    const content::URLDataSource::GotDataCallback& callback,
    std::string data_string) {
  callback.Run(base::RefCountedString::TakeString(&data_string));
}

std::string GetLocalNtpPath() {
  return std::string(chrome::kChromeSearchScheme) + "://" +
         std::string(chrome::kChromeSearchLocalNtpHost) + "/";
}

base::Value ConvertCollectionInfoToDict(
    const std::vector<CollectionInfo>& collection_info) {
  base::Value collections(base::Value::Type::LIST);
  collections.GetList().reserve(collection_info.size());
  for (const CollectionInfo& collection : collection_info) {
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey("collectionId", base::Value(collection.collection_id));
    dict.SetKey("collectionName", base::Value(collection.collection_name));
    dict.SetKey("previewImageUrl",
                base::Value(collection.preview_image_url.spec()));
    collections.GetList().push_back(std::move(dict));
  }
  return collections;
}

base::Value ConvertCollectionImageToDict(
    const std::vector<CollectionImage>& collection_image) {
  base::Value images(base::Value::Type::LIST);
  images.GetList().reserve(collection_image.size());
  for (const CollectionImage& image : collection_image) {
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey("thumbnailImageUrl",
                base::Value(image.thumbnail_image_url.spec()));
    dict.SetKey("imageUrl", base::Value(image.image_url.spec()));
    dict.SetKey("collectionId", base::Value(image.collection_id));
    base::Value attributions(base::Value::Type::LIST);
    for (const auto& attribution : image.attribution) {
      attributions.GetList().push_back(base::Value(attribution));
    }
    dict.SetKey("attributions", std::move(attributions));
    dict.SetKey("attributionActionUrl",
                base::Value(image.attribution_action_url.spec()));
    images.GetList().push_back(std::move(dict));
  }
  return images;
}

base::Value ConvertAlbumInfoToDict(const std::vector<AlbumInfo>& album_info) {
  base::Value albums(base::Value::Type::LIST);
  albums.GetList().reserve(album_info.size());
  for (const AlbumInfo& album : album_info) {
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey("albumId", base::Value(std::to_string(album.album_id)));
    dict.SetKey("photoContainerId", base::Value(album.photo_container_id));
    dict.SetKey("albumName", base::Value(album.album_name));
    dict.SetKey("previewImageUrl", base::Value(album.preview_image_url.spec()));
    albums.GetList().push_back(std::move(dict));
  }
  return albums;
}

base::Value ConvertAlbumPhotosToDict(
    const std::vector<AlbumPhoto>& album_photos) {
  base::Value photos(base::Value::Type::LIST);
  photos.GetList().reserve(album_photos.size());
  for (const AlbumPhoto& photo : album_photos) {
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey("thumbnailPhotoUrl",
                base::Value(photo.thumbnail_photo_url.spec()));
    dict.SetKey("photoUrl", base::Value(photo.photo_url.spec()));
    dict.SetKey("albumId", base::Value(photo.album_id));
    dict.SetKey("photoContainerId", base::Value(photo.photo_container_id));
    photos.GetList().push_back(std::move(dict));
  }
  return photos;
}

std::unique_ptr<base::DictionaryValue> ConvertOGBDataToDict(
    const OneGoogleBarData& og) {
  auto result = std::make_unique<base::DictionaryValue>();
  result->SetString("barHtml", og.bar_html);
  result->SetString("inHeadScript", og.in_head_script);
  result->SetString("inHeadStyle", og.in_head_style);
  result->SetString("afterBarScript", og.after_bar_script);
  result->SetString("endOfBodyHtml", og.end_of_body_html);
  result->SetString("endOfBodyScript", og.end_of_body_script);
  return result;
}

std::unique_ptr<base::DictionaryValue> ConvertPromoDataToDict(
    const base::Optional<PromoData>& promo) {
  auto result = std::make_unique<base::DictionaryValue>();
  if (promo.has_value()) {
    result->SetString("promoHtml", promo->promo_html);
    result->SetString("promoLogUrl", promo->promo_log_url.spec());
  } else {
    result->SetString("promoHtml", std::string());
  }
  return result;
}

std::unique_ptr<base::DictionaryValue> ConvertSearchSuggestDataToDict(
    const base::Optional<SearchSuggestData>& data) {
  auto result = std::make_unique<base::DictionaryValue>();
  if (data.has_value()) {
    result->SetString("suggestionsHtml", data->suggestions_html);
    result->SetString("suggestionsEndOfBodyScript", data->end_of_body_script);
  } else {
    result->SetString("suggestionsHtml", std::string());
  }
  return result;
}

std::string ConvertLogoImageToBase64(const EncodedLogo& logo) {
  if (!logo.encoded_image)
    return std::string();

  std::string base64;
  base::Base64Encode(logo.encoded_image->data(), &base64);
  return base::StringPrintf("data:%s;base64,%s",
                            logo.metadata.mime_type.c_str(), base64.c_str());
}

std::string LogoTypeToString(search_provider_logos::LogoType type) {
  switch (type) {
    case search_provider_logos::LogoType::SIMPLE:
      return "SIMPLE";
    case search_provider_logos::LogoType::ANIMATED:
      return "ANIMATED";
    case search_provider_logos::LogoType::INTERACTIVE:
      return "INTERACTIVE";
  }
  NOTREACHED();
  return std::string();
}

std::unique_ptr<base::DictionaryValue> ConvertLogoMetadataToDict(
    const LogoMetadata& meta) {
  auto result = std::make_unique<base::DictionaryValue>();
  result->SetString("type", LogoTypeToString(meta.type));
  result->SetString("onClickUrl", meta.on_click_url.spec());
  result->SetString("altText", meta.alt_text);
  result->SetString("mimeType", meta.mime_type);
  result->SetString("animatedUrl", meta.animated_url.spec());
  result->SetInteger("iframeWidthPx", meta.iframe_width_px);
  result->SetInteger("iframeHeightPx", meta.iframe_height_px);
  result->SetString("logUrl", meta.log_url.spec());
  result->SetString("ctaLogUrl", meta.cta_log_url.spec());
  result->SetString("shortLink", meta.short_link.spec());

  if (meta.share_button_x >= 0 && meta.share_button_y >= 0 &&
      !meta.share_button_icon.empty() && !meta.share_button_bg.empty()) {
    result->SetInteger("shareButtonX", meta.share_button_x);
    result->SetInteger("shareButtonY", meta.share_button_y);
    result->SetDouble("shareButtonOpacity", meta.share_button_opacity);
    result->SetString("shareButtonIcon", meta.share_button_icon);
    result->SetString("shareButtonBg", meta.share_button_bg);
  }

  GURL full_page_url = meta.full_page_url;
  result->SetString("fullPageUrl", full_page_url.spec());

  // The fpdoodle url is always relative to google.com, for testing it needs to
  // be replaced with the demo url provided on the command line via
  // --google-base-url.
  GURL google_base_url = google_util::CommandLineGoogleBaseURL();
  std::string url = full_page_url.spec();
  auto pos = url.find(kGoogleUrl);
  if (google_base_url.is_valid() && pos != std::string::npos) {
    url.replace(pos, strlen(kGoogleUrl), google_base_url.spec());
    result->SetString("fullPageUrl", url);
  }

  // If support for interactive Doodles is disabled, treat them as simple
  // Doodles instead and use the full page URL as the target URL.
  if (meta.type == search_provider_logos::LogoType::INTERACTIVE &&
      !base::GetFieldTrialParamByFeatureAsBool(features::kDoodlesOnLocalNtp,
                                               "local_ntp_interactive_doodles",
                                               /*default_value=*/true)) {
    result->SetString(
        "type", LogoTypeToString(search_provider_logos::LogoType::SIMPLE));
    result->SetString("onClickUrl", meta.full_page_url.spec());
  }

  return result;
}

// Note: Code that runs on the IO thread is implemented as non-member functions,
// to avoid accidentally accessing member data that's owned by the UI thread.

bool ShouldServiceRequestIOThread(const GURL& url,
                                  content::ResourceContext* resource_context,
                                  int render_process_id) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  DCHECK(url.host_piece() == chrome::kChromeSearchLocalNtpHost);
  if (!InstantIOContext::ShouldServiceRequest(url, resource_context,
                                              render_process_id)) {
    return false;
  }

  if (url.SchemeIs(chrome::kChromeSearchScheme)) {
    std::string filename;
    webui::ParsePathAndScale(url, &filename, nullptr);
    for (size_t i = 0; i < base::size(kResources); ++i) {
      if (filename == kResources[i].filename)
        return true;
    }
  }
  return false;
}

std::string GetErrorDict(const ErrorInfo& error) {
  base::DictionaryValue error_info;
  error_info.SetBoolean("auth_error",
                        error.error_type == ErrorType::AUTH_ERROR);
  error_info.SetBoolean("net_error", error.error_type == ErrorType::NET_ERROR);
  error_info.SetBoolean("service_error",
                        error.error_type == ErrorType::SERVICE_ERROR);
  error_info.SetInteger("net_error_no", error.net_error);

  std::string js_text;
  JSONStringValueSerializer serializer(&js_text);
  serializer.Serialize(error_info);

  return js_text;
}

}  // namespace

// Keeps the search engine configuration data to be included on the Local NTP,
// and will also keep track of any changes in search engine provider to
// recompute this data.
class LocalNtpSource::SearchConfigurationProvider
    : public TemplateURLServiceObserver {
 public:
  explicit SearchConfigurationProvider(TemplateURLService* service)
      : service_(service) {
    DCHECK(service_);
    service_->AddObserver(this);
    UpdateConfigData();
  }

  ~SearchConfigurationProvider() override {
    if (service_)
      service_->RemoveObserver(this);
  }

  const std::string& config_data_js() const { return config_data_js_; }
  const std::string& config_data_integrity() const {
    return config_data_integrity_;
  }

 private:
  // Updates the configuration data for the local NTP.
  void UpdateConfigData() {
    bool is_google = search::DefaultSearchProviderIsGoogle(service_);
    const GURL google_base_url =
        GURL(service_->search_terms_data().GoogleBaseURLValue());
    base::DictionaryValue config_data;
    config_data.Set("translatedStrings", GetTranslatedStrings(is_google));
    config_data.SetBoolean("isGooglePage", is_google);
    config_data.SetString("googleBaseUrl", google_base_url.spec());
    config_data.SetBoolean("isAccessibleBrowser",
                           content::BrowserAccessibilityState::GetInstance()
                               ->IsAccessibleBrowser());
    config_data.SetBoolean(
        "isDarkModeEnabled",
        ui::NativeTheme::GetInstanceForNativeUi()->SystemDarkModeEnabled());

    // Serialize the dictionary.
    std::string js_text;
    JSONStringValueSerializer serializer(&js_text);
    serializer.Serialize(config_data);

    config_data_js_ = "var configData = ";
    config_data_js_.append(js_text);
    config_data_js_.append(";");

    std::string config_sha256 = crypto::SHA256HashString(config_data_js_);
    base::Base64Encode(config_sha256, &config_data_integrity_);
  }

  void OnTemplateURLServiceChanged() override {
    // The search provider may have changed, keep the config data valid.
    UpdateConfigData();
  }

  void OnTemplateURLServiceShuttingDown() override {
    service_->RemoveObserver(this);
    service_ = nullptr;
  }

  TemplateURLService* service_;

  std::string config_data_js_;
  std::string config_data_integrity_;
};

class LocalNtpSource::DesktopLogoObserver {
 public:
  DesktopLogoObserver() : weak_ptr_factory_(this) {}

  // Get the cached logo.
  void GetCachedLogo(LogoService* service,
                     const content::URLDataSource::GotDataCallback& callback) {
    StartGetLogo(service, callback, /*from_cache=*/true);
  }

  // Get the fresh logo corresponding to a previous request for a cached logo.
  // If that previous request is still ongoing, then schedule the callback to be
  // called when the fresh logo comes in. If it's not, then start a new request
  // and schedule the cached logo to be handed back.
  //
  // Strictly speaking, it's not a "fresh" logo anymore, but it should be the
  // same logo that would have been fresh relative to the corresponding cached
  // request, or perhaps one newer.
  void GetFreshLogo(LogoService* service,
                    int requested_version,
                    const content::URLDataSource::GotDataCallback& callback) {
    bool from_cache = (requested_version <= version_finished_);
    StartGetLogo(service, callback, from_cache);
  }

 private:
  void OnLogoAvailable(const content::URLDataSource::GotDataCallback& callback,
                       LogoCallbackReason type,
                       const base::Optional<EncodedLogo>& logo) {
    scoped_refptr<base::RefCountedString> response;
    auto ddl = std::make_unique<base::DictionaryValue>();
    ddl->SetInteger("v", version_started_);
    if (type == LogoCallbackReason::DETERMINED) {
      ddl->SetBoolean("usable", true);
      if (logo.has_value()) {
        ddl->SetString("image", ConvertLogoImageToBase64(logo.value()));
        ddl->Set("metadata", ConvertLogoMetadataToDict(logo->metadata));
      } else {
        ddl->SetKey("image", base::Value());
        ddl->SetKey("metadata", base::Value());
      }
    } else {
      ddl->SetBoolean("usable", false);
    }

    std::string js;
    base::JSONWriter::Write(*ddl, &js);
    js = "var ddl = " + js + ";";
    response = base::RefCountedString::TakeString(&js);
    callback.Run(response);
  }

  void OnCachedLogoAvailable(
      const content::URLDataSource::GotDataCallback& callback,
      LogoCallbackReason type,
      const base::Optional<EncodedLogo>& logo) {
    OnLogoAvailable(callback, type, logo);
  }

  void OnFreshLogoAvailable(
      const content::URLDataSource::GotDataCallback& callback,
      LogoCallbackReason type,
      const base::Optional<EncodedLogo>& logo) {
    OnLogoAvailable(callback, type, logo);
    OnRequestCompleted(type, logo);
  }

  void OnRequestCompleted(LogoCallbackReason type,
                          const base::Optional<EncodedLogo>& logo) {
    version_finished_ = version_started_;
  }

  void StartGetLogo(LogoService* service,
                    const content::URLDataSource::GotDataCallback& callback,
                    bool from_cache) {
    EncodedLogoCallback cached, fresh;
    LogoCallbacks callbacks;
    if (from_cache) {
      callbacks.on_cached_encoded_logo_available =
          base::BindOnce(&DesktopLogoObserver::OnCachedLogoAvailable,
                         weak_ptr_factory_.GetWeakPtr(), callback);
      callbacks.on_fresh_encoded_logo_available =
          base::BindOnce(&DesktopLogoObserver::OnRequestCompleted,
                         weak_ptr_factory_.GetWeakPtr());
    } else {
      callbacks.on_fresh_encoded_logo_available =
          base::BindOnce(&DesktopLogoObserver::OnFreshLogoAvailable,
                         weak_ptr_factory_.GetWeakPtr(), callback);
    }
    if (!observing()) {
      ++version_started_;
    }
    service->GetLogo(std::move(callbacks));
  }

  bool observing() const {
    DCHECK_LE(version_finished_, version_started_);
    DCHECK_LE(version_started_, version_finished_ + 1);
    return version_started_ != version_finished_;
  }

  int version_started_ = 0;
  int version_finished_ = 0;

  base::WeakPtrFactory<DesktopLogoObserver> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(DesktopLogoObserver);
};

LocalNtpSource::LocalNtpSource(Profile* profile)
    : profile_(profile),
      ntp_background_service_(
          NtpBackgroundServiceFactory::GetForProfile(profile_)),
      ntp_background_service_observer_(this),
      one_google_bar_service_(
          OneGoogleBarServiceFactory::GetForProfile(profile_)),
      one_google_bar_service_observer_(this),
      promo_service_(PromoServiceFactory::GetForProfile(profile_)),
      promo_service_observer_(this),
      search_suggest_service_(
          SearchSuggestServiceFactory::GetForProfile(profile_)),
      search_suggest_service_observer_(this),
      logo_service_(nullptr),
      weak_ptr_factory_(this) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // |ntp_background_service_| is null in incognito, or when the feature is
  // disabled.
  if (ntp_background_service_)
    ntp_background_service_observer_.Add(ntp_background_service_);

  // |one_google_bar_service_| is null in incognito, or when the feature is
  // disabled.
  if (one_google_bar_service_)
    one_google_bar_service_observer_.Add(one_google_bar_service_);

  // |search_suggest_service_| is null in incognito, or when the feature is
  // disabled.
  if (search_suggest_service_)
    search_suggest_service_observer_.Add(search_suggest_service_);

  // |promo_service_| is null in incognito, or when the feature is
  // disabled.
  if (promo_service_)
    promo_service_observer_.Add(promo_service_);

  if (base::FeatureList::IsEnabled(features::kDoodlesOnLocalNtp)) {
    logo_service_ = LogoServiceFactory::GetForProfile(profile_);
    logo_observer_ = std::make_unique<DesktopLogoObserver>();
  }

  TemplateURLService* template_url_service =
      TemplateURLServiceFactory::GetForProfile(profile_);
  if (template_url_service) {
    search_config_provider_ =
        std::make_unique<SearchConfigurationProvider>(template_url_service);
  }
}

LocalNtpSource::~LocalNtpSource() = default;

std::string LocalNtpSource::GetSource() const {
  return chrome::kChromeSearchLocalNtpHost;
}

void LocalNtpSource::StartDataRequest(
    const std::string& path,
    const content::ResourceRequestInfo::WebContentsGetter& wc_getter,
    const content::URLDataSource::GotDataCallback& callback) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  std::string stripped_path = StripParameters(path);
  if (stripped_path == kConfigDataFilename) {
    std::string config_data_js = search_config_provider_->config_data_js();
    callback.Run(base::RefCountedString::TakeString(&config_data_js));
    return;
  }
  if (stripped_path == kThemeCSSFilename) {
    std::string theme_css = GetThemeCSS(profile_);
    callback.Run(base::RefCountedString::TakeString(&theme_css));
    return;
  }

  if (stripped_path == chrome::kChromeSearchLocalNtpBackgroundFilename) {
    base::PostTaskWithTraitsAndReplyWithResult(
        FROM_HERE, {base::TaskPriority::USER_VISIBLE, base::MayBlock()},
        base::BindOnce(&ReadBackgroundImageData, profile_->GetPath()),
        base::BindOnce(&ServeBackgroundImageData, callback));
    return;
  }

  if (stripped_path == kNtpBackgroundCollectionScriptFilename) {
    if (!ntp_background_service_) {
      callback.Run(nullptr);
      return;
    }

    std::string collection_type_param;
    GURL path_url = GURL(chrome::kChromeSearchLocalNtpUrl).Resolve(path);
    if (net::GetValueForKeyInQuery(path_url, "collection_type",
                                   &collection_type_param) &&
        (collection_type_param == "album")) {
      ntp_background_albums_requests_.emplace_back(base::TimeTicks::Now(),
                                                   callback);
      ntp_background_service_->FetchAlbumInfo();
    } else {
      // If collection_type is not "album", default to getting collections.
      // TODO(ramyan): Explicitly require a collection_type when frontend
      //  supports it.
      ntp_background_collections_requests_.emplace_back(base::TimeTicks::Now(),
                                                        callback);
      ntp_background_service_->FetchCollectionInfo();
    }
    return;
  }

  if (stripped_path == kNtpBackgroundImageScriptFilename) {
    if (!ntp_background_service_) {
      callback.Run(nullptr);
      return;
    }
    std::string collection_type_param;
    GURL path_url = GURL(chrome::kChromeSearchLocalNtpUrl).Resolve(path);
    if (net::GetValueForKeyInQuery(path_url, "collection_type",
                                   &collection_type_param) &&
        (collection_type_param == "album")) {
      std::string album_id_param;
      std::string photo_container_id_param;
      if (!net::GetValueForKeyInQuery(path_url, "album_id", &album_id_param) ||
          !net::GetValueForKeyInQuery(path_url, "photo_container_id",
                                      &photo_container_id_param)) {
        callback.Run(nullptr);
        return;
      }
      ntp_background_photos_requests_.emplace_back(base::TimeTicks::Now(),
                                                   callback);
      ntp_background_service_->FetchAlbumPhotos(album_id_param,
                                                photo_container_id_param);
    } else {
      // If collection_type is not "album", default to getting images for a
      // collection.
      // TODO(ramyan): Explicitly require a collection_type when frontend
      // supports it.
      std::string collection_id_param;
      GURL path_url = GURL(chrome::kChromeSearchLocalNtpUrl).Resolve(path);
      if (net::GetValueForKeyInQuery(path_url, "collection_id",
                                     &collection_id_param)) {
        ntp_background_image_info_requests_.emplace_back(base::TimeTicks::Now(),
                                                         callback);
        ntp_background_service_->FetchCollectionImageInfo(collection_id_param);
      } else {
        callback.Run(nullptr);
      }
    }
    return;
  }

  if (stripped_path == kOneGoogleBarScriptFilename) {
    if (!one_google_bar_service_) {
      callback.Run(nullptr);
      return;
    }

    one_google_bar_requests_.emplace_back(base::TimeTicks::Now(), callback);
    one_google_bar_service_->Refresh();

    return;
  }

  if (stripped_path == kPromoScriptFilename) {
    if (!promo_service_) {
      callback.Run(nullptr);
      return;
    }

    // TODO(crbug/909931): There's no need to fetch the promo on each load,
    // we can sometimes use cached data.
    promo_requests_.emplace_back(base::TimeTicks::Now(), callback);
    promo_service_->Refresh();

    return;
  }

  if (stripped_path == kSearchSuggestionsScriptFilename) {
    if (!search_suggest_service_) {
      callback.Run(nullptr);
      return;
    }

    MaybeServeSearchSuggestions(callback);

    search_suggest_requests_.emplace_back(base::TimeTicks::Now());
    search_suggest_service_->Refresh();

    return;
  }

  if (stripped_path == kDoodleScriptFilename) {
    if (!logo_service_) {
      callback.Run(nullptr);
      return;
    }

    std::string version_string;
    int version = 0;
    GURL url = GURL(chrome::kChromeSearchLocalNtpUrl).Resolve(path);
    if (net::GetValueForKeyInQuery(url, "v", &version_string) &&
        base::StringToInt(version_string, &version)) {
      logo_observer_->GetFreshLogo(logo_service_, version, callback);
    } else {
      logo_observer_->GetCachedLogo(logo_service_, callback);
    }
    return;
  }

#if !defined(GOOGLE_CHROME_BUILD)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kLocalNtpReload)) {
    if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" ||
        stripped_path == "local-ntp.css" || stripped_path == "voice.js" ||
        stripped_path == "voice.css") {
      base::ReplaceChars(stripped_path, "-", "_", &stripped_path);
      local_ntp::SendLocalFileResource(stripped_path, callback);
      return;
    }
  }
#endif  // !defined(GOOGLE_CHROME_BUILD)

  if (stripped_path == kMainHtmlFilename) {
    std::string html = ui::ResourceBundle::GetSharedInstance()
                           .GetRawDataResource(IDR_LOCAL_NTP_HTML)
                           .as_string();

    std::string animations_integrity =
        base::StringPrintf(kIntegrityFormat, ANIMATIONS_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{ANIMATIONS_INTEGRITY}}",
                                           animations_integrity);

    std::string config_data_integrity = base::StringPrintf(
        kIntegrityFormat,
        search_config_provider_->config_data_integrity().c_str());
    base::ReplaceFirstSubstringAfterOffset(
        &html, 0, "{{CONFIG_DATA_INTEGRITY}}", config_data_integrity);

    std::string custom_bg_integrity =
        base::StringPrintf(kIntegrityFormat, CUSTOM_BACKGROUNDS_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(
        &html, 0, "{{LOCAL_NTP_CUSTOM_BG_INTEGRITY}}", custom_bg_integrity);

    std::string doodles_integrity =
        base::StringPrintf(kIntegrityFormat, DOODLES_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{DOODLES_INTEGRITY}}",
                                           doodles_integrity);

    std::string local_ntp_integrity =
        base::StringPrintf(kIntegrityFormat, LOCAL_NTP_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{LOCAL_NTP_INTEGRITY}}",
                                           local_ntp_integrity);

    std::string utils_integrity =
        base::StringPrintf(kIntegrityFormat, UTILS_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{UTILS_INTEGRITY}}",
                                           utils_integrity);

    std::string voice_integrity =
        base::StringPrintf(kIntegrityFormat, VOICE_JS_INTEGRITY);
    base::ReplaceFirstSubstringAfterOffset(
        &html, 0, "{{LOCAL_NTP_VOICE_INTEGRITY}}", voice_integrity);

    base::ReplaceFirstSubstringAfterOffset(
        &html, 0, "{{CONTENT_SECURITY_POLICY}}", GetContentSecurityPolicy());

    std::string force_doodle_param;
    GURL path_url = GURL(chrome::kChromeSearchLocalNtpUrl).Resolve(path);
    if (net::GetValueForKeyInQuery(path_url, "force-doodle",
                                   &force_doodle_param)) {
      base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

      command_line->AppendSwitchASCII(
          search_provider_logos::switches::kGoogleDoodleUrl,
          "https://www.gstatic.com/chrome/ntp/doodle_test/ddljson_desktop" +
              force_doodle_param + ".json");
    }

    callback.Run(base::RefCountedString::TakeString(&html));
    return;
  }

  float scale = 1.0f;
  std::string filename;
  webui::ParsePathAndScale(
      GURL(GetLocalNtpPath() + stripped_path), &filename, &scale);
  ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale);

  for (size_t i = 0; i < base::size(kResources); ++i) {
    if (filename == kResources[i].filename) {
      scoped_refptr<base::RefCountedMemory> response(
          ui::ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
              kResources[i].identifier, scale_factor));
      callback.Run(response.get());
      return;
    }
  }
  callback.Run(nullptr);
}

std::string LocalNtpSource::GetMimeType(
    const std::string& path) const {
  const std::string stripped_path = StripParameters(path);
  for (size_t i = 0; i < base::size(kResources); ++i) {
    if (stripped_path == kResources[i].filename)
      return kResources[i].mime_type;
  }
  return std::string();
}

bool LocalNtpSource::AllowCaching() const {
  // Some resources served by LocalNtpSource, i.e. config.js, are dynamically
  // generated and could differ on each access. To avoid using old cached
  // content on reload, disallow caching here. Otherwise, it fails to reflect
  // newly revised user configurations in the page.
  return false;
}

bool LocalNtpSource::ShouldServiceRequest(
    const GURL& url,
    content::ResourceContext* resource_context,
    int render_process_id) const {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  return ShouldServiceRequestIOThread(url, resource_context, render_process_id);
}

bool LocalNtpSource::ShouldAddContentSecurityPolicy() const {
  // The Content Security Policy is served as a meta tag in local NTP html.
  // We disable the HTTP Header version here to avoid a conflicting policy. See
  // GetContentSecurityPolicy.
  return false;
}

std::string LocalNtpSource::GetContentSecurityPolicy() const {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
#if !defined(GOOGLE_CHROME_BUILD)
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if (command_line->HasSwitch(switches::kLocalNtpReload)) {
    // While live-editing the local NTP files, turn off CSP.
    return "script-src * 'unsafe-inline';";
  }
#endif  // !defined(GOOGLE_CHROME_BUILD)

  GURL google_base_url = google_util::CommandLineGoogleBaseURL();

  // Allow embedding of the most visited iframe, as well as the account
  // switcher and the notifications dropdown from the One Google Bar, and/or
  // the iframe for interactive Doodles.
  std::string child_src_csp = base::StringPrintf(
      "child-src %s https://*.google.com/ %s;",
      chrome::kChromeSearchMostVisitedUrl, google_base_url.spec().c_str());

  // Restrict scripts in the main page to those listed here. However,
  // 'strict-dynamic' allows those scripts to load dependencies not listed here.
  std::string script_src_csp = base::StringPrintf(
      "script-src 'strict-dynamic' 'sha256-%s' 'sha256-%s' 'sha256-%s' "
      "'sha256-%s' 'sha256-%s' 'sha256-%s' 'sha256-%s';",
      ANIMATIONS_JS_INTEGRITY, CUSTOM_BACKGROUNDS_JS_INTEGRITY,
      DOODLES_JS_INTEGRITY, LOCAL_NTP_JS_INTEGRITY, UTILS_JS_INTEGRITY,
      VOICE_JS_INTEGRITY,
      search_config_provider_->config_data_integrity().c_str());

  return GetContentSecurityPolicyObjectSrc() +
         GetContentSecurityPolicyStyleSrc() + GetContentSecurityPolicyImgSrc() +
         child_src_csp + script_src_csp;
}

void LocalNtpSource::OnCollectionInfoAvailable() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (ntp_background_collections_requests_.empty())
    return;

  std::string js_errors =
      "var coll_errors = " +
      GetErrorDict(ntp_background_service_->collection_error_info());

  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(
      ConvertCollectionInfoToDict(ntp_background_service_->collection_info()),
      &js);
  js = "var coll = " + js + "; " + js_errors;
  result = base::RefCountedString::TakeString(&js);

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : ntp_background_collections_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES(
        "NewTabPage.BackgroundService.Collections.RequestLatency", delta);
    // Any response where no collections are returned is considered a failure.
    if (ntp_background_service_->collection_info().empty()) {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.BackgroundService.Collections.RequestLatency.Failure",
          delta);
    } else {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.BackgroundService.Collections.RequestLatency.Success",
          delta);
    }
  }
  ntp_background_collections_requests_.clear();
}

void LocalNtpSource::OnCollectionImagesAvailable() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (ntp_background_image_info_requests_.empty())
    return;

  std::string js_errors =
      "var coll_img_errors = " +
      GetErrorDict(ntp_background_service_->collection_images_error_info());

  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(ConvertCollectionImageToDict(
                              ntp_background_service_->collection_images()),
                          &js);
  js = "var coll_img = " + js + "; " + js_errors;
  result = base::RefCountedString::TakeString(&js);

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : ntp_background_image_info_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES(
        "NewTabPage.BackgroundService.Images.RequestLatency", delta);
    // Any response where no images are returned is considered a failure.
    if (ntp_background_service_->collection_images().empty()) {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.BackgroundService.Images.RequestLatency.Failure", delta);
    } else {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.BackgroundService.Images.RequestLatency.Success", delta);
    }
  }
  ntp_background_image_info_requests_.clear();
}

void LocalNtpSource::OnAlbumInfoAvailable() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (ntp_background_albums_requests_.empty())
    return;

  std::string js_errors =
      "var albums_errors = " +
      GetErrorDict(ntp_background_service_->album_error_info());

  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(
      ConvertAlbumInfoToDict(ntp_background_service_->album_info()), &js);
  js = "var albums = " + js + "; " + js_errors;
  result = base::RefCountedString::TakeString(&js);

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : ntp_background_albums_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES(
        "NewTabPage.BackgroundService.Albums.RequestLatency", delta);
    // TODO(ramyan): Define and capture latency for failed requests.
  }
  ntp_background_albums_requests_.clear();
}

void LocalNtpSource::OnAlbumPhotosAvailable() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (ntp_background_photos_requests_.empty())
    return;

  std::string js_errors =
      "var photos_errors = " +
      GetErrorDict(ntp_background_service_->album_photos_error_info());

  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(
      ConvertAlbumPhotosToDict(ntp_background_service_->album_photos()), &js);
  js = "var photos = " + js + "; " + js_errors;
  result = base::RefCountedString::TakeString(&js);

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : ntp_background_photos_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES(
        "NewTabPage.BackgroundService.Photos.RequestLatency", delta);
    // TODO(ramyan): Define and capture latency for failed requests.
  }
  ntp_background_photos_requests_.clear();
}

void LocalNtpSource::OnNtpBackgroundServiceShuttingDown() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ntp_background_service_observer_.RemoveAll();
  ntp_background_service_ = nullptr;
}

void LocalNtpSource::OnOneGoogleBarDataUpdated() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ServeOneGoogleBar(one_google_bar_service_->one_google_bar_data());
}

void LocalNtpSource::OnOneGoogleBarServiceShuttingDown() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  one_google_bar_service_observer_.RemoveAll();
  one_google_bar_service_ = nullptr;
}

void LocalNtpSource::OnPromoDataUpdated() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ServePromo(promo_service_->promo_data());
}

void LocalNtpSource::OnPromoServiceShuttingDown() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  promo_service_observer_.RemoveAll();
  promo_service_ = nullptr;
}

void LocalNtpSource::OnSearchSuggestDataUpdated() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  SearchSuggestLoader::Status result =
      search_suggest_service_->search_suggest_status();
  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : search_suggest_requests_) {
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.SearchSuggestions.RequestLatency",
                               delta);
    SearchSuggestionsRequestStatus request_status =
        SearchSuggestionsRequestStatus::UNKNOWN_ERROR;

    if (result == SearchSuggestLoader::Status::SIGNED_OUT) {
      request_status = SearchSuggestionsRequestStatus::SIGNED_OUT;
    } else if (result == SearchSuggestLoader::Status::OPTED_OUT) {
      request_status = SearchSuggestionsRequestStatus::OPTED_OUT;
    } else if (result == SearchSuggestLoader::Status::IMPRESSION_CAP) {
      request_status = SearchSuggestionsRequestStatus::IMPRESSION_CAP;
    } else if (result == SearchSuggestLoader::Status::REQUESTS_FROZEN) {
      request_status = SearchSuggestionsRequestStatus::FROZEN;
    } else if (result == SearchSuggestLoader::Status::OK) {
      request_status = SearchSuggestionsRequestStatus::SENT;
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.SearchSuggestions.RequestLatency.Success", delta);
    } else if (result == SearchSuggestLoader::Status::FATAL_ERROR) {
      request_status = SearchSuggestionsRequestStatus::FATAL_ERROR;
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.SearchSuggestions.RequestLatency.Failure", delta);
    }
    UMA_HISTOGRAM_ENUMERATION("NewTabPage.SearchSuggestions.RequestStatus",
                              request_status);
  }
  search_suggest_requests_.clear();
}

void LocalNtpSource::OnSearchSuggestServiceShuttingDown() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  search_suggest_service_observer_.RemoveAll();
  search_suggest_service_ = nullptr;
}
void LocalNtpSource::MaybeServeSearchSuggestions(
    const content::URLDataSource::GotDataCallback& callback) {
  base::Optional<SearchSuggestData> data =
      search_suggest_service_->search_suggest_data();

  search_suggest_service_->SuggestionsDisplayed();
  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(*ConvertSearchSuggestDataToDict(data), &js);
  js = "var search_suggestions  = " + js + ";";
  result = base::RefCountedString::TakeString(&js);
  callback.Run(result);
}

void LocalNtpSource::ServeOneGoogleBar(
    const base::Optional<OneGoogleBarData>& data) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (one_google_bar_requests_.empty())
    return;

  scoped_refptr<base::RefCountedString> result;
  if (data.has_value()) {
    std::string js;
    base::JSONWriter::Write(*ConvertOGBDataToDict(*data), &js);
    js = "var og = " + js + ";";
    result = base::RefCountedString::TakeString(&js);
  }

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : one_google_bar_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.OneGoogleBar.RequestLatency", delta);
    if (result) {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.OneGoogleBar.RequestLatency.Success", delta);
    } else {
      UMA_HISTOGRAM_MEDIUM_TIMES(
          "NewTabPage.OneGoogleBar.RequestLatency.Failure", delta);
    }
  }
  one_google_bar_requests_.clear();
}

void LocalNtpSource::ServePromo(const base::Optional<PromoData>& data) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  if (promo_requests_.empty())
    return;

  scoped_refptr<base::RefCountedString> result;
  std::string js;
  base::JSONWriter::Write(*ConvertPromoDataToDict(data), &js);
  js = "var promo = " + js + ";";
  result = base::RefCountedString::TakeString(&js);

  base::TimeTicks now = base::TimeTicks::Now();
  for (const auto& request : promo_requests_) {
    request.callback.Run(result);
    base::TimeDelta delta = now - request.start_time;
    UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Promos.RequestLatency", delta);
    if (result) {
      UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Promos.RequestLatency.Success",
                                 delta);
    } else {
      UMA_HISTOGRAM_MEDIUM_TIMES("NewTabPage.Promos.RequestLatency.Failure",
                                 delta);
    }
  }
  promo_requests_.clear();
}

LocalNtpSource::NtpBackgroundRequest::NtpBackgroundRequest(
    base::TimeTicks start_time,
    const content::URLDataSource::GotDataCallback& callback)
    : start_time(start_time), callback(callback) {}

LocalNtpSource::NtpBackgroundRequest::NtpBackgroundRequest(
    const NtpBackgroundRequest&) = default;

LocalNtpSource::NtpBackgroundRequest::~NtpBackgroundRequest() = default;

LocalNtpSource::OneGoogleBarRequest::OneGoogleBarRequest(
    base::TimeTicks start_time,
    const content::URLDataSource::GotDataCallback& callback)
    : start_time(start_time), callback(callback) {}

LocalNtpSource::OneGoogleBarRequest::OneGoogleBarRequest(
    const OneGoogleBarRequest&) = default;

LocalNtpSource::OneGoogleBarRequest::~OneGoogleBarRequest() = default;

LocalNtpSource::PromoRequest::PromoRequest(
    base::TimeTicks start_time,
    const content::URLDataSource::GotDataCallback& callback)
    : start_time(start_time), callback(callback) {}

LocalNtpSource::PromoRequest::PromoRequest(const PromoRequest&) = default;

LocalNtpSource::PromoRequest::~PromoRequest() = default;

LocalNtpSource::SearchSuggestRequest::SearchSuggestRequest(
    base::TimeTicks start_time)
    : start_time(start_time) {}

LocalNtpSource::SearchSuggestRequest::SearchSuggestRequest(
    const SearchSuggestRequest&) = default;

LocalNtpSource::SearchSuggestRequest::~SearchSuggestRequest() = default;
