// Copyright 2019 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/ui/thumbnails/thumbnail_image.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/image/image_skia.h"

namespace {

constexpr int kTestBitmapWidth = 200;
constexpr int kTestBitmapHeight = 123;

template <typename... T>
base::RepeatingCallback<void(T...)> IgnoreArgs(
    base::RepeatingCallback<void()> cb) {
  auto helper = [](T...) {};
  return base::BindRepeating(helper).Then(std::move(cb));
}

class CallbackWaiter {
 public:
  CallbackWaiter() {
    callback_ = base::BindRepeating(&CallbackWaiter::HandleCallback,
                                    weak_ptr_factory_.GetWeakPtr());
  }

  base::RepeatingClosure callback() { return callback_; }

  bool called() const { return called_; }

  void Reset() { called_ = false; }

  void Wait() {
    if (called_)
      return;

    base::RunLoop run_loop;
    quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

 private:
  void HandleCallback() {
    if (quit_closure_)
      std::move(quit_closure_).Run();
    called_ = true;
  }

  base::RepeatingClosure callback_;
  base::OnceClosure quit_closure_;
  bool called_ = false;

  base::WeakPtrFactory<CallbackWaiter> weak_ptr_factory_{this};
};

class StubDelegate : public ThumbnailImage::Delegate {
 public:
  StubDelegate() = default;
  ~StubDelegate() override = default;

  // ThumbnailImage::Delegate:
  void ThumbnailImageBeingObservedChanged(bool is_being_observed) override {}
};

}  // anonymous namespace

class ThumbnailImageTest : public testing::Test,
                           public ThumbnailImage::Delegate {
 public:
  ThumbnailImageTest() = default;

  ThumbnailImageTest(const ThumbnailImageTest&) = delete;
  ThumbnailImageTest& operator=(const ThumbnailImageTest&) = delete;

 protected:
  static SkBitmap CreateBitmap(int width, int height) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(width, height);
    bitmap.eraseARGB(255, 0, 255, 0);
    return bitmap;
  }

  std::vector<uint8_t> Compress(SkBitmap bitmap) const {
    return ThumbnailImage::CompressBitmap(bitmap, absl::nullopt);
  }

  bool is_being_observed() const { return is_being_observed_; }

 private:
  void ThumbnailImageBeingObservedChanged(bool is_being_observed) override {
    is_being_observed_ = is_being_observed;
  }

  bool is_being_observed_ = false;
  base::test::TaskEnvironment task_environment_;
};

using Subscription = ThumbnailImage::Subscription;

TEST_F(ThumbnailImageTest, AddRemoveSubscriber) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);
  EXPECT_FALSE(is_being_observed());

  std::unique_ptr<Subscription> subscription = image->Subscribe();
  EXPECT_TRUE(is_being_observed());

  subscription.reset();
  EXPECT_FALSE(is_being_observed());
}

TEST_F(ThumbnailImageTest, AddRemoveMultipleObservers) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);
  EXPECT_FALSE(is_being_observed());

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();
  EXPECT_TRUE(is_being_observed());

  std::unique_ptr<Subscription> subscription2 = image->Subscribe();
  EXPECT_TRUE(is_being_observed());

  subscription1.reset();
  EXPECT_TRUE(is_being_observed());

  subscription2.reset();
  EXPECT_FALSE(is_being_observed());
}

TEST_F(ThumbnailImageTest, AssignSkBitmapNotifiesObservers) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();
  std::unique_ptr<Subscription> subscription2 = image->Subscribe();

  CallbackWaiter waiter1;
  subscription1->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter1.callback()));

  CallbackWaiter waiter2;
  subscription2->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter2.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());
}

TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesObserversAgain) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();
  std::unique_ptr<Subscription> subscription2 = image->Subscribe();

  CallbackWaiter waiter1;
  subscription1->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter1.callback()));

  CallbackWaiter waiter2;
  subscription2->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter2.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());

  waiter1.Reset();
  waiter2.Reset();

  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());
}

TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesCompressedObservers) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();
  std::unique_ptr<Subscription> subscription2 = image->Subscribe();

  CallbackWaiter waiter1;
  subscription1->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter1.callback()));

  CallbackWaiter waiter2;
  subscription2->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter2.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());
}

TEST_F(ThumbnailImageTest, AssignSkBitmap_NotifiesCompressedObserversAgain) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();
  std::unique_ptr<Subscription> subscription2 = image->Subscribe();

  CallbackWaiter waiter1;
  subscription1->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter1.callback()));

  CallbackWaiter waiter2;
  subscription2->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter2.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());

  waiter1.Reset();
  waiter2.Reset();

  image->AssignSkBitmap(bitmap, absl::nullopt);

  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());
}

TEST_F(ThumbnailImageTest, RequestThumbnailImage) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription1 = image->Subscribe();

  CallbackWaiter waiter1;
  subscription1->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter1.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);
  waiter1.Wait();
  EXPECT_TRUE(waiter1.called());
  waiter1.Reset();

  std::unique_ptr<Subscription> subscription2 = image->Subscribe();

  CallbackWaiter waiter2;
  subscription2->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(waiter2.callback()));

  image->RequestThumbnailImage();
  waiter1.Wait();
  waiter2.Wait();
  EXPECT_TRUE(waiter1.called());
  EXPECT_TRUE(waiter2.called());
}

TEST_F(ThumbnailImageTest, RequestCompressedThumbnailData) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription = image->Subscribe();

  CallbackWaiter waiter;
  subscription->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(waiter.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);
  waiter.Wait();
  EXPECT_TRUE(waiter.called());
  waiter.Reset();

  image->RequestCompressedThumbnailData();
  waiter.Wait();
  EXPECT_TRUE(waiter.called());
}

TEST_F(ThumbnailImageTest, ClearThumbnailAfterAssignBitmap) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription = image->Subscribe();

  CallbackWaiter uncompressed_image_waiter;
  subscription->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(uncompressed_image_waiter.callback()));

  CallbackWaiter compressed_image_waiter;
  subscription->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(
          compressed_image_waiter.callback()));

  CallbackWaiter async_operation_finished_waiter;
  image->set_async_operation_finished_callback_for_testing(
      async_operation_finished_waiter.callback());

  // No observers should be notified if the thumbnail is cleared just
  // after assigning a bitmap.
  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);
  image->ClearData();
  async_operation_finished_waiter.Wait();
  EXPECT_TRUE(async_operation_finished_waiter.called());
  EXPECT_FALSE(uncompressed_image_waiter.called());
  EXPECT_FALSE(compressed_image_waiter.called());
}

TEST_F(ThumbnailImageTest, ClearExistingThumbnailNotifiesObservers) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription = image->Subscribe();

  CallbackWaiter uncompressed_image_waiter;
  subscription->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(uncompressed_image_waiter.callback()));

  CallbackWaiter compressed_image_waiter;
  subscription->SetCompressedImageCallback(
      IgnoreArgs<ThumbnailImage::CompressedThumbnailData>(
          compressed_image_waiter.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);
  compressed_image_waiter.Wait();
  uncompressed_image_waiter.Wait();
  EXPECT_TRUE(compressed_image_waiter.called());
  EXPECT_TRUE(uncompressed_image_waiter.called());
  compressed_image_waiter.Reset();
  uncompressed_image_waiter.Reset();

  image->ClearData();
  compressed_image_waiter.Wait();
  uncompressed_image_waiter.Wait();
  EXPECT_TRUE(compressed_image_waiter.called());
  EXPECT_TRUE(uncompressed_image_waiter.called());
}

// Makes sure a null dereference does not happen. Regression test for
// crbug.com/1159701.
TEST_F(ThumbnailImageTest, UnsubscribeAfterDelegateDestroyed) {
  auto delegate = std::make_unique<StubDelegate>();
  auto image = base::MakeRefCounted<ThumbnailImage>(delegate.get());

  std::unique_ptr<Subscription> subscription = image->Subscribe();

  // Normally |image| will notify its delegate when the last
  // subscription is destroyed. When there is no delegate it shouldn't
  // do anything.
  delegate.reset();
  subscription.reset();
}

// Ensures subscribers with a size hint get notified correctly on
// thumbnail clear. Regression test for crbug.com/1168483 where
// CropPreviewImage was called on blank thumbnails resulting in a
// DCHECK.
TEST_F(ThumbnailImageTest, DoesNotCropBlankThumbnails) {
  auto image = base::MakeRefCounted<ThumbnailImage>(this);

  std::unique_ptr<Subscription> subscription = image->Subscribe();
  subscription->SetSizeHint(
      gfx::Size(kTestBitmapWidth / 2, kTestBitmapHeight / 2));

  CallbackWaiter uncompressed_image_waiter;
  subscription->SetUncompressedImageCallback(
      IgnoreArgs<gfx::ImageSkia>(uncompressed_image_waiter.callback()));

  SkBitmap bitmap = CreateBitmap(kTestBitmapWidth, kTestBitmapHeight);
  image->AssignSkBitmap(bitmap, absl::nullopt);
  uncompressed_image_waiter.Wait();
  EXPECT_TRUE(uncompressed_image_waiter.called());
  uncompressed_image_waiter.Reset();

  image->ClearData();
  uncompressed_image_waiter.Wait();
  EXPECT_TRUE(uncompressed_image_waiter.called());
}
