// 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_tracker.h"

#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/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/run_loop.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "base/values.h"
#include "components/search_provider_logos/google_logo_api.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_status.h"
#include "net/url_request/url_request_test_util.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::InSequence;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;

namespace search_provider_logos {

namespace {

bool AreImagesSameSize(const SkBitmap& bitmap1, const SkBitmap& bitmap2) {
  return bitmap1.width() == bitmap2.width() &&
         bitmap1.height() == bitmap2.height();
}

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 = logo_url.spec();
  logo.metadata.on_click_url = "http://www.google.com/search?q=potato";
  logo.metadata.alt_text = "A logo about potatoes";
  logo.metadata.animated_url = "http://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 = logo_url.spec();
  logo.metadata.on_click_url = "http://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;
  if (!image.isNull())
    dict.SetString("update.logo.data", EncodeBitmapAsPNGBase64(image));

  dict.SetString("update.logo.target", on_click_url);
  dict.SetString("update.logo.alt", alt_text);
  if (!animated_url.empty())
    dict.SetString("update.logo.url", animated_url);
  if (!mime_type.empty())
    dict.SetString("update.logo.mime_type", mime_type);
  dict.SetString("update.logo.fingerprint", fingerprint);
  if (time_to_live.ToInternalValue() != 0)
    dict.SetInteger("update.logo.time_to_live",
                    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,
                            logo.metadata.alt_text,
                            logo.metadata.animated_url,
                            logo.metadata.mime_type,
                            logo.metadata.fingerprint,
                            time_to_live);
}

void ExpectLogosEqual(const Logo* expected_logo,
                      const Logo* actual_logo) {
  if (!expected_logo) {
    ASSERT_FALSE(actual_logo);
    return;
  }
  ASSERT_TRUE(actual_logo);
  EXPECT_TRUE(AreImagesSameSize(expected_logo->image, actual_logo->image));
  EXPECT_EQ(expected_logo->metadata.on_click_url,
            actual_logo->metadata.on_click_url);
  EXPECT_EQ(expected_logo->metadata.source_url,
            actual_logo->metadata.source_url);
  EXPECT_EQ(expected_logo->metadata.animated_url,
            actual_logo->metadata.animated_url);
  EXPECT_EQ(expected_logo->metadata.alt_text,
            actual_logo->metadata.alt_text);
  EXPECT_EQ(expected_logo->metadata.mime_type,
            actual_logo->metadata.mime_type);
  EXPECT_EQ(expected_logo->metadata.fingerprint,
            actual_logo->metadata.fingerprint);
  EXPECT_EQ(expected_logo->metadata.can_show_after_expiration,
            actual_logo->metadata.can_show_after_expiration);
}

void ExpectLogosEqual(const Logo* expected_logo,
                      const EncodedLogo* actual_encoded_logo) {
  Logo actual_logo;
  if (actual_encoded_logo)
    actual_logo = DecodeLogo(*actual_encoded_logo);
  ExpectLogosEqual(expected_logo, actual_encoded_logo ? &actual_logo : NULL);
}

ACTION_P(ExpectLogosEqualAction, expected_logo) {
  ExpectLogosEqual(expected_logo, arg0);
}

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);
    EXPECT_CALL(*this, SetCachedLogo(_))
        .WillOnce(ExpectLogosEqualAction(expected_logo));
  }

  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;
  }

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

  virtual void SetCachedLogoInternal(const EncodedLogo* logo) {
    logo_.reset(logo ? new EncodedLogo(*logo) : NULL);
    metadata_.reset(logo ? new LogoMetadata(logo->metadata) : NULL);
  }

  scoped_ptr<EncodedLogo> GetCachedLogo() override {
    OnGetCachedLogo();
    return make_scoped_ptr(logo_ ? new EncodedLogo(*logo_) : NULL);
  }

 private:
  scoped_ptr<LogoMetadata> metadata_;
  scoped_ptr<EncodedLogo> logo_;
};

class MockLogoObserver : public LogoObserver {
 public:
  virtual ~MockLogoObserver() {}

  void ExpectNoLogo() {
    Mock::VerifyAndClearExpectations(this);
    EXPECT_CALL(*this, OnLogoAvailable(_, _)).Times(0);
    EXPECT_CALL(*this, OnObserverRemoved()).Times(1);
  }

  void ExpectCachedLogo(const Logo* expected_cached_logo) {
    Mock::VerifyAndClearExpectations(this);
    EXPECT_CALL(*this, OnLogoAvailable(_, true))
        .WillOnce(ExpectLogosEqualAction(expected_cached_logo));
    EXPECT_CALL(*this, OnLogoAvailable(_, false)).Times(0);
    EXPECT_CALL(*this, OnObserverRemoved()).Times(1);
  }

  void ExpectFreshLogo(const Logo* expected_fresh_logo) {
    Mock::VerifyAndClearExpectations(this);
    EXPECT_CALL(*this, OnLogoAvailable(_, true)).Times(0);
    EXPECT_CALL(*this, OnLogoAvailable(NULL, true));
    EXPECT_CALL(*this, OnLogoAvailable(_, false))
        .WillOnce(ExpectLogosEqualAction(expected_fresh_logo));
    EXPECT_CALL(*this, OnObserverRemoved()).Times(1);
  }

  void ExpectCachedAndFreshLogos(const Logo* expected_cached_logo,
                                 const Logo* expected_fresh_logo) {
    Mock::VerifyAndClearExpectations(this);
    InSequence dummy;
    EXPECT_CALL(*this, OnLogoAvailable(_, true))
        .WillOnce(ExpectLogosEqualAction(expected_cached_logo));
    EXPECT_CALL(*this, OnLogoAvailable(_, false))
        .WillOnce(ExpectLogosEqualAction(expected_fresh_logo));
    EXPECT_CALL(*this, OnObserverRemoved()).Times(1);
  }

  MOCK_METHOD2(OnLogoAvailable, void(const Logo*, bool));
  MOCK_METHOD0(OnObserverRemoved, void());
};

class TestLogoDelegate : public LogoDelegate {
 public:
  TestLogoDelegate() {}
  ~TestLogoDelegate() override {}

  void DecodeUntrustedImage(
      const scoped_refptr<base::RefCountedString>& encoded_image,
      base::Callback<void(const SkBitmap&)> image_decoded_callback) override {
    SkBitmap bitmap =
        gfx::Image::CreateFrom1xPNGBytes(encoded_image->front(),
                                         encoded_image->size()).AsBitmap();
    base::MessageLoopProxy::current()->PostTask(
        FROM_HERE, base::Bind(image_decoded_callback, bitmap));
  }
};

class LogoTrackerTest : public ::testing::Test {
 protected:
  LogoTrackerTest()
      : message_loop_(new base::MessageLoop()),
        logo_url_("https://google.com/doodleoftheday?size=hp"),
        test_clock_(new base::SimpleTestClock()),
        logo_cache_(new NiceMock<MockLogoCache>()),
        fake_url_fetcher_factory_(NULL) {
    test_clock_->SetNow(base::Time::FromJsTime(GG_INT64_C(1388686828000)));
    logo_tracker_ = new LogoTracker(
        base::FilePath(),
        base::MessageLoopProxy::current(),
        base::MessageLoopProxy::current(),
        new net::TestURLRequestContextGetter(base::MessageLoopProxy::current()),
        scoped_ptr<LogoDelegate>(new TestLogoDelegate()));
    logo_tracker_->SetServerAPI(logo_url_, base::Bind(&GoogleParseLogoResponse),
                                base::Bind(&GoogleAppendQueryparamsToLogoURL),
                                false);
    logo_tracker_->SetClockForTests(scoped_ptr<base::Clock>(test_clock_));
    logo_tracker_->SetLogoCacheForTests(scoped_ptr<LogoCache>(logo_cache_));
  }

  virtual void TearDown() {
    // logo_tracker_ owns logo_cache_, which gets destructed on the file thread
    // after logo_tracker_'s destruction. Ensure that logo_cache_ is actually
    // destructed before the test ends to make gmock happy.
    delete logo_tracker_;
    message_loop_->RunUntilIdle();
  }

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

  // Sets the response to be returned when the LogoTracker fetches the logo.
  void SetServerResponse(const std::string& response,
                         net::URLRequestStatus::Status request_status =
                             net::URLRequestStatus::SUCCESS,
                         net::HttpStatusCode response_code = net::HTTP_OK);

  // Sets the response to be returned when the LogoTracker fetches the logo and
  // provides the given fingerprint.
  void SetServerResponseWhenFingerprint(
      const std::string& fingerprint,
      const std::string& response_when_fingerprint,
      net::URLRequestStatus::Status request_status =
          net::URLRequestStatus::SUCCESS,
      net::HttpStatusCode response_code = net::HTTP_OK);

  // Calls logo_tracker_->GetLogo() with listener_ and waits for the
  // asynchronous response(s).
  void GetLogo();

  scoped_ptr<base::MessageLoop> message_loop_;
  GURL logo_url_;
  base::SimpleTestClock* test_clock_;
  NiceMock<MockLogoCache>* logo_cache_;
  net::FakeURLFetcherFactory fake_url_fetcher_factory_;
  LogoTracker* logo_tracker_;
  NiceMock<MockLogoObserver> observer_;
};

std::string LogoTrackerTest::ServerResponse(const Logo& logo) const {
  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 LogoTrackerTest::SetServerResponse(
    const std::string& response,
    net::URLRequestStatus::Status request_status,
    net::HttpStatusCode response_code) {
  fake_url_fetcher_factory_.SetFakeResponse(
      logo_url_, response, response_code, request_status);
}

void LogoTrackerTest::SetServerResponseWhenFingerprint(
    const std::string& fingerprint,
    const std::string& response_when_fingerprint,
    net::URLRequestStatus::Status request_status,
    net::HttpStatusCode response_code) {
  GURL url_with_fp =
      GoogleAppendQueryparamsToLogoURL(logo_url_, fingerprint, false);
  fake_url_fetcher_factory_.SetFakeResponse(
      url_with_fp, response_when_fingerprint, response_code, request_status);
}

void LogoTrackerTest::GetLogo() {
  logo_tracker_->GetLogo(&observer_);
  base::RunLoop().RunUntilIdle();
}

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

TEST_F(LogoTrackerTest, FingerprintURLHasColon) {
  GURL url_with_fp = GoogleAppendQueryparamsToLogoURL(
      GURL("http://logourl.com/path"), "abc123", false);
  EXPECT_EQ("http://logourl.com/path?async=es_dfp:abc123", url_with_fp.spec());

  url_with_fp = GoogleAppendQueryparamsToLogoURL(
      GURL("http://logourl.com/?a=b"), "cafe0", false);
  EXPECT_EQ("http://logourl.com/?a=b&async=es_dfp:cafe0", url_with_fp.spec());
}

TEST_F(LogoTrackerTest, CTAURLHasComma) {
  GURL url_with_fp = GoogleAppendQueryparamsToLogoURL(
      GURL("http://logourl.com/path"), "abc123", true);
  EXPECT_EQ("http://logourl.com/path?async=es_dfp:abc123,cta:1",
            url_with_fp.spec());

  url_with_fp = GoogleAppendQueryparamsToLogoURL(
      GURL("http://logourl.com/?a=b"), "", true);
  EXPECT_EQ("http://logourl.com/?a=b&async=cta:1", url_with_fp.spec());
}

TEST_F(LogoTrackerTest, DownloadAndCacheLogo) {
  Logo logo = GetSampleLogo(logo_url_, test_clock_->Now());
  SetServerResponse(ServerResponse(logo));
  logo_cache_->ExpectSetCachedLogo(&logo);
  observer_.ExpectFreshLogo(&logo);
  GetLogo();
}

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

  SetServerResponse("server is borked");
  observer_.ExpectCachedLogo(NULL);
  GetLogo();

  SetServerResponse("", net::URLRequestStatus::FAILED, net::HTTP_OK);
  observer_.ExpectCachedLogo(NULL);
  GetLogo();

  SetServerResponse("", net::URLRequestStatus::SUCCESS, net::HTTP_BAD_GATEWAY);
  observer_.ExpectCachedLogo(NULL);
  GetLogo();
}

TEST_F(LogoTrackerTest, AcceptMinimalLogoResponse) {
  Logo logo;
  logo.image = MakeBitmap(1, 2);
  logo.metadata.source_url = logo_url_.spec();
  logo.metadata.can_show_after_expiration = true;
  logo.metadata.mime_type = "image/png";

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

  SetServerResponse(response);
  observer_.ExpectFreshLogo(&logo);
  GetLogo();
}

TEST_F(LogoTrackerTest, ReturnCachedLogo) {
  Logo cached_logo = GetSampleLogo(logo_url_, test_clock_->Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);
  SetServerResponseWhenFingerprint(cached_logo.metadata.fingerprint,
                                   "",
                                   net::URLRequestStatus::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));
  observer_.ExpectCachedLogo(&cached_logo);
  GetLogo();
}

TEST_F(LogoTrackerTest, ValidateCachedLogo) {
  Logo cached_logo = GetSampleLogo(logo_url_, 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));
  observer_.ExpectCachedLogo(&cached_logo);
  GetLogo();

  EXPECT_TRUE(logo_cache_->GetCachedLogoMetadata() != NULL);
  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. http://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));
  observer_.ExpectCachedLogo(&cached_logo);
  GetLogo();
}

TEST_F(LogoTrackerTest, UpdateCachedLogoMetadata) {
  Logo cached_logo = GetSampleLogo(logo_url_, 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 = "http://new.onclick.url";
  fresh_logo.metadata.alt_text = "new alt text";
  fresh_logo.metadata.animated_url = "http://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.
  observer_.ExpectCachedLogo(&cached_logo);
  GetLogo();

  // 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;
  observer_.ExpectCachedLogo(&expected_logo);
  GetLogo();
}

TEST_F(LogoTrackerTest, UpdateCachedLogo) {
  Logo cached_logo = GetSampleLogo(logo_url_, test_clock_->Now());
  logo_cache_->EncodeAndSetCachedLogo(cached_logo);

  Logo fresh_logo = GetSampleLogo2(logo_url_, 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));
  observer_.ExpectCachedAndFreshLogos(&cached_logo, &fresh_logo);

  GetLogo();
}

TEST_F(LogoTrackerTest, InvalidateCachedLogo) {
  Logo cached_logo = GetSampleLogo(logo_url_, 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(NULL);
  EXPECT_CALL(*logo_cache_, UpdateCachedLogoMetadata(_)).Times(0);
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));
  observer_.ExpectCachedAndFreshLogos(&cached_logo, NULL);

  GetLogo();
}

TEST_F(LogoTrackerTest, DeleteCachedLogoFromOldUrl) {
  SetServerResponse("", net::URLRequestStatus::FAILED, net::HTTP_OK);
  Logo cached_logo =
      GetSampleLogo(GURL("http://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(NULL)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));
  observer_.ExpectCachedLogo(NULL);
  GetLogo();
}

TEST_F(LogoTrackerTest, LogoWithTTLCannotBeShownAfterExpiration) {
  Logo logo = GetSampleLogo(logo_url_, 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));
  GetLogo();

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

TEST_F(LogoTrackerTest, LogoWithoutTTLCanBeShownAfterExpiration) {
  Logo logo = GetSampleLogo(logo_url_, test_clock_->Now());
  base::TimeDelta time_to_live = base::TimeDelta();
  SetServerResponse(MakeServerResponse(logo, time_to_live));
  GetLogo();

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

TEST_F(LogoTrackerTest, UseSoftExpiredCachedLogo) {
  SetServerResponse("", net::URLRequestStatus::FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(logo_url_, 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));
  observer_.ExpectCachedLogo(&cached_logo);
  GetLogo();
}

TEST_F(LogoTrackerTest, RerequestSoftExpiredCachedLogo) {
  Logo cached_logo = GetSampleLogo(logo_url_, 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(logo_url_, 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));
  observer_.ExpectCachedAndFreshLogos(&cached_logo, &fresh_logo);

  GetLogo();
}

TEST_F(LogoTrackerTest, DeleteAncientCachedLogo) {
  SetServerResponse("", net::URLRequestStatus::FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(logo_url_, 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(NULL)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));
  observer_.ExpectCachedLogo(NULL);
  GetLogo();
}

TEST_F(LogoTrackerTest, DeleteExpiredCachedLogo) {
  SetServerResponse("", net::URLRequestStatus::FAILED, net::HTTP_OK);
  Logo cached_logo = GetSampleLogo(logo_url_, 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(NULL)).Times(AnyNumber());
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(1));
  observer_.ExpectCachedLogo(NULL);
  GetLogo();
}

// Tests that deal with multiple listeners.

void EnqueueObservers(LogoTracker* logo_tracker,
                      const ScopedVector<MockLogoObserver>& observers,
                      size_t start_index) {
  if (start_index >= observers.size())
    return;

  logo_tracker->GetLogo(observers[start_index]);
  base::MessageLoop::current()->PostTask(FROM_HERE,
                                         base::Bind(&EnqueueObservers,
                                                    logo_tracker,
                                                    base::ConstRef(observers),
                                                    start_index + 1));
}

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

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

  const int kNumListeners = 10;
  ScopedVector<MockLogoObserver> listeners;
  for (int i = 0; i < kNumListeners; ++i) {
    MockLogoObserver* listener = new MockLogoObserver();
    listener->ExpectCachedAndFreshLogos(&cached_logo, &fresh_logo);
    listeners.push_back(listener);
  }
  EnqueueObservers(logo_tracker_, listeners, 0);

  EXPECT_CALL(*logo_cache_, SetCachedLogo(_)).Times(AtMost(3));
  EXPECT_CALL(*logo_cache_, OnGetCachedLogo()).Times(AtMost(3));

  base::RunLoop().RunUntilIdle();
}

TEST_F(LogoTrackerTest, DeleteObserversWhenLogoURLChanged) {
  MockLogoObserver listener1;
  listener1.ExpectNoLogo();
  logo_tracker_->GetLogo(&listener1);

  logo_url_ = GURL("http://example.com/new-logo-url");
  logo_tracker_->SetServerAPI(logo_url_, base::Bind(&GoogleParseLogoResponse),
                              base::Bind(&GoogleAppendQueryparamsToLogoURL),
                              false);
  Logo logo = GetSampleLogo(logo_url_, test_clock_->Now());
  SetServerResponse(ServerResponse(logo));

  MockLogoObserver listener2;
  listener2.ExpectFreshLogo(&logo);
  logo_tracker_->GetLogo(&listener2);

  base::RunLoop().RunUntilIdle();
}

}  // namespace

}  // namespace search_provider_logos
