// Copyright 2017 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/search_provider_logos/logo_service_impl.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/post_task.h"
#include "base/task_runner_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_clock.h"
#include "build/build_config.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url_service.h"
#include "components/search_provider_logos/features.h"
#include "components/search_provider_logos/fixed_logo_api.h"
#include "components/search_provider_logos/google_logo_api.h"
#include "components/search_provider_logos/logo_cache.h"
#include "components/search_provider_logos/logo_observer.h"
#include "components/search_provider_logos/switches.h"
#include "net/http/http_status_code.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "ui/gfx/image/image.h"

namespace search_provider_logos {
namespace {

const int64_t kMaxDownloadBytes = 1024 * 1024;
const int kDecodeLogoTimeoutSeconds = 30;

// Implements a callback for image_fetcher::ImageDecoder. If Run() is called on
// a callback returned by GetCallback() within 30 seconds, forwards the decoded
// image to the wrapped callback. If not, sends an empty image to the wrapped
// callback instead. Either way, deletes the object and prevents further calls.
//
// TODO(sfiera): find a more idiomatic way of setting a deadline on the
// callback. This is implemented as a self-deleting object in part because it
// needed to when it used to be a delegate and in part because I couldn't figure
// out a better way, now that it isn't.
class ImageDecodedHandlerWithTimeout {
 public:
  static base::RepeatingCallback<void(const gfx::Image&)> Wrap(
      const base::RepeatingCallback<void(const SkBitmap&)>&
          image_decoded_callback) {
    auto* handler = new ImageDecodedHandlerWithTimeout(image_decoded_callback);
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE,
        base::BindOnce(&ImageDecodedHandlerWithTimeout::OnImageDecoded,
                       handler->weak_ptr_factory_.GetWeakPtr(), gfx::Image()),
        base::TimeDelta::FromSeconds(kDecodeLogoTimeoutSeconds));
    return base::BindRepeating(&ImageDecodedHandlerWithTimeout::OnImageDecoded,
                               handler->weak_ptr_factory_.GetWeakPtr());
  }

 private:
  explicit ImageDecodedHandlerWithTimeout(
      const base::RepeatingCallback<void(const SkBitmap&)>&
          image_decoded_callback)
      : image_decoded_callback_(image_decoded_callback),
        weak_ptr_factory_(this) {}

  void OnImageDecoded(const gfx::Image& decoded_image) {
    image_decoded_callback_.Run(decoded_image.AsBitmap());
    delete this;
  }

  base::RepeatingCallback<void(const SkBitmap&)> image_decoded_callback_;
  base::WeakPtrFactory<ImageDecodedHandlerWithTimeout> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ImageDecodedHandlerWithTimeout);
};

void ObserverOnLogoAvailable(LogoObserver* observer,
                             bool from_cache,
                             LogoCallbackReason type,
                             const base::Optional<Logo>& logo) {
  switch (type) {
    case LogoCallbackReason::DISABLED:
    case LogoCallbackReason::CANCELED:
    case LogoCallbackReason::FAILED:
      break;

    case LogoCallbackReason::REVALIDATED:
      // TODO(sfiera): double-check whether we should inform the observer of the
      // fresh metadata.
      break;

    case LogoCallbackReason::DETERMINED:
      observer->OnLogoAvailable(logo ? &logo.value() : nullptr, from_cache);
      break;
  }
  if (!from_cache) {
    observer->OnObserverRemoved();
  }
}

void RunCallbacksWithDisabled(LogoCallbacks callbacks) {
  if (callbacks.on_cached_encoded_logo_available) {
    std::move(callbacks.on_cached_encoded_logo_available)
        .Run(LogoCallbackReason::DISABLED, base::nullopt);
  }
  if (callbacks.on_cached_decoded_logo_available) {
    std::move(callbacks.on_cached_decoded_logo_available)
        .Run(LogoCallbackReason::DISABLED, base::nullopt);
  }
  if (callbacks.on_fresh_encoded_logo_available) {
    std::move(callbacks.on_fresh_encoded_logo_available)
        .Run(LogoCallbackReason::DISABLED, base::nullopt);
  }
  if (callbacks.on_fresh_decoded_logo_available) {
    std::move(callbacks.on_fresh_decoded_logo_available)
        .Run(LogoCallbackReason::DISABLED, base::nullopt);
  }
}

// Returns whether the metadata for the cached logo indicates that the logo is
// OK to show, i.e. it's not expired or it's allowed to be shown temporarily
// after expiration.
bool IsLogoOkToShow(const LogoMetadata& metadata, base::Time now) {
  base::TimeDelta offset =
      base::TimeDelta::FromMilliseconds(kMaxTimeToLiveMS * 3 / 2);
  base::Time distant_past = now - offset;
  // Sanity check so logos aren't accidentally cached forever.
  if (metadata.expiration_time < distant_past) {
    return false;
  }
  return metadata.can_show_after_expiration || metadata.expiration_time >= now;
}

// Reads the logo from the cache and returns it. Returns NULL if the cache is
// empty, corrupt, expired, or doesn't apply to the current logo URL.
std::unique_ptr<EncodedLogo> GetLogoFromCacheOnFileThread(LogoCache* logo_cache,
                                                          const GURL& logo_url,
                                                          base::Time now) {
  const LogoMetadata* metadata = logo_cache->GetCachedLogoMetadata();
  if (!metadata)
    return nullptr;

  if (metadata->source_url != logo_url || !IsLogoOkToShow(*metadata, now)) {
    logo_cache->SetCachedLogo(nullptr);
    return nullptr;
  }

  return logo_cache->GetCachedLogo();
}

void NotifyAndClear(std::vector<EncodedLogoCallback>* encoded_callbacks,
                    std::vector<LogoCallback>* decoded_callbacks,
                    LogoCallbackReason type,
                    const EncodedLogo* encoded_logo,
                    const Logo* decoded_logo) {
  auto opt_encoded_logo =
      encoded_logo ? base::Optional<EncodedLogo>(*encoded_logo) : base::nullopt;
  for (EncodedLogoCallback& callback : *encoded_callbacks) {
    std::move(callback).Run(type, opt_encoded_logo);
  }
  encoded_callbacks->clear();

  auto opt_decoded_logo =
      decoded_logo ? base::Optional<Logo>(*decoded_logo) : base::nullopt;
  for (LogoCallback& callback : *decoded_callbacks) {
    std::move(callback).Run(type, opt_decoded_logo);
  }
  decoded_callbacks->clear();
}

}  // namespace

LogoServiceImpl::LogoServiceImpl(
    const base::FilePath& cache_directory,
    identity::IdentityManager* identity_manager,
    TemplateURLService* template_url_service,
    std::unique_ptr<image_fetcher::ImageDecoder> image_decoder,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    base::RepeatingCallback<bool()> want_gray_logo_getter)
    : cache_directory_(cache_directory),
      identity_manager_(identity_manager),
      template_url_service_(template_url_service),
      url_loader_factory_(url_loader_factory),
      want_gray_logo_getter_(std::move(want_gray_logo_getter)),
      image_decoder_(std::move(image_decoder)),
      is_idle_(true),
      is_cached_logo_valid_(false),
      cache_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
           base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})),
      logo_cache_(new LogoCache(cache_directory_),
                  base::OnTaskRunnerDeleter(cache_task_runner_)),
      weak_ptr_factory_(this) {
  identity_manager_->AddObserver(this);
}

LogoServiceImpl::~LogoServiceImpl() = default;

void LogoServiceImpl::Shutdown() {
  // The IdentityManager may be destroyed at any point after Shutdown,
  // so make sure we drop any references to it.
  identity_manager_->RemoveObserver(this);
  ReturnToIdle(kDownloadOutcomeNotTracked);
}

void LogoServiceImpl::GetLogo(search_provider_logos::LogoObserver* observer) {
  LogoCallbacks callbacks;
  callbacks.on_cached_decoded_logo_available =
      base::BindOnce(ObserverOnLogoAvailable, observer, true);
  callbacks.on_fresh_decoded_logo_available =
      base::BindOnce(ObserverOnLogoAvailable, observer, false);
  GetLogo(std::move(callbacks));
}

void LogoServiceImpl::GetLogo(LogoCallbacks callbacks) {
  if (!template_url_service_) {
    RunCallbacksWithDisabled(std::move(callbacks));
    return;
  }

  const TemplateURL* template_url =
      template_url_service_->GetDefaultSearchProvider();
  if (!template_url) {
    RunCallbacksWithDisabled(std::move(callbacks));
    return;
  }

  const base::CommandLine* command_line =
      base::CommandLine::ForCurrentProcess();

  GURL logo_url;
  if (command_line->HasSwitch(switches::kSearchProviderLogoURL)) {
    logo_url = GURL(
        command_line->GetSwitchValueASCII(switches::kSearchProviderLogoURL));
  } else {
#if defined(OS_ANDROID)
    // Non-Google default search engine logos are currently enabled only on
    // Android (https://crbug.com/737283).
    logo_url = template_url->logo_url();
#endif
  }

  GURL base_url;
  GURL doodle_url;
  const bool is_google = template_url->url_ref().HasGoogleBaseURLs(
      template_url_service_->search_terms_data());
  if (is_google) {
    // TODO(treib): Put the Google doodle URL into prepopulated_engines.json.
    base_url =
        GURL(template_url_service_->search_terms_data().GoogleBaseURLValue());
    doodle_url = search_provider_logos::GetGoogleDoodleURL(base_url);
  } else {
    if (command_line->HasSwitch(switches::kThirdPartyDoodleURL)) {
      doodle_url = GURL(
          command_line->GetSwitchValueASCII(switches::kThirdPartyDoodleURL));
    } else {
      doodle_url = template_url->doodle_url();
    }
    base_url = doodle_url.GetOrigin();
  }

  if (!logo_url.is_valid() && !doodle_url.is_valid()) {
    RunCallbacksWithDisabled(std::move(callbacks));
    return;
  }

  if (!clock_) {
    clock_ = base::DefaultClock::GetInstance();
  }

  const bool use_fixed_logo = !doodle_url.is_valid();
  if (use_fixed_logo) {
    SetServerAPI(
        logo_url,
        base::BindRepeating(&search_provider_logos::ParseFixedLogoResponse),
        base::BindRepeating(&search_provider_logos::UseFixedLogoUrl));
  } else {
    // We encode the type of doodle (regular or gray) in the URL so that the
    // logo cache gets cleared when that value changes.
    GURL prefilled_url = AppendPreliminaryParamsToDoodleURL(
        want_gray_logo_getter_.Run(), doodle_url);
    SetServerAPI(
        prefilled_url,
        base::Bind(&search_provider_logos::ParseDoodleLogoResponse, base_url),
        base::Bind(&search_provider_logos::AppendFingerprintParamToDoodleURL));
  }

  DCHECK(!logo_url_.is_empty());
  DCHECK(callbacks.on_cached_decoded_logo_available ||
         callbacks.on_cached_encoded_logo_available ||
         callbacks.on_fresh_decoded_logo_available ||
         callbacks.on_fresh_encoded_logo_available);

  if (callbacks.on_cached_encoded_logo_available) {
    on_cached_encoded_logo_.push_back(
        std::move(callbacks.on_cached_encoded_logo_available));
  }
  if (callbacks.on_cached_decoded_logo_available) {
    on_cached_decoded_logo_.push_back(
        std::move(callbacks.on_cached_decoded_logo_available));
  }
  if (callbacks.on_fresh_encoded_logo_available) {
    on_fresh_encoded_logo_.push_back(
        std::move(callbacks.on_fresh_encoded_logo_available));
  }
  if (callbacks.on_fresh_decoded_logo_available) {
    on_fresh_decoded_logo_.push_back(
        std::move(callbacks.on_fresh_decoded_logo_available));
  }

  if (is_idle_) {
    is_idle_ = false;

    base::PostTaskAndReplyWithResult(
        cache_task_runner_.get(), FROM_HERE,
        base::BindRepeating(&GetLogoFromCacheOnFileThread,
                            base::Unretained(logo_cache_.get()), logo_url_,
                            clock_->Now()),
        base::BindRepeating(&LogoServiceImpl::OnCachedLogoRead,
                            weak_ptr_factory_.GetWeakPtr()));
  } else if (is_cached_logo_valid_) {
    NotifyAndClear(&on_cached_encoded_logo_, &on_cached_decoded_logo_,
                   LogoCallbackReason::DETERMINED, cached_encoded_logo_.get(),
                   cached_logo_.get());
  }
}

void LogoServiceImpl::SetLogoCacheForTests(std::unique_ptr<LogoCache> cache) {
  // |logo_cache_| has a custom deleter, which makes the two unique_ptrs
  // be different types. so one can't be moved on top of the other.
  logo_cache_.reset(std::move(cache).release());
}

void LogoServiceImpl::SetClockForTests(base::Clock* clock) {
  clock_ = clock;
}

void LogoServiceImpl::SetServerAPI(
    const GURL& logo_url,
    const ParseLogoResponse& parse_logo_response_func,
    const AppendQueryparamsToLogoURL& append_queryparams_func) {
  if (logo_url == logo_url_)
    return;

  ReturnToIdle(kDownloadOutcomeNotTracked);

  logo_url_ = logo_url;
  parse_logo_response_func_ = parse_logo_response_func;
  append_queryparams_func_ = append_queryparams_func;
}

void LogoServiceImpl::ClearCachedLogo() {
  // First cancel any fetch that might be ongoing.
  ReturnToIdle(kDownloadOutcomeNotTracked);
  // Then clear any cached logo.
  SetCachedLogo(nullptr);
}

void LogoServiceImpl::ReturnToIdle(int outcome) {
  if (outcome != kDownloadOutcomeNotTracked) {
    UMA_HISTOGRAM_ENUMERATION("NewTabPage.LogoDownloadOutcome",
                              static_cast<LogoDownloadOutcome>(outcome),
                              DOWNLOAD_OUTCOME_COUNT);
  }

  // Cancel the current asynchronous operation, if any.
  loader_.reset();
  weak_ptr_factory_.InvalidateWeakPtrs();

  // Reset state.
  is_idle_ = true;
  cached_logo_.reset();
  cached_encoded_logo_.reset();
  is_cached_logo_valid_ = false;

  // Clear callbacks.
  NotifyAndClear(&on_cached_encoded_logo_, &on_cached_decoded_logo_,
                 LogoCallbackReason::CANCELED, nullptr, nullptr);
  NotifyAndClear(&on_fresh_encoded_logo_, &on_fresh_decoded_logo_,
                 LogoCallbackReason::CANCELED, nullptr, nullptr);
}

void LogoServiceImpl::OnCachedLogoRead(
    std::unique_ptr<EncodedLogo> cached_logo) {
  DCHECK(!is_idle_);

  if (cached_logo && cached_logo->encoded_image) {
    // Store the value of logo->encoded_image for use below. This ensures that
    // logo->encoded_image is evaulated before base::Passed(&logo), which sets
    // logo to NULL.
    scoped_refptr<base::RefCountedString> encoded_image =
        cached_logo->encoded_image;
    image_decoder_->DecodeImage(
        encoded_image->data(), gfx::Size(),  // No particular size desired.
        ImageDecodedHandlerWithTimeout::Wrap(base::BindRepeating(
            &LogoServiceImpl::OnCachedLogoAvailable,
            weak_ptr_factory_.GetWeakPtr(), base::Passed(&cached_logo))));
  } else if (cached_logo) {
    OnCachedLogoAvailable(std::move(cached_logo), SkBitmap());
  } else {
    OnCachedLogoAvailable({}, SkBitmap());
  }
}

void LogoServiceImpl::SetCachedLogo(std::unique_ptr<EncodedLogo> logo) {
  cache_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&LogoCache::SetCachedLogo,
                                base::Unretained(logo_cache_.get()),
                                base::Owned(logo.release())));
}

void LogoServiceImpl::SetCachedMetadata(const LogoMetadata& metadata) {
  cache_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&LogoCache::UpdateCachedLogoMetadata,
                                base::Unretained(logo_cache_.get()), metadata));
}

void LogoServiceImpl::OnCachedLogoAvailable(
    std::unique_ptr<EncodedLogo> encoded_logo,
    const SkBitmap& image) {
  DCHECK(!is_idle_);

  if (encoded_logo && encoded_logo->encoded_image && !image.isNull()) {
    cached_logo_.reset(new Logo());
    cached_logo_->metadata = encoded_logo->metadata;
    cached_logo_->image = image;
    cached_encoded_logo_ = std::move(encoded_logo);
  }
  is_cached_logo_valid_ = true;
  NotifyAndClear(&on_cached_encoded_logo_, &on_cached_decoded_logo_,
                 LogoCallbackReason::DETERMINED, cached_encoded_logo_.get(),
                 cached_logo_.get());
  FetchLogo();
}

void LogoServiceImpl::FetchLogo() {
  DCHECK(!loader_);
  DCHECK(!is_idle_);

  std::string fingerprint;
  if (cached_logo_ && !cached_logo_->metadata.fingerprint.empty() &&
      cached_logo_->metadata.expiration_time >= clock_->Now()) {
    fingerprint = cached_logo_->metadata.fingerprint;
  }
  GURL url = append_queryparams_func_.Run(logo_url_, fingerprint);
  net::NetworkTrafficAnnotationTag traffic_annotation =
      net::DefineNetworkTrafficAnnotation("logo_service", R"(
        semantics {
          sender: "Logo Service"
          description:
            "Provides the logo image (aka Doodle) if Google is your configured "
            "search provider."
          trigger: "Displaying the new tab page on iOS or Android."
          data:
            "Logo ID, and the user's Google cookies to show for example "
            "birthday doodles at appropriate times."
          destination: OTHER
        }
        policy {
          cookies_allowed: YES
          cookies_store: "user"
          setting:
            "Choosing a non-Google search engine in Chromium settings under "
            "'Search Engine' will disable this feature."
          policy_exception_justification:
            "Not implemented, considered not useful as it does not upload any"
            "data and just downloads a logo image."
        })");
  auto request = std::make_unique<network::ResourceRequest>();
  request->url = url;
  // TODO(https://crbug.com/808498) re-add data use measurement once
  // SimpleURLLoader supports it:
  // data_use_measurement::DataUseUserData::SEARCH_PROVIDER_LOGOS
  loader_ =
      network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
  loader_->DownloadToString(
      url_loader_factory_.get(),
      base::BindOnce(&LogoServiceImpl::OnURLLoadComplete,
                     base::Unretained(this), loader_.get()),
      kMaxDownloadBytes);
  logo_download_start_time_ = base::TimeTicks::Now();
}

void LogoServiceImpl::OnFreshLogoParsed(bool* parsing_failed,
                                        bool from_http_cache,
                                        std::unique_ptr<EncodedLogo> logo) {
  DCHECK(!is_idle_);

  if (logo)
    logo->metadata.source_url = logo_url_;

  if (!logo || !logo->encoded_image) {
    OnFreshLogoAvailable(std::move(logo), /*download_failed=*/false,
                         *parsing_failed, from_http_cache, SkBitmap());
  } else {
    // Store the value of logo->encoded_image for use below. This ensures that
    // logo->encoded_image is evaulated before base::Passed(&logo), which sets
    // logo to NULL.
    scoped_refptr<base::RefCountedString> encoded_image = logo->encoded_image;
    image_decoder_->DecodeImage(
        encoded_image->data(), gfx::Size(),  // No particular size desired.
        ImageDecodedHandlerWithTimeout::Wrap(base::BindRepeating(
            &LogoServiceImpl::OnFreshLogoAvailable,
            weak_ptr_factory_.GetWeakPtr(), base::Passed(&logo),
            /*download_failed=*/false, *parsing_failed, from_http_cache)));
  }
}

void LogoServiceImpl::OnFreshLogoAvailable(
    std::unique_ptr<EncodedLogo> encoded_logo,
    bool download_failed,
    bool parsing_failed,
    bool from_http_cache,
    const SkBitmap& image) {
  DCHECK(!is_idle_);

  LogoDownloadOutcome download_outcome = DOWNLOAD_OUTCOME_COUNT;
  std::unique_ptr<Logo> logo;

  if (download_failed) {
    download_outcome = DOWNLOAD_OUTCOME_DOWNLOAD_FAILED;
  } else if (encoded_logo && !encoded_logo->encoded_image && cached_logo_ &&
             !encoded_logo->metadata.fingerprint.empty() &&
             encoded_logo->metadata.fingerprint ==
                 cached_logo_->metadata.fingerprint) {
    // The cached logo was revalidated, i.e. its fingerprint was verified.
    // mime_type isn't sent when revalidating, so copy it from the cached logo.
    encoded_logo->metadata.mime_type = cached_logo_->metadata.mime_type;
    SetCachedMetadata(encoded_logo->metadata);
    download_outcome = DOWNLOAD_OUTCOME_LOGO_REVALIDATED;
  } else if (encoded_logo && encoded_logo->encoded_image && image.isNull()) {
    // Image decoding failed. Do nothing.
    download_outcome = DOWNLOAD_OUTCOME_DECODING_FAILED;
  } else if (encoded_logo && !encoded_logo->encoded_image &&
             encoded_logo->metadata.type != LogoType::INTERACTIVE) {
    download_outcome = DOWNLOAD_OUTCOME_MISSING_REQUIRED_IMAGE;
#if defined(OS_ANDROID) || defined(OS_IOS)
  } else if (encoded_logo && !encoded_logo->encoded_image) {
    // On Mobile interactive doodles require a static CTA image, on Desktop the
    // static image is not required as it's handled by the iframed page.
    download_outcome = DOWNLOAD_OUTCOME_MISSING_REQUIRED_IMAGE;
#endif
  } else {
    // Check if the server returned a valid, non-empty response.
    if (encoded_logo) {
      UMA_HISTOGRAM_BOOLEAN("NewTabPage.LogoImageDownloaded", from_http_cache);

      DCHECK(!encoded_logo->encoded_image || !image.isNull());
      logo.reset(new Logo());
      logo->metadata = encoded_logo->metadata;
      logo->image = image;
    }

    if (logo) {
      download_outcome = DOWNLOAD_OUTCOME_NEW_LOGO_SUCCESS;
    } else {
      if (parsing_failed)
        download_outcome = DOWNLOAD_OUTCOME_PARSING_FAILED;
      else
        download_outcome = DOWNLOAD_OUTCOME_NO_LOGO_TODAY;
    }
  }

  LogoCallbackReason callback_type = LogoCallbackReason::FAILED;
  switch (download_outcome) {
    case DOWNLOAD_OUTCOME_NEW_LOGO_SUCCESS:
      DCHECK(encoded_logo);
      DCHECK(logo);
      callback_type = LogoCallbackReason::DETERMINED;
      break;

    case DOWNLOAD_OUTCOME_PARSING_FAILED:
    case DOWNLOAD_OUTCOME_NO_LOGO_TODAY:
      // Clear the cached logo if it was non-null. Otherwise, report this as a
      // revalidation of "no logo".
      DCHECK(!encoded_logo);
      DCHECK(!logo);
      if (cached_logo_) {
        callback_type = LogoCallbackReason::DETERMINED;
      } else {
        callback_type = LogoCallbackReason::REVALIDATED;
      }
      break;

    case DOWNLOAD_OUTCOME_MISSING_REQUIRED_IMAGE:
    case DOWNLOAD_OUTCOME_DOWNLOAD_FAILED:
      // In the download failed, don't notify the callback at all, since the
      // callback should continue to use the cached logo.
      DCHECK(!encoded_logo || !encoded_logo->encoded_image);
      DCHECK(!logo);
      callback_type = LogoCallbackReason::FAILED;
      break;

    case DOWNLOAD_OUTCOME_DECODING_FAILED:
      DCHECK(encoded_logo);
      DCHECK(!logo);
      encoded_logo.reset();
      callback_type = LogoCallbackReason::FAILED;
      break;

    case DOWNLOAD_OUTCOME_LOGO_REVALIDATED:
      // In the server reported that the cached logo is still current, don't
      // notify the callback at all, since the callback should continue to use
      // the cached logo.
      DCHECK(encoded_logo);
      DCHECK(!logo);
      callback_type = LogoCallbackReason::REVALIDATED;
      break;

    case DOWNLOAD_OUTCOME_COUNT:
      NOTREACHED();
      return;
  }

  NotifyAndClear(&on_fresh_encoded_logo_, &on_fresh_decoded_logo_,
                 callback_type, encoded_logo.get(), logo.get());

  switch (callback_type) {
    case LogoCallbackReason::DETERMINED:
      SetCachedLogo(std::move(encoded_logo));
      break;

    default:
      break;
  }

  ReturnToIdle(download_outcome);
}

void LogoServiceImpl::OnURLLoadComplete(const network::SimpleURLLoader* source,
                                        std::unique_ptr<std::string> body) {
  DCHECK(!is_idle_);
  std::unique_ptr<network::SimpleURLLoader> cleanup_loader(loader_.release());

  if (source->NetError() != net::OK) {
    OnFreshLogoAvailable({}, /*download_failed=*/true, false, false,
                         SkBitmap());
    return;
  }

  if (!source->ResponseInfo() || !source->ResponseInfo()->headers ||
      source->ResponseInfo()->headers->response_code() != net::HTTP_OK) {
    OnFreshLogoAvailable({}, /*download_failed=*/true, false, false,
                         SkBitmap());
    return;
  }

  UMA_HISTOGRAM_TIMES("NewTabPage.LogoDownloadTime",
                      base::TimeTicks::Now() - logo_download_start_time_);

  std::unique_ptr<std::string> response =
      body ? std::move(body) : std::make_unique<std::string>();
  base::Time response_time = clock_->Now();

  bool from_http_cache = !source->ResponseInfo()->network_accessed;

  bool* parsing_failed = new bool(false);
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE,
      {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
      base::BindOnce(parse_logo_response_func_, std::move(response),
                     response_time, parsing_failed),
      base::BindOnce(&LogoServiceImpl::OnFreshLogoParsed,
                     weak_ptr_factory_.GetWeakPtr(),
                     base::Owned(parsing_failed), from_http_cache));
}

void LogoServiceImpl::OnAccountsInCookieUpdated(
    const identity::AccountsInCookieJarInfo&,
    const GoogleServiceAuthError&) {
  // Clear any cached logo, since it may be personalized (e.g. birthday Doodle).
  if (!clock_) {
    clock_ = base::DefaultClock::GetInstance();
  }
  ClearCachedLogo();
}

}  // namespace search_provider_logos
