// Copyright 2016 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 "components/ntp_tiles/icon_cacher_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "components/favicon/core/favicon_server_fetcher_params.h"
#include "components/favicon/core/favicon_service.h"
#include "components/favicon/core/favicon_util.h"
#include "components/favicon/core/large_icon_service.h"
#include "components/favicon_base/fallback_icon_style.h"
#include "components/favicon_base/favicon_types.h"
#include "components/favicon_base/favicon_util.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/image_fetcher/core/image_fetcher.h"
#include "components/ntp_tiles/constants.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/image/image.h"
#include "url/gurl.h"

namespace ntp_tiles {

namespace {

constexpr int kDesiredFrameSize = 128;

// TODO(jkrcal): Make the size in dip and the scale factor be passed as
// arguments from the UI so that we desire for the right size on a given device.
// See crbug.com/696563.
constexpr int kDefaultTileIconMinSizePx = 1;
constexpr int kDefaultTileIconDesiredSizePx = 96;

const char kImageFetcherUmaClient[] = "IconCacher";

constexpr char kTileIconMinSizePxFieldParam[] = "min_size";
constexpr char kTileIconDesiredSizePxFieldParam[] = "desired_size";

favicon_base::IconType IconType(const PopularSites::Site& site) {
  return site.large_icon_url.is_valid() ? favicon_base::IconType::kTouchIcon
                                        : favicon_base::IconType::kFavicon;
}

const GURL& IconURL(const PopularSites::Site& site) {
  return site.large_icon_url.is_valid() ? site.large_icon_url
                                        : site.favicon_url;
}

bool HasResultDefaultBackgroundColor(
    const favicon_base::LargeIconResult& result) {
  if (!result.fallback_icon_style) {
    return false;
  }
  return result.fallback_icon_style->is_default_background_color;
}

int GetMinimumFetchingSizeForChromeSuggestionsFaviconsFromServer() {
  return base::GetFieldTrialParamByFeatureAsInt(
      kNtpMostLikelyFaviconsFromServerFeature, kTileIconMinSizePxFieldParam,
      kDefaultTileIconMinSizePx);
}

int GetDesiredFetchingSizeForChromeSuggestionsFaviconsFromServer() {
  return base::GetFieldTrialParamByFeatureAsInt(
      kNtpMostLikelyFaviconsFromServerFeature, kTileIconDesiredSizePxFieldParam,
      kDefaultTileIconDesiredSizePx);
}

}  // namespace

IconCacherImpl::IconCacherImpl(
    favicon::FaviconService* favicon_service,
    favicon::LargeIconService* large_icon_service,
    std::unique_ptr<image_fetcher::ImageFetcher> image_fetcher)
    : favicon_service_(favicon_service),
      large_icon_service_(large_icon_service),
      image_fetcher_(std::move(image_fetcher)),
      weak_ptr_factory_(this) {
}

IconCacherImpl::~IconCacherImpl() = default;

void IconCacherImpl::StartFetchPopularSites(
    PopularSites::Site site,
    const base::Closure& icon_available,
    const base::Closure& preliminary_icon_available) {
  // Copy values from |site| before it is moved.
  GURL site_url = site.url;
  if (!StartRequest(site_url, icon_available)) {
    return;
  }

  favicon_base::IconType icon_type = IconType(site);
  favicon::GetFaviconImageForPageURL(
      favicon_service_, site_url, icon_type,
      base::Bind(&IconCacherImpl::OnGetFaviconImageForPageURLFinished,
                 base::Unretained(this), std::move(site),
                 preliminary_icon_available),
      &tracker_);
}

void IconCacherImpl::OnGetFaviconImageForPageURLFinished(
    PopularSites::Site site,
    const base::Closure& preliminary_icon_available,
    const favicon_base::FaviconImageResult& result) {
  if (!result.image.IsEmpty()) {
    FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
    return;
  }

  std::unique_ptr<CancelableImageCallback> preliminary_callback =
      MaybeProvideDefaultIcon(site, preliminary_icon_available);

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("icon_cacher", R"(
        semantics {
          sender: "Popular Sites New Tab Fetch"
          description:
            "Chrome may display a list of regionally-popular web sites on the "
            "New Tab Page. This service fetches icons from those sites."
          trigger:
            "Whenever a popular site would be displayed, but its icon is not "
            "yet cached in the browser."
          data: "The URL for which to retrieve an icon."
          destination: WEBSITE
        }
        policy {
          cookies_allowed: NO
          setting: "This feature cannot be disabled in settings."
          policy_exception_justification: "Not implemented."
        })");
  image_fetcher::ImageFetcherParams params(traffic_annotation,
                                           kImageFetcherUmaClient);
  // For images with multiple frames, prefer one of size 128x128px.
  params.set_frame_size(gfx::Size(kDesiredFrameSize, kDesiredFrameSize));
  image_fetcher_->FetchImage(
      IconURL(site),
      base::BindOnce(&IconCacherImpl::OnPopularSitesFaviconDownloaded,
                     base::Unretained(this), site,
                     std::move(preliminary_callback)),
      std::move(params));
}

void IconCacherImpl::OnPopularSitesFaviconDownloaded(
    PopularSites::Site site,
    std::unique_ptr<CancelableImageCallback> preliminary_callback,
    const gfx::Image& fetched_image,
    const image_fetcher::RequestMetadata& metadata) {
  if (fetched_image.IsEmpty()) {
    FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/false);
    UMA_HISTOGRAM_BOOLEAN("NewTabPage.TileFaviconFetchSuccess.Popular", false);
    return;
  }

  // Avoid invoking callback about preliminary icon to be triggered. The best
  // possible icon has already been downloaded.
  if (preliminary_callback) {
    preliminary_callback->Cancel();
  }
  SaveIconForSite(site, fetched_image);
  FinishRequestAndNotifyIconAvailable(site.url, /*newly_available=*/true);
  UMA_HISTOGRAM_BOOLEAN("NewTabPage.TileFaviconFetchSuccess.Popular", true);
}

void IconCacherImpl::SaveAndNotifyDefaultIconForSite(
    const PopularSites::Site& site,
    const base::Closure& preliminary_icon_available,
    const gfx::Image& image) {
  SaveIconForSite(site, image);
  if (preliminary_icon_available) {
    preliminary_icon_available.Run();
  }
}

void IconCacherImpl::SaveIconForSite(const PopularSites::Site& site,
                                     const gfx::Image& image) {
  // Although |SetFaviconColorSpace| affects OSX only, copies of gfx::Images are
  // just copies of the reference to the image and therefore cheap.
  gfx::Image img(image);
  favicon_base::SetFaviconColorSpace(&img);

  favicon_service_->SetFavicons({site.url}, IconURL(site), IconType(site),
                                std::move(img));
}

std::unique_ptr<IconCacherImpl::CancelableImageCallback>
IconCacherImpl::MaybeProvideDefaultIcon(
    const PopularSites::Site& site,
    const base::Closure& preliminary_icon_available) {
  if (site.default_icon_resource < 0) {
    return std::unique_ptr<CancelableImageCallback>();
  }
  std::unique_ptr<CancelableImageCallback> preliminary_callback(
      new CancelableImageCallback(base::Bind(
          &IconCacherImpl::SaveAndNotifyDefaultIconForSite,
          weak_ptr_factory_.GetWeakPtr(), site, preliminary_icon_available)));
  image_fetcher_->GetImageDecoder()->DecodeImage(
      ui::ResourceBundle::GetSharedInstance()
          .GetRawDataResource(site.default_icon_resource)
          .as_string(),
      gfx::Size(kDesiredFrameSize, kDesiredFrameSize),
      preliminary_callback->callback());
  return preliminary_callback;
}

void IconCacherImpl::StartFetchMostLikely(const GURL& page_url,
                                          const base::Closure& icon_available) {
  if (!StartRequest(page_url, icon_available)) {
    return;
  }

  // Desired size 0 means that we do not want the service to resize the image
  // (as we will not use it anyway).
  large_icon_service_->GetLargeIconRawBitmapOrFallbackStyleForPageUrl(
      page_url, GetMinimumFetchingSizeForChromeSuggestionsFaviconsFromServer(),
      /*desired_size_in_pixel=*/0,
      base::Bind(&IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished,
                 weak_ptr_factory_.GetWeakPtr(), page_url),
      &tracker_);
}

void IconCacherImpl::OnGetLargeIconOrFallbackStyleFinished(
    const GURL& page_url,
    const favicon_base::LargeIconResult& result) {
  if (!HasResultDefaultBackgroundColor(result)) {
    // There is already an icon, there is nothing to do. (We should only fetch
    // for default "gray" tiles so that we never overwrite any favicon of any
    // size.)
    FinishRequestAndNotifyIconAvailable(page_url, /*newly_available=*/false);
    // Update the time when the icon was last requested - postpone thus the
    // automatic eviction of the favicon from the favicon database.
    large_icon_service_->TouchIconFromGoogleServer(result.bitmap.icon_url);
    return;
  }

  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("icon_catcher_get_large_icon", R"(
        semantics {
          sender: "Favicon Component"
          description:
            "Sends a request to a Google server to retrieve the favicon bitmap "
            "for a server-suggested most visited tile on the new tab page."
          trigger:
            "A request can be sent if Chrome does not have a favicon for a "
            "particular page and history sync is enabled."
          data: "Page URL and desired icon size."
          destination: GOOGLE_OWNED_SERVICE
        }
        policy {
          cookies_allowed: NO
          setting:
            "Users can disable this feature via 'History' setting under "
            "'Advanced sync settings'."
          chrome_policy {
            SyncDisabled {
              policy_options {mode: MANDATORY}
              SyncDisabled: true
            }
          }
        })");
  large_icon_service_
      ->GetLargeIconOrFallbackStyleFromGoogleServerSkippingLocalCache(
          favicon::FaviconServerFetcherParams::CreateForMobile(
              page_url,
              GetMinimumFetchingSizeForChromeSuggestionsFaviconsFromServer(),
              GetDesiredFetchingSizeForChromeSuggestionsFaviconsFromServer()),
          /*may_page_url_be_private=*/true, traffic_annotation,
          base::Bind(&IconCacherImpl::OnMostLikelyFaviconDownloaded,
                     weak_ptr_factory_.GetWeakPtr(), page_url));
}

void IconCacherImpl::OnMostLikelyFaviconDownloaded(
    const GURL& request_url,
    favicon_base::GoogleFaviconServerRequestStatus status) {
  UMA_HISTOGRAM_ENUMERATION(
      "NewTabPage.TileFaviconFetchStatus.Server", status,
      favicon_base::GoogleFaviconServerRequestStatus::COUNT);
  FinishRequestAndNotifyIconAvailable(
      request_url,
      status == favicon_base::GoogleFaviconServerRequestStatus::SUCCESS);
}

bool IconCacherImpl::StartRequest(const GURL& request_url,
                                  const base::Closure& icon_available) {
  bool in_flight = in_flight_requests_.count(request_url) > 0;
  in_flight_requests_[request_url].push_back(icon_available);
  return !in_flight;
}

void IconCacherImpl::FinishRequestAndNotifyIconAvailable(
    const GURL& request_url,
    bool newly_available) {
  std::vector<base::Closure> callbacks =
      std::move(in_flight_requests_[request_url]);
  in_flight_requests_.erase(request_url);
  if (!newly_available) {
    return;
  }
  for (const base::Closure& callback : callbacks) {
    if (callback) {
      callback.Run();
    }
  }
}

}  // namespace ntp_tiles
