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

#include "components/omnibox/browser/favicon_cache.h"

#include "base/functional/bind.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "components/variations/scoped_variations_ids_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/favicon_size.h"

using testing::_;
using testing::DoAll;
using testing::Return;

namespace {

favicon_base::FaviconImageResult GetDummyFaviconResult() {
  favicon_base::FaviconImageResult result;

  result.icon_url = GURL("http://example.com/favicon.ico");

  SkBitmap bitmap;
  bitmap.allocN32Pixels(gfx::kFaviconSize, gfx::kFaviconSize);
  bitmap.eraseColor(SK_ColorBLUE);
  result.image = gfx::Image::CreateFrom1xBitmap(bitmap);

  return result;
}

favicon_base::FaviconRawBitmapResult GetDummyRawFaviconResult() {
  favicon_base::FaviconRawBitmapResult result;

  result.bitmap_data = GetDummyFaviconResult().image.As1xPNGBytes();

  return result;
}

void VerifyFetchedFaviconAndCount(int* count, const gfx::Image& favicon) {
  DCHECK(count);
  EXPECT_FALSE(favicon.IsEmpty());
  ++(*count);
}

void VerifyFetchedFavicon(const gfx::Image& favicon) {
  EXPECT_FALSE(favicon.IsEmpty());
}

void Fail(const gfx::Image& favicon) {
  FAIL() << "This asynchronous callback should never have been called.";
}

}  // namespace

class FaviconCacheTest : public testing::Test {
 protected:
  const GURL kUrlA = GURL("http://www.a.com/");
  const GURL kUrlB = GURL("http://www.b.com/");
  const GURL kIconUrl = GURL("http://a.com/favicon.ico");

  FaviconCacheTest()
      : cache_(&favicon_service_, nullptr /* history_service */) {}

  testing::NiceMock<favicon::MockFaviconService> favicon_service_;

  void ExpectFaviconServiceForPageUrlCalls(int a_site_calls, int b_site_calls) {
    if (a_site_calls > 0) {
      EXPECT_CALL(
          favicon_service_,
          GetFaviconImageForPageURL(kUrlA, _ /* callback */, _ /* tracker */))
          .Times(a_site_calls)
          .WillRepeatedly(
              [&](auto, favicon_base::FaviconImageCallback callback, auto) {
                favicon_service_a_site_response_ = std::move(callback);
                return base::CancelableTaskTracker::kBadTaskId;
              });
    }

    if (b_site_calls > 0) {
      EXPECT_CALL(
          favicon_service_,
          GetFaviconImageForPageURL(kUrlB, _ /* callback */, _ /* tracker */))
          .Times(b_site_calls)
          .WillRepeatedly(
              [&](auto, favicon_base::FaviconImageCallback callback, auto) {
                favicon_service_b_site_response_ = std::move(callback);
                return base::CancelableTaskTracker::kBadTaskId;
              });
    }
  }

  void ExpectFaviconServiceForLargestFaviconPageUrlCalls(int a_site_calls,
                                                         int b_site_calls) {
    if (a_site_calls > 0) {
      EXPECT_CALL(favicon_service_,
                  GetRawFaviconForPageURL(kUrlA, _ /*icon_types */,
                                          0 /* desired_size_in_pixel */,
                                          false /* fallback_to_host */,
                                          _ /* callback */, _ /* tracker */))
          .Times(a_site_calls)
          .WillRepeatedly([&](auto, auto, auto, auto,
                              favicon_base::FaviconRawBitmapCallback callback,
                              auto) {
            favicon_service_a_site_raw_favicon_response_ = std::move(callback);
            return base::CancelableTaskTracker::kBadTaskId;
          });
    }

    if (b_site_calls > 0) {
      EXPECT_CALL(favicon_service_,
                  GetRawFaviconForPageURL(kUrlB, _ /*icon_types */,
                                          0 /* desired_size_in_pixel */,
                                          false /* fallback_to_host */,
                                          _ /* callback */, _ /* tracker */))
          .Times(b_site_calls)
          .WillRepeatedly([&](auto, auto, auto, auto,
                              favicon_base::FaviconRawBitmapCallback callback,
                              auto) {
            favicon_service_b_site_raw_favicon_response_ = std::move(callback);
            return base::CancelableTaskTracker::kBadTaskId;
          });
    }
  }

  void ExpectFaviconServiceForIconUrlCalls(int calls) {
    EXPECT_CALL(favicon_service_,
                GetFaviconImage(kIconUrl, _ /* callback */, _ /* tracker */))
        .Times(calls);
  }

  variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
      variations::VariationsIdsProvider::Mode::kUseSignedInState};
  favicon_base::FaviconImageCallback favicon_service_a_site_response_;
  favicon_base::FaviconImageCallback favicon_service_b_site_response_;
  favicon_base::FaviconRawBitmapCallback
      favicon_service_a_site_raw_favicon_response_;
  favicon_base::FaviconRawBitmapCallback
      favicon_service_b_site_raw_favicon_response_;

  FaviconCache cache_;
};

TEST_F(FaviconCacheTest, Basic) {
  ExpectFaviconServiceForPageUrlCalls(1, 0);
  ExpectFaviconServiceForIconUrlCalls(0);

  int response_count = 0;
  gfx::Image result = cache_.GetFaviconForPageUrl(
      kUrlA, base::BindOnce(&VerifyFetchedFaviconAndCount, &response_count));

  // Expect the synchronous result to be empty.
  EXPECT_TRUE(result.IsEmpty());

  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());

  // Re-request the same favicon and expect a non-empty result now that the
  // cache is populated. The above EXPECT_CALL will also verify that the
  // backing FaviconService is not hit again.
  result = cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail));

  EXPECT_FALSE(result.IsEmpty());
  EXPECT_EQ(1, response_count);
}

TEST_F(FaviconCacheTest, Largest) {
  ExpectFaviconServiceForLargestFaviconPageUrlCalls(1, 0);
  ExpectFaviconServiceForIconUrlCalls(0);

  int response_count = 0;
  gfx::Image result = cache_.GetLargestFaviconForPageUrl(
      kUrlA, base::BindOnce(&VerifyFetchedFaviconAndCount, &response_count));

  // Expect the synchronous result to be empty.
  EXPECT_TRUE(result.IsEmpty());

  std::move(favicon_service_a_site_raw_favicon_response_)
      .Run(GetDummyRawFaviconResult());

  // Re-request the same favicon and expect a non-empty result now that the
  // cache is populated. The above EXPECT_CALL will also verify that the
  // backing FaviconService is not hit again.
  result = cache_.GetLargestFaviconForPageUrl(kUrlA, base::BindOnce(&Fail));

  EXPECT_FALSE(result.IsEmpty());
  EXPECT_EQ(1, response_count);
}

TEST_F(FaviconCacheTest, GetFaviconForIconUrl) {
  // Verify that the service receives a request by the icon URL.
  ExpectFaviconServiceForPageUrlCalls(0, 0);
  ExpectFaviconServiceForIconUrlCalls(1);

  // Since the other tests are comprehensive, we don't simulate or verify the
  // actual result.
  gfx::Image result =
      cache_.GetFaviconForIconUrl(kIconUrl, base::BindOnce(&Fail));
  EXPECT_TRUE(result.IsEmpty());
}

TEST_F(FaviconCacheTest, MultipleRequestsAreCoalesced) {
  ExpectFaviconServiceForPageUrlCalls(1, 0);

  int response_count = 0;
  for (int i = 0; i < 10; ++i) {
    cache_.GetFaviconForPageUrl(
        kUrlA, base::BindOnce(&VerifyFetchedFaviconAndCount, &response_count));
  }

  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());

  EXPECT_EQ(10, response_count);
}

TEST_F(FaviconCacheTest, SeparateOriginsAreCachedSeparately) {
  ExpectFaviconServiceForPageUrlCalls(1, 1);

  int a_site_response_count = 0;
  int b_site_response_count = 0;

  gfx::Image a_site_return = cache_.GetFaviconForPageUrl(
      kUrlA,
      base::BindOnce(&VerifyFetchedFaviconAndCount, &a_site_response_count));
  gfx::Image b_site_return = cache_.GetFaviconForPageUrl(
      kUrlB,
      base::BindOnce(&VerifyFetchedFaviconAndCount, &b_site_response_count));

  EXPECT_TRUE(a_site_return.IsEmpty());
  EXPECT_TRUE(b_site_return.IsEmpty());
  EXPECT_EQ(0, a_site_response_count);
  EXPECT_EQ(0, b_site_response_count);

  std::move(favicon_service_b_site_response_).Run(GetDummyFaviconResult());

  EXPECT_EQ(0, a_site_response_count);
  EXPECT_EQ(1, b_site_response_count);

  a_site_return = cache_.GetFaviconForPageUrl(
      kUrlA,
      base::BindOnce(&VerifyFetchedFaviconAndCount, &a_site_response_count));
  b_site_return = cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail));

  EXPECT_TRUE(a_site_return.IsEmpty());
  EXPECT_FALSE(b_site_return.IsEmpty());
  EXPECT_EQ(0, a_site_response_count);
  EXPECT_EQ(1, b_site_response_count);

  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());

  EXPECT_EQ(2, a_site_response_count);
  EXPECT_EQ(1, b_site_response_count);

  a_site_return = cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail));
  b_site_return = cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail));

  EXPECT_FALSE(a_site_return.IsEmpty());
  EXPECT_FALSE(b_site_return.IsEmpty());
}

TEST_F(FaviconCacheTest, ClearIconsWithHistoryDeletions) {
  ExpectFaviconServiceForPageUrlCalls(3, 2);

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());

  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());
  std::move(favicon_service_b_site_response_).Run(GetDummyFaviconResult());

  EXPECT_FALSE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
  EXPECT_FALSE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail)).IsEmpty());

  // Delete just the entry for kUrlA.
  history::URLRows a_rows = {history::URLRow(kUrlA)};
  cache_.OnHistoryDeletions(
      nullptr /* history_service */,
      history::DeletionInfo::ForUrls(a_rows, {} /* favicon_urls */));

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());
  EXPECT_FALSE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail)).IsEmpty());

  // Restore the cache entry for kUrlA.
  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());

  // Delete all history.
  cache_.OnHistoryDeletions(nullptr /* history_service */,
                            history::DeletionInfo::ForAllHistory());

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());
}

TEST_F(FaviconCacheTest, CacheNullFavicons) {
  ExpectFaviconServiceForPageUrlCalls(1, 0);

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
  std::move(favicon_service_a_site_response_)
      .Run(favicon_base::FaviconImageResult());

  // The mock FaviconService's EXPECT_CALL verifies that we do not make another
  // call to FaviconService.
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
}

TEST_F(FaviconCacheTest, ExpireNullFaviconsByHistory) {
  ExpectFaviconServiceForPageUrlCalls(2, 0);

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
  std::move(favicon_service_a_site_response_)
      .Run(favicon_base::FaviconImageResult());

  cache_.OnURLVisited(nullptr /* history_service */, history::URLRow(kUrlA),
                      history::VisitRow());

  // Now the empty favicon should have been expired and we expect our second
  // call to the mock underlying FaviconService.
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&VerifyFetchedFavicon))
          .IsEmpty());
  std::move(favicon_service_a_site_response_).Run(GetDummyFaviconResult());
  EXPECT_FALSE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
}

TEST_F(FaviconCacheTest, ObserveFaviconsChanged) {
  ExpectFaviconServiceForPageUrlCalls(2, 1);

  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail)).IsEmpty());

  // Simulate responses to both requests.
  std::move(favicon_service_a_site_response_)
      .Run(favicon_base::FaviconImageResult());
  std::move(favicon_service_b_site_response_)
      .Run(favicon_base::FaviconImageResult());

  cache_.OnFaviconsChanged({kUrlA}, GURL());

  // Request the two favicons again.
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlA, base::BindOnce(&Fail)).IsEmpty());
  EXPECT_TRUE(
      cache_.GetFaviconForPageUrl(kUrlB, base::BindOnce(&Fail)).IsEmpty());

  // Our call to |ExpectFaviconServiceForPageUrlCalls(expected A calls, expected
  // B calls)| above should verify that we re-request the icon for kUrlA only
  // (because the null result has been invalidated by OnFaviconsChanged).
}
