// 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 "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h"

#include <stddef.h>

#include "base/macros.h"
#include "chrome/browser/bitmap_fetcher/bitmap_fetcher.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace {

class TestNotificationInterface {
 public:
  virtual ~TestNotificationInterface() {}
  virtual void OnImageChanged() = 0;
  virtual void OnRequestFinished() = 0;
};

class TestObserver : public BitmapFetcherService::Observer {
 public:
  explicit TestObserver(TestNotificationInterface* target) : target_(target) {}
  ~TestObserver() override { target_->OnRequestFinished(); }

  void OnImageChanged(BitmapFetcherService::RequestId request_id,
                      const SkBitmap& answers_image) override {
    target_->OnImageChanged();
  }

 private:
  TestNotificationInterface* target_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

class TestService : public BitmapFetcherService {
 public:
  explicit TestService(content::BrowserContext* context)
      : BitmapFetcherService(context) {}
  ~TestService() override {}

  // Create a fetcher, but don't start downloading. That allows side-stepping
  // the decode step, which requires a utility process.
  std::unique_ptr<BitmapFetcher> CreateFetcher(
      const GURL& url,
      const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
    return std::make_unique<BitmapFetcher>(url, this, traffic_annotation);
  }
};

}  // namespace

class BitmapFetcherServiceTest : public testing::Test,
                                 public TestNotificationInterface {
 public:
  BitmapFetcherServiceTest()
      : url1_(GURL("http://example.org/sample-image-1.png")),
        url2_(GURL("http://example.org/sample-image-2.png")) {
  }

  void SetUp() override {
    service_.reset(new TestService(&profile_));
    requests_finished_ = 0;
    images_changed_ = 0;
  }

  const std::vector<std::unique_ptr<BitmapFetcherRequest>>& requests() const {
    return service_->requests_;
  }
  const std::vector<std::unique_ptr<BitmapFetcher>>& active_fetchers() const {
    return service_->active_fetchers_;
  }
  size_t cache_size() const { return service_->cache_.size(); }

  void OnImageChanged() override { images_changed_++; }

  void OnRequestFinished() override { requests_finished_++; }

  // Simulate finishing a URL fetch and decode for the given fetcher.
  void CompleteFetch(const GURL& url) {
    const BitmapFetcher* fetcher = service_->FindFetcherForUrl(url);
    ASSERT_TRUE(fetcher);

    // Create a non-empty bitmap.
    SkBitmap image;
    image.allocN32Pixels(2, 2);
    image.eraseColor(SK_ColorGREEN);

    const_cast<BitmapFetcher*>(fetcher)->OnImageDecoded(image);
  }

  void FailFetch(const GURL& url) {
    const BitmapFetcher* fetcher = service_->FindFetcherForUrl(url);
    ASSERT_TRUE(fetcher);
    const_cast<BitmapFetcher*>(fetcher)->OnImageDecoded(SkBitmap());
  }

  // A failed decode results in a nullptr image.
  void FailDecode(const GURL& url) {
    const BitmapFetcher* fetcher = service_->FindFetcherForUrl(url);
    ASSERT_TRUE(fetcher);
    const_cast<BitmapFetcher*>(fetcher)->OnDecodeImageFailed();
  }

 protected:
  std::unique_ptr<BitmapFetcherService> service_;

  int images_changed_;
  int requests_finished_;

  const GURL url1_;
  const GURL url2_;

 private:
  content::TestBrowserThreadBundle thread_bundle_;
  TestingProfile profile_;
};

TEST_F(BitmapFetcherServiceTest, RequestInvalidUrl) {
  const BitmapFetcherService::RequestId invalid_request_id =
      BitmapFetcherService::REQUEST_ID_INVALID;
  GURL invalid_url;
  ASSERT_FALSE(invalid_url.is_valid());

  BitmapFetcherService::RequestId request_id = service_->RequestImage(
      invalid_url, new TestObserver(this), TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(invalid_request_id, request_id);
}

TEST_F(BitmapFetcherServiceTest, CancelInvalidRequest) {
  service_->CancelRequest(BitmapFetcherService::REQUEST_ID_INVALID);
  service_->CancelRequest(23);
}

TEST_F(BitmapFetcherServiceTest, OnlyFirstRequestCreatesFetcher) {
  EXPECT_EQ(0U, active_fetchers().size());

  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(1U, active_fetchers().size());

  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(1U, active_fetchers().size());
}

TEST_F(BitmapFetcherServiceTest, CompletedFetchNotifiesAllObservers) {
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(1U, active_fetchers().size());
  EXPECT_EQ(4U, requests().size());

  CompleteFetch(url1_);
  EXPECT_EQ(4, images_changed_);
  EXPECT_EQ(4, requests_finished_);
}

TEST_F(BitmapFetcherServiceTest, CancelRequest) {
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  BitmapFetcherService::RequestId requestId = service_->RequestImage(
      url2_, new TestObserver(this), TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(5U, requests().size());

  service_->CancelRequest(requestId);
  EXPECT_EQ(4U, requests().size());

  CompleteFetch(url2_);
  EXPECT_EQ(0, images_changed_);

  CompleteFetch(url1_);
  EXPECT_EQ(4, images_changed_);
}

TEST_F(BitmapFetcherServiceTest, FailedNullRequestsAreHandled) {
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url2_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(0U, cache_size());

  CompleteFetch(url1_);
  EXPECT_EQ(1U, cache_size());

  FailDecode(url2_);
  EXPECT_EQ(1U, cache_size());
}
TEST_F(BitmapFetcherServiceTest, FailedRequestsDontEnterCache) {
  service_->RequestImage(url1_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  service_->RequestImage(url2_, new TestObserver(this),
                         TRAFFIC_ANNOTATION_FOR_TESTS);
  EXPECT_EQ(0U, cache_size());

  CompleteFetch(url1_);
  EXPECT_EQ(1U, cache_size());

  FailFetch(url2_);
  EXPECT_EQ(1U, cache_size());
}
