// 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 "ui/app_list/folder_image.h"

#include <string>
#include <utility>

#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_item_list.h"
#include "ui/app_list/app_list_model.h"
#include "ui/gfx/skia_util.h"

namespace app_list {

namespace {

gfx::ImageSkia CreateSquareBitmapWithColor(int size, SkColor color) {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(size, size);
  bitmap.eraseColor(color);
  return gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
}

bool ImagesAreEqual(const gfx::ImageSkia& image1,
                    const gfx::ImageSkia& image2) {
  return gfx::BitmapsAreEqual(*image1.bitmap(), *image2.bitmap());
}

// Listens for OnFolderImageUpdated and sets a flag upon receiving the signal.
class TestFolderImageObserver : public FolderImageObserver {
 public:
  TestFolderImageObserver() : updated_flag_(false) {}

  bool updated() const { return updated_flag_; }

  void Reset() { updated_flag_ = false; }

  // FolderImageObserver overrides:
  void OnFolderImageUpdated() override { updated_flag_ = true; }

 private:
  bool updated_flag_;

  DISALLOW_COPY_AND_ASSIGN(TestFolderImageObserver);
};

}  // namespace

class FolderImageTest : public testing::Test {
 public:
  FolderImageTest() : folder_image_(app_list_model_.top_level_item_list()) {}

  ~FolderImageTest() override {}

  void SetUp() override {
    // Populate the AppListModel with three items (to test that the FolderImage
    // correctly supports having fewer than four icons).
    AddAppWithColoredIcon("app1", SK_ColorRED);
    AddAppWithColoredIcon("app2", SK_ColorGREEN);
    AddAppWithColoredIcon("app3", SK_ColorBLUE);

    observer_.Reset();
    folder_image_.AddObserver(&observer_);
  }

  void TearDown() override { folder_image_.RemoveObserver(&observer_); }

 protected:
  void AddAppWithColoredIcon(const std::string& id, SkColor icon_color) {
    std::unique_ptr<AppListItem> item(new AppListItem(id));
    item->SetIcon(CreateSquareBitmapWithColor(kListIconSize, icon_color));
    app_list_model_.AddItem(std::move(item));
  }

  AppListModel app_list_model_;

  FolderImage folder_image_;

  TestFolderImageObserver observer_;

 private:
  DISALLOW_COPY_AND_ASSIGN(FolderImageTest);
};

TEST_F(FolderImageTest, UpdateListTest) {
  gfx::ImageSkia icon1 = folder_image_.icon();

  // Call UpdateIcon and ensure that the observer event fired.
  folder_image_.UpdateIcon();
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  // The icon should not have changed.
  EXPECT_TRUE(ImagesAreEqual(icon1, folder_image_.icon()));

  // Swap two items. Ensure that the observer fired and the icon changed.
  app_list_model_.top_level_item_list()->MoveItem(2, 1);
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  gfx::ImageSkia icon2 = folder_image_.icon();
  EXPECT_FALSE(ImagesAreEqual(icon1, icon2));

  // Swap back items. Ensure that the observer fired and the icon changed back.
  app_list_model_.top_level_item_list()->MoveItem(2, 1);
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  EXPECT_TRUE(ImagesAreEqual(icon1, folder_image_.icon()));

  // Add a new item. Ensure that the observer fired and the icon changed.
  AddAppWithColoredIcon("app4", SK_ColorYELLOW);
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  gfx::ImageSkia icon3 = folder_image_.icon();
  EXPECT_FALSE(ImagesAreEqual(icon1, icon3));

  // Add a new item. The observer should not fire, nor should the icon change
  // (because it does not affect the first four icons).
  AddAppWithColoredIcon("app5", SK_ColorCYAN);
  EXPECT_FALSE(observer_.updated());
  observer_.Reset();
  EXPECT_TRUE(ImagesAreEqual(icon3, folder_image_.icon()));

  // Delete an item. Ensure that the observer fired and the icon changed.
  app_list_model_.DeleteItem("app2");
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  gfx::ImageSkia icon4 = folder_image_.icon();
  EXPECT_FALSE(ImagesAreEqual(icon3, icon4));
}

TEST_F(FolderImageTest, UpdateItemTest) {
  gfx::ImageSkia icon1 = folder_image_.icon();

  // Change an item's icon. Ensure that the observer fired and the icon changed.
  app_list_model_.FindItem("app2")
      ->SetIcon(CreateSquareBitmapWithColor(kListIconSize, SK_ColorMAGENTA));
  EXPECT_TRUE(observer_.updated());
  observer_.Reset();
  EXPECT_FALSE(ImagesAreEqual(icon1, folder_image_.icon()));
}

}  // namespace app_list
