// Copyright 2014 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 <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/test/simple_test_clock.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "components/image_fetcher/core/image_decoder.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_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/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "net/base/url_util.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image.h"

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtMost;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::Ne;
using ::testing::NiceMock;
using ::testing::Not;
using ::testing::NotNull;
using ::testing::Pointee;
using ::testing::Return;
using ::testing::StrictMock;

using sync_preferences::TestingPrefServiceSyncable;

namespace search_provider_logos {

namespace {

using MockLogoCallback = base::MockCallback<LogoCallback>;
using MockEncodedLogoCallback = base::MockCallback<EncodedLogoCallback>;

scoped_refptr<base::RefCountedString> EncodeBitmapAsPNG(
    const SkBitmap& bitmap) {
  scoped_refptr<base::RefCountedMemory> png_bytes =
      gfx::Image::CreateFrom1xBitmap(bitmap).As1xPNGBytes();
  scoped_refptr<base::RefCountedString> str = new base::RefCountedString();
  str->data().assign(png_bytes->front_as<char>(), png_bytes->size());
  return str;
}

std::string EncodeBitmapAsPNGBase64(const SkBitmap& bitmap) {
  scoped_refptr<base::RefCountedString> png_bytes = EncodeBitmapAsPNG(bitmap);
  std::string encoded_image_base64;
  base::Base64Encode(png_bytes->data(), &encoded_image_base64);
  return encoded_image_base64;
}

SkBitmap MakeBitmap(int width, int height) {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(width, height);
  bitmap.eraseColor(SK_ColorBLUE);
  return bitmap;
}

EncodedLogo EncodeLogo(const Logo& logo) {
  EncodedLogo encoded_logo;
  encoded_logo.encoded_image = EncodeBitmapAsPNG(logo.image);
  encoded_logo.metadata = logo.metadata;
  return encoded_logo;
}

Logo DecodeLogo(const EncodedLogo& encoded_logo) {
  Logo logo;
  logo.image =
      gfx::Image::CreateFrom1xPNGBytes(encoded_logo.encoded_image->front(),
                                       encoded_logo.encoded_image->size())
          .AsBitmap();
  logo.metadata = encoded_logo.metadata;
  return logo;
}

Logo GetSampleLogo(const GURL& logo_url, base::Time response_time) {
  Logo logo;
  logo.image = MakeBitmap(2, 5);
  logo.metadata.can_show_after_expiration = false;
  logo.metadata.expiration_time =
      response_time + base::TimeDelta::FromHours(19);
  logo.metadata.fingerprint = "8bc33a80";
  logo.metadata.source_url =
      AppendPreliminaryParamsToDoodleURL(false, logo_url);
  logo.metadata.on_click_url = GURL("https://www.google.com/search?q=potato");
  logo.metadata.alt_text = "A logo about potatoes";
  logo.metadata.animated_url = GURL("https://www.google.com/logos/doodle.png");
  logo.metadata.mime_type = "image/png";
  return logo;
}

Logo GetSampleLogo2(const GURL& logo_url, base::Time response_time) {
  Logo logo;
  logo.image = MakeBitmap(4, 3);
  logo.metadata.can_show_after_expiration = true;
  logo.metadata.expiration_time = base::Time();
  logo.metadata.fingerprint = "71082741021409127";
  logo.metadata.source_url =
      AppendPreliminaryParamsToDoodleURL(false, logo_url);
  logo.metadata.on_click_url = GURL("https://example.com/page25");
  logo.metadata.alt_text = "The logo for example.com";
  logo.metadata.mime_type = "image/jpeg";
  return logo;
}

std::string MakeServerResponse(const SkBitmap& image,
                               const std::string& on_click_url,
                               const std::string& alt_text,
                               const std::string& animated_url,
                               const std::string& mime_type,
                               const std::string& fingerprint,
                               base::TimeDelta time_to_live) {
  base::DictionaryValue dict;

  std::string data_uri = "data:";
  data_uri += mime_type;
  data_uri += ";base64,";
  data_uri += EncodeBitmapAsPNGBase64(image);

  dict.SetString("ddljson.target_url", on_click_url);
  dict.SetString("ddljson.alt_text", alt_text);
  if (animated_url.empty()) {
    dict.SetString("ddljson.doodle_type", "SIMPLE");
    if (!image.isNull())
      dict.SetString("ddljson.data_uri", data_uri);
  } else {
    dict.SetString("ddljson.doodle_type", "ANIMATED");
    dict.SetBoolean("ddljson.large_image.is_animated_gif", true);
    dict.SetString("ddljson.large_image.url", animated_url);
    if (!image.isNull())
      dict.SetString("ddljson.cta_data_uri", data_uri);
  }
  dict.SetString("ddljson.fingerprint", fingerprint);
  if (time_to_live != base::TimeDelta())
    dict.SetInteger("ddljson.time_to_live_ms",
                    static_cast<int>(time_to_live.InMilliseconds()));

  std::string output;
  base::JSONWriter::Write(dict, &output);
  return output;
}

std::string MakeServerResponse(const Logo& logo, base::TimeDelta time_to_live) {
  return MakeServerResponse(
      logo.image, logo.metadata.on_click_url.spec(), logo.metadata.alt_text,
      logo.metadata.animated_url.spec(), logo.metadata.mime_type,
      logo.metadata.fingerprint, time_to_live);
}

template <typename Arg, typename Matcher>
bool Match(const Arg& arg,
           const Matcher& matcher,
           ::testing::MatchResultListener* result_listener) {
  return ::testing::Matcher<Arg>(matcher).MatchAndExplain(arg, result_listener);
}

MATCHER_P(DecodesTo, decoded_logo, "") {
  return Match(DecodeLogo(arg), Eq(decoded_logo), result_listener);
}

class MockLogoCache : public LogoCache {
 public:
  MockLogoCache() : LogoCache(base::FilePath()) {
    // Delegate actions to the *Internal() methods by default.
    ON_CALL(*this, UpdateCachedLogoMetadata(_))
        .WillByDefault(
            Invoke(this, &MockLogoCache::UpdateCachedLogoMetadataInternal));
    ON_CALL(*this, GetCachedLogoMetadata())
        .WillByDefault(
            Invoke(this, &MockLogoCache::GetCachedLogoMetadataInternal));
    ON_CALL(*this, SetCachedLogo(_))
        .WillByDefault(Invoke(this, &MockLogoCache::SetCachedLogoInternal));
  }

  MOCK_METHOD1(UpdateCachedLogoMetadata, void(const LogoMetadata& metadata));
  MOCK_METHOD0(GetCachedLogoMetadata, const LogoMetadata*());
  MOCK_METHOD1(SetCachedLogo, void(const EncodedLogo* logo));
  // GetCachedLogo() can't be mocked since it returns a scoped_ptr, which is
  // non-copyable. Instead create a method that's pinged when GetCachedLogo() is
  // called.
  MOCK_METHOD0(OnGetCachedLogo, void());

  void EncodeAndSetCachedLogo(const Logo& logo) {
    EncodedLogo encoded_logo = EncodeLogo(logo);
    SetCachedLogo(&encoded_logo);
  }

  void ExpectSetCachedLogo(const Logo* expected_logo) {
    Mock::VerifyAndClearExpectations(this);
    if (expected_logo) {
      EXPECT_CALL(*this, SetCachedLogo(Pointee(DecodesTo(*expected_logo))));
    } else {
      EXPECT_CALL(*this, SetCachedLogo(nullptr));
    }
  }

  void UpdateCachedLogoMetadataInternal(const LogoMetadata& metadata) {
    ASSERT_TRUE(logo_.get());
    ASSERT_TRUE(metadata_.get());
    EXPECT_EQ(metadata_->fingerprint, metadata.fingerprint);
    metadata_.reset(new LogoMetadata(metadata));
    logo_->metadata = metadata;
  }

  const LogoMetadata* GetCachedLogoMetadataInternal() {
    return metadata_.get();
  }

  void SetCachedLogoInternal(const EncodedLogo* logo) {
    logo_ = logo ? std::make_unique<EncodedLogo>(*logo) : nullptr;
    metadata_ = logo ? std::make_unique<LogoMetadata>(logo->metadata) : nullptr;
  }

  std::unique_ptr<EncodedLogo> GetCachedLogo() override {
    OnGetCachedLogo();
    return logo_ ? std::make_unique<EncodedLogo>(*logo_) : nullptr;
  }

 private:
  std::unique_ptr<LogoMetadata> metadata_;
  std::unique_ptr<EncodedLogo> logo_;
};

class FakeImageDecoder : public image_fetcher::ImageDecoder {
 public:
  void DecodeImage(
      const std::string& image_data,
      const gfx::Size& desired_image_frame_size,
      const image_fetcher::ImageDecodedCallback& callback) override {
    gfx::Image image = gfx::Image::CreateFrom1xPNGBytes(
        reinterpret_cast<const uint8_t*>(image_data.data()), image_data.size());
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(callback, image));
  }
};

// A helper class that wraps around all the dependencies required to simulate
// signing in/out.
class SigninHelper {
 public:
  explicit SigninHelper(base::test::ScopedTaskEnvironment* task_environment)
      : task_environment_(task_environment),
        signin_client_(&pref_service_),
        token_service_(&pref_service_),
        cookie_service_(&token_service_,
                        &signin_client_,
                        &test_url_loader_factory_) {
    // GaiaCookieManagerService calls static methods of AccountTrackerService
    // which access prefs.
    AccountTrackerService::RegisterPrefs(pref_service_.registry());
  }

  GaiaCookieManagerService* cookie_service() { return &cookie_service_; }

  void SignIn() {
    cookie_service_.SetListAccountsResponseOneAccount("user@gmail.com",
                                                      "gaia_id");
    cookie_service_.TriggerListAccounts();
    task_environment_->RunUntilIdle();
  }

  void SignOut() {
    cookie_service_.SetListAccountsResponseNoAccounts();
    cookie_service_.TriggerListAccounts();
    task_environment_->RunUntilIdle();
  }

 private:
  base::test::ScopedTaskEnvironment* task_environment_;

  TestingPrefServiceSyncable pref_service_;
  TestSigninClient signin_client_;
  FakeProfileOAuth2TokenService token_service_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  FakeGaiaCookieManagerService cookie_service_;
};

class LogoServiceImplTest : public ::testing::Test {
 protected:
  LogoServiceImplTest()
      : template_url_service_(nullptr, 0),
        logo_cache_(new NiceMock<MockLogoCache>()),
        shared_factory_(
            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
                &test_url_loader_factory_)),
        signin_helper_(&task_environment_),
        use_gray_background_(false) {
    test_url_loader_factory_.SetInterceptor(base::BindRepeating(
        &LogoServiceImplTest::CapturingInterceptor, base::Unretained(this)));

    // Default search engine with logo. All 3P doodle_urls use ddljson API.
    AddSearchEngine("ex", "Logo Example",
                    "https://example.com/?q={searchTerms}",
                    GURL("https://example.com/logo.json"),
                    /*make_default=*/true);

    test_clock_.SetNow(base::Time::FromJsTime(INT64_C(1388686828000)));
    logo_service_ = std::make_unique<LogoServiceImpl>(
        base::FilePath(), signin_helper_.cookie_service(),
        &template_url_service_, std::make_unique<FakeImageDecoder>(),
        shared_factory_,
        base::BindRepeating(&LogoServiceImplTest::use_gray_background,
                            base::Unretained(this)));
    logo_service_->SetClockForTests(&test_clock_);
    logo_service_->SetLogoCacheForTests(base::WrapUnique(logo_cache_));
  }

  void TearDown() override {
    // |logo_service_|'s owns |logo_cache_|, which gets destroyed on
    // a background sequence after the LogoService's destruction. Ensure that
    // |logo_cache_| is actually destroyed before the test ends to make gmock
    // happy.
    logo_service_.reset();
    task_environment_.RunUntilIdle();
  }

  // Returns the response that the server would send for the given logo.
  std::string ServerResponse(const Logo& logo);

  // Sets the response to be returned when the LogoService fetches the logo.
  void SetServerResponse(const std::string& response,
                         int error_code = net::OK,
                         net::HttpStatusCode response_code = net::HTTP_OK);

  // Sets the response to be returned when the LogoService fetches the logo and
  // provides the given fingerprint.
  void SetServerResponseWhenFingerprint(
      const std::string& fingerprint,
      const std::string& response_when_fingerprint,
      int error_code = net::OK,
      net::HttpStatusCode response_code = net::HTTP_OK);

  const GURL& DoodleURL() const;

  // Calls logo_service_->GetLogo() and waits for the asynchronous response(s).
  void GetLogo(LogoCallbacks callbacks);
  void GetDecodedLogo(LogoCallback cached, LogoCallback fresh);
  void GetEncodedLogo(EncodedLogoCallback cached, EncodedLogoCallback fresh);

  void AddSearchEngine(base::StringPiece keyword,
                       base::StringPiece short_name,
                       const std::string& url,
                       GURL doodle_url,
                       bool make_default);

  void CapturingInterceptor(const network::ResourceRequest& request);

  bool use_gray_background() const { return use_gray_background_; }

  base::test::ScopedTaskEnvironment task_environment_;
  TemplateURLService template_url_service_;
  base::SimpleTestClock test_clock_;
  NiceMock<MockLogoCache>* logo_cache_;

  // Used for mocking |logo_service_| URLs.
  network::TestURLLoaderFactory test_url_loader_factory_;
  scoped_refptr<network::SharedURLLoaderFactory> shared_factory_;
  std::unique_ptr<LogoServiceImpl> logo_service_;

  SigninHelper signin_helper_;

  GURL latest_url_;
  bool use_gray_background_;
};

void LogoServiceImplTest::CapturingInterceptor(
    const network::ResourceRequest& request) {
  latest_url_ = request.url;
}

std::string LogoServiceImplTest::ServerResponse(const Logo& logo) {
  base::TimeDelta time_to_live;
  if (!logo.metadata.expiration_time.is_null())
    time_to_live = logo.metadata.expiration_time - test_clock_.Now();
  return MakeServerResponse(logo, time_to_live);
}

void LogoServiceImplTest::SetServerResponse(const std::string& response,
                                            int error_code,
                                            net::HttpStatusCode response_code) {
  SetServerResponseWhenFingerprint(std::string(), response, error_code,
                                   response_code);
}

void LogoServiceImplTest::SetServerResponseWhenFingerprint(
    const std::string& fingerprint,
    const std::string& response_when_fingerprint,
    int error_code,
    net::HttpStatusCode response_code) {
  GURL url_with_fp = AppendFingerprintParamToDoodleURL(
      AppendPreliminaryParamsToDoodleURL(false, DoodleURL()), fingerprint);

  network::ResourceResponseHead head;
  std::string headers(base::StringPrintf(
      "HTTP/1.1 %d %s\nContent-type: text/html\n\n",
      static_cast<int>(response_code), GetHttpReasonPhrase(response_code)));
  head.headers = new net::HttpResponseHeaders(
      net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
  head.mime_type = "text/html";
  network::URLLoaderCompletionStatus status;
  status.error_code = error_code;
  status.decoded_body_length = response_when_fingerprint.size();

  test_url_loader_factory_.AddResponse(url_with_fp, head,
                                       response_when_fingerprint, status);
}

const GURL& LogoServiceImplTest::DoodleURL() const {
  return template_url_service_.GetDefaultSearchProvider()->doodle_url();
}

void LogoServiceImplTest::GetLogo(LogoCallbacks callbacks) {
  logo_service_->GetLogo(std::move(callbacks));
  task_environment_.RunUntilIdle();
}

void LogoServiceImplTest::GetDecodedLogo(LogoCallback cached,
                                         LogoCallback fresh) {
  LogoCallbacks callbacks;
  callbacks.on_cached_decoded_logo_available = std::move(cached);
  callbacks.on_fresh_decoded_logo_available = std::move(fresh);
  GetLogo(std::move(callbacks));
}

void LogoServiceImplTest::GetEncodedLogo(EncodedLogoCallback cached,
                                         EncodedLogoCallback fresh) {
  LogoCallbacks callbacks;
  callbacks.on_cached_encoded_logo_available = std::move(cached);
  callbacks.on_fresh_encoded_logo_available = std::move(fresh);
  GetLogo(std::move(callbacks));
}

void LogoServiceImplTest::AddSearchEngine(base::StringPiece keyword,
                                          base::StringPiece short_name,
                                          const std::string& url,
                                          GURL doodle_url,
                                          bool make_default) {
  TemplateURLData search_url;
  search_url.SetKeyword(base::ASCIIToUTF16(keyword));
  search_url.SetShortName(base::ASCIIToUTF16(short_name));
  search_url.SetURL(url);
  search_url.doodle_url = doodle_url;

  TemplateURL* template_url =
      template_url_service_.Add(std::make_unique<TemplateURL>(search_url));
  if (make_default) {
    template_url_service_.SetUserSelectedDefaultSearchProvider(template_url);
  }
}

// Tests -----------------------------------------------------------------------

TEST_F(LogoServiceImplTest, CTARequestedBackgroundCanUpdate) {
  std::string response =
      ServerResponse(GetSampleLogo(DoodleURL(), test_clock_.Now()));
  GURL query_with_gray_background = AppendFingerprintParamToDoodleURL(
      AppendPreliminaryParamsToDoodleURL(true, DoodleURL()), std::string());
  GURL query_without_gray_background = AppendFingerprintParamToDoodleURL(
      AppendPreliminaryParamsToDoodleURL(false, DoodleURL()), std::string());

  use_gray_background_ = false;
  test_url_loader_factory_.ClearResponses();
  test_url_loader_factory_.AddResponse(query_without_gray_background.spec(),
                                       response, net::HTTP_OK);
  {
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(fresh, Run(_, _));
    LogoCallbacks callbacks;
    callbacks.on_fresh_decoded_logo_available = fresh.Get();
    logo_service_->GetLogo(std::move(callbacks));
    task_environment_.RunUntilIdle();
  }
  EXPECT_EQ(latest_url_.query().find("graybg:1"), std::string::npos);

  use_gray_background_ = true;
  test_url_loader_factory_.ClearResponses();
  test_url_loader_factory_.AddResponse(query_with_gray_background.spec(),
                                       response, net::HTTP_OK);
  {
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(fresh, Run(_, _));
    LogoCallbacks callbacks;
    callbacks.on_fresh_decoded_logo_available = fresh.Get();
    logo_service_->GetLogo(std::move(callbacks));
    task_environment_.RunUntilIdle();
  }
  EXPECT_NE(latest_url_.query().find("graybg:1"), std::string::npos);
}

TEST_F(LogoServiceImplTest, DownloadAndCacheLogo) {
  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  SetServerResponse(ServerResponse(logo));
  logo_cache_->ExpectSetCachedLogo(&logo);
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(logo)));
  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, DownloadAndCacheEncodedLogo) {
  StrictMock<MockEncodedLogoCallback> cached;
  StrictMock<MockEncodedLogoCallback> fresh;
  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  EncodedLogo encoded_logo = EncodeLogo(logo);
  SetServerResponse(ServerResponse(logo));
  logo_cache_->ExpectSetCachedLogo(&logo);
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(encoded_logo)));
  GetEncodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, ShouldReturnDisabledWhenDSEHasNoLogo) {
  AddSearchEngine("cr", "Chromium", "https://www.chromium.org/?q={searchTerms}",
                  GURL(/* logo disabled */), /*make_default=*/true);

  {
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DISABLED, Eq(base::nullopt)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::DISABLED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }

  {
    StrictMock<MockEncodedLogoCallback> cached;
    StrictMock<MockEncodedLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DISABLED, Eq(base::nullopt)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::DISABLED, Eq(base::nullopt)));
    GetEncodedLogo(cached.Get(), fresh.Get());
  }
}

TEST_F(LogoServiceImplTest, EmptyCacheAndFailedDownload) {
  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(nullptr)).Times(AnyNumber());

  {
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    SetServerResponse("server is borked");
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::REVALIDATED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }

  {
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    SetServerResponse("", net::ERR_FAILED, net::HTTP_OK);
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }

  {
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    SetServerResponse("", net::OK, net::HTTP_BAD_GATEWAY);
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }
}

TEST_F(LogoServiceImplTest, AcceptMinimalLogoResponse) {
  Logo logo;
  logo.image = MakeBitmap(1, 2);
  logo.metadata.source_url =
      AppendPreliminaryParamsToDoodleURL(false, DoodleURL());
  logo.metadata.can_show_after_expiration = true;
  logo.metadata.mime_type = "image/png";

  std::string response =
      ")]}' {\"ddljson\":{\"data_uri\":\"data:image/png;base64," +
      EncodeBitmapAsPNGBase64(logo.image) + "\"}}";

  SetServerResponse(response);

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(logo)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, ReturnCachedLogo) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);
  SetServerResponseWhenFingerprint(cached_logo.metadata.fingerprint, "",
                                   net::ERR_FAILED, net::HTTP_OK);

  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, ValidateCachedLogo) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  // During revalidation, the image data and mime_type are absent.
  Logo fresh_logo = cached_logo;
  fresh_logo.image.reset();
  fresh_logo.metadata.mime_type.clear();
  fresh_logo.metadata.expiration_time =
      test_clock_.Now() + base::TimeDelta::FromDays(8);
  SetServerResponseWhenFingerprint(fresh_logo.metadata.fingerprint,
                                   ServerResponse(fresh_logo));

  {
    EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(1);
    EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
    EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::REVALIDATED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }

  ASSERT_TRUE(logo_cache_->GetCachedLogoMetadata());
  EXPECT_EQ(fresh_logo.metadata.expiration_time,
            logo_cache_->GetCachedLogoMetadata()->expiration_time);

  {
    // Ensure that cached logo is still returned correctly on subsequent
    // requests. In particular, the metadata should stay valid.
    // https://crbug.com/480090
    EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(1);
    EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
    EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::REVALIDATED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }
}

TEST_F(LogoServiceImplTest, UpdateCachedLogoMetadata) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  Logo fresh_logo = cached_logo;
  fresh_logo.image.reset();
  fresh_logo.metadata.mime_type.clear();
  fresh_logo.metadata.on_click_url = GURL("https://new.onclick.url");
  fresh_logo.metadata.alt_text = "new alt text";
  fresh_logo.metadata.animated_url = GURL("https://new.animated.url");
  fresh_logo.metadata.expiration_time =
      test_clock_.Now() + base::TimeDelta::FromDays(8);
  SetServerResponseWhenFingerprint(fresh_logo.metadata.fingerprint,
                                   ServerResponse(fresh_logo));

  // On the first request, the cached logo should be used.
  {
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::REVALIDATED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }

  // Subsequently, the cached image should be returned along with the updated
  // metadata.
  {
    Logo expected_logo = fresh_logo;
    expected_logo.image = cached_logo.image;
    expected_logo.metadata.mime_type = cached_logo.metadata.mime_type;
    StrictMock<MockLogoCallback> cached;
    StrictMock<MockLogoCallback> fresh;
    EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(expected_logo)));
    EXPECT_CALL(fresh, Run(LogoCallbackReason::REVALIDATED, Eq(base::nullopt)));
    GetDecodedLogo(cached.Get(), fresh.Get());
  }
}

TEST_F(LogoServiceImplTest, UpdateCachedLogo) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  Logo fresh_logo = GetSampleLogo2(DoodleURL(), test_clock_.Now());
  SetServerResponseWhenFingerprint(cached_logo.metadata.fingerprint,
                                   ServerResponse(fresh_logo));

  logo_cache_->ExpectSetCachedLogo(&fresh_logo);
  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(fresh_logo)));
  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, InvalidateCachedLogo) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  // This response means there's no current logo.
  SetServerResponseWhenFingerprint(cached_logo.metadata.fingerprint,
                                   ")]}' {\"update\":{}}");

  logo_cache_->ExpectSetCachedLogo(nullptr);
  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, DeleteCachedLogoFromOldUrl) {
  SetServerResponse("", net::ERR_FAILED, net::HTTP_OK);
  Logo cached_logo =
      GetSampleLogo(GURL("https://oldsearchprovider.com"), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(nullptr)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, LogoWithTTLCannotBeShownAfterExpiration) {
  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  base::TimeDelta time_to_live = base::TimeDelta::FromDays(3);
  logo.metadata.expiration_time = test_clock_.Now() + time_to_live;
  SetServerResponse(ServerResponse(logo));
  LogoCallbacks callbacks;
  callbacks.on_fresh_decoded_logo_available = base::Bind(
      [](LogoCallbackReason type, const base::Optional<Logo>& logo) {});
  GetLogo(std::move(callbacks));

  const LogoMetadata* cached_metadata = logo_cache_->GetCachedLogoMetadata();
  ASSERT_TRUE(cached_metadata);
  EXPECT_FALSE(cached_metadata->can_show_after_expiration);
  EXPECT_EQ(test_clock_.Now() + time_to_live, cached_metadata->expiration_time);
}

TEST_F(LogoServiceImplTest, LogoWithoutTTLCanBeShownAfterExpiration) {
  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  base::TimeDelta time_to_live = base::TimeDelta();
  SetServerResponse(MakeServerResponse(logo, time_to_live));
  LogoCallbacks callbacks;
  callbacks.on_fresh_decoded_logo_available = base::Bind(
      [](LogoCallbackReason type, const base::Optional<Logo>& logo) {});
  GetLogo(std::move(callbacks));

  const LogoMetadata* cached_metadata = logo_cache_->GetCachedLogoMetadata();
  ASSERT_TRUE(cached_metadata);
  EXPECT_TRUE(cached_metadata->can_show_after_expiration);
  EXPECT_EQ(test_clock_.Now() + base::TimeDelta::FromDays(30),
            cached_metadata->expiration_time);
}

TEST_F(LogoServiceImplTest, UseSoftExpiredCachedLogo) {
  SetServerResponse("", net::ERR_FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  cached_logo.metadata.expiration_time =
      test_clock_.Now() - base::TimeDelta::FromSeconds(1);
  cached_logo.metadata.can_show_after_expiration = true;
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, RerequestSoftExpiredCachedLogo) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  cached_logo.metadata.expiration_time =
      test_clock_.Now() - base::TimeDelta::FromDays(5);
  cached_logo.metadata.can_show_after_expiration = true;
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  Logo fresh_logo = GetSampleLogo2(DoodleURL(), test_clock_.Now());
  SetServerResponse(ServerResponse(fresh_logo));

  logo_cache_->ExpectSetCachedLogo(&fresh_logo);
  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(fresh_logo)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, DeleteAncientCachedLogo) {
  SetServerResponse("", net::ERR_FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  cached_logo.metadata.expiration_time =
      test_clock_.Now() - base::TimeDelta::FromDays(200);
  cached_logo.metadata.can_show_after_expiration = true;
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(nullptr)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, DeleteExpiredCachedLogo) {
  SetServerResponse("", net::ERR_FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  cached_logo.metadata.expiration_time =
      test_clock_.Now() - base::TimeDelta::FromSeconds(1);
  cached_logo.metadata.can_show_after_expiration = false;
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(0);
  EXPECT_CALL(*logo_cache_, SetCachedLogo(nullptr)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));

  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::FAILED, Eq(base::nullopt)));

  GetDecodedLogo(cached.Get(), fresh.Get());
}

TEST_F(LogoServiceImplTest, ClearLogoOnSignOut) {
  // Sign in and setup a logo response.
  signin_helper_.SignIn();
  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  SetServerResponse(ServerResponse(logo));

  // Request the logo so it gets fetched and cached.
  logo_cache_->ExpectSetCachedLogo(&logo);
  StrictMock<MockLogoCallback> cached;
  StrictMock<MockLogoCallback> fresh;
  EXPECT_CALL(cached, Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(fresh, Run(LogoCallbackReason::DETERMINED, Eq(logo)));
  GetDecodedLogo(cached.Get(), fresh.Get());

  // Signing out should clear the cached logo immediately.
  logo_cache_->ExpectSetCachedLogo(nullptr);
  signin_helper_.SignOut();
}

// Tests that deal with multiple listeners.

void EnqueueCallbacks(LogoServiceImpl* logo_service,
                      std::vector<LogoCallback>* cached_callbacks,
                      std::vector<LogoCallback>* fresh_callbacks,
                      size_t start_index) {
  DCHECK_EQ(cached_callbacks->size(), fresh_callbacks->size());
  if (start_index >= cached_callbacks->size())
    return;

  LogoCallbacks callbacks;
  callbacks.on_cached_decoded_logo_available =
      std::move((*cached_callbacks)[start_index]);
  callbacks.on_fresh_decoded_logo_available =
      std::move((*fresh_callbacks)[start_index]);
  logo_service->GetLogo(std::move(callbacks));
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&EnqueueCallbacks, logo_service, cached_callbacks,
                     fresh_callbacks, start_index + 1));
}

TEST_F(LogoServiceImplTest, SupportOverlappingLogoRequests) {
  Logo cached_logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);
  ON_CALL(*logo_cache_, SetCachedLogo(_)).WillByDefault(Return());

  Logo fresh_logo = GetSampleLogo2(DoodleURL(), test_clock_.Now());
  std::string response = ServerResponse(fresh_logo);
  SetServerResponse(response);
  SetServerResponseWhenFingerprint(cached_logo.metadata.fingerprint, response);

  const int kNumListeners = 10;
  std::vector<std::unique_ptr<MockLogoCallback>> mocks;
  std::vector<LogoCallback> cached_callbacks;
  std::vector<LogoCallback> fresh_callbacks;
  for (int i = 0; i < kNumListeners; ++i) {
    mocks.push_back(std::make_unique<MockLogoCallback>());
    EXPECT_CALL(*mocks.back(),
                Run(LogoCallbackReason::DETERMINED, Eq(cached_logo)));
    cached_callbacks.push_back(mocks.back()->Get());

    mocks.push_back(std::make_unique<MockLogoCallback>());
    EXPECT_CALL(*mocks.back(),
                Run(LogoCallbackReason::DETERMINED, Eq(fresh_logo)));
    fresh_callbacks.push_back(mocks.back()->Get());
  }
  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(AtMost(3));
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(3));

  EnqueueCallbacks(logo_service_.get(), &cached_callbacks, &fresh_callbacks, 0);

  task_environment_.RunUntilIdle();
}

TEST_F(LogoServiceImplTest, DeleteCallbacksWhenLogoURLChanged) {
  StrictMock<MockLogoCallback> first_cached;
  StrictMock<MockLogoCallback> first_fresh;
  EXPECT_CALL(first_cached,
              Run(LogoCallbackReason::CANCELED, Eq(base::nullopt)));
  EXPECT_CALL(first_fresh,
              Run(LogoCallbackReason::CANCELED, Eq(base::nullopt)));
  LogoCallbacks first_callbacks;
  first_callbacks.on_cached_decoded_logo_available = first_cached.Get();
  first_callbacks.on_fresh_decoded_logo_available = first_fresh.Get();
  logo_service_->GetLogo(std::move(first_callbacks));

  // Change default search engine; new DSE has a doodle URL.
  AddSearchEngine("cr", "Chromium", "https://www.chromium.org/?q={searchTerms}",
                  GURL("https://chromium.org/logo.json"),
                  /*make_default=*/true);

  Logo logo = GetSampleLogo(DoodleURL(), test_clock_.Now());
  SetServerResponse(ServerResponse(logo));

  StrictMock<MockLogoCallback> second_cached;
  StrictMock<MockLogoCallback> second_fresh;
  EXPECT_CALL(second_cached,
              Run(LogoCallbackReason::DETERMINED, Eq(base::nullopt)));
  EXPECT_CALL(second_fresh, Run(LogoCallbackReason::DETERMINED, Eq(logo)));
  LogoCallbacks second_callbacks;
  second_callbacks.on_cached_decoded_logo_available = second_cached.Get();
  second_callbacks.on_fresh_decoded_logo_available = second_fresh.Get();
  logo_service_->GetLogo(std::move(second_callbacks));

  task_environment_.RunUntilIdle();
}

}  // namespace

bool operator==(const Logo& a, const Logo& b) {
  return (a.image.width() == b.image.width()) &&
         (a.image.height() == b.image.height()) &&
         (a.metadata.on_click_url == b.metadata.on_click_url) &&
         (a.metadata.source_url == b.metadata.source_url) &&
         (a.metadata.animated_url == b.metadata.animated_url) &&
         (a.metadata.alt_text == b.metadata.alt_text) &&
         (a.metadata.mime_type == b.metadata.mime_type) &&
         (a.metadata.fingerprint == b.metadata.fingerprint) &&
         (a.metadata.can_show_after_expiration ==
          b.metadata.can_show_after_expiration);
}

bool operator==(const EncodedLogo& a, const EncodedLogo& b) {
  return DecodeLogo(a) == DecodeLogo(b);
}

void PrintTo(const Logo& logo, std::ostream* ostr) {
  *ostr << "image size: " << logo.image.width() << "x" << logo.image.height()
        << "\non_click_url: " << logo.metadata.on_click_url
        << "\nsource_url: " << logo.metadata.source_url
        << "\nanimated_url: " << logo.metadata.animated_url
        << "\nalt_text: " << logo.metadata.alt_text
        << "\nmime_type: " << logo.metadata.mime_type
        << "\nfingerprint: " << logo.metadata.fingerprint
        << "\ncan_show_after_expiration: "
        << logo.metadata.can_show_after_expiration;
}

void PrintTo(const EncodedLogo& logo, std::ostream* ostr) {
  PrintTo(DecodeLogo(logo), ostr);
}

}  // namespace search_provider_logos
