// Copyright 2017 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 <memory>
#include <vector>

#include "base/macros.h"
#include "base/run_loop.h"
#include "chrome/browser/extensions/chrome_app_icon.h"
#include "chrome/browser/extensions/chrome_app_icon_delegate.h"
#include "chrome/browser/extensions/chrome_app_icon_loader.h"
#include "chrome/browser/extensions/chrome_app_icon_service.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_icon_loader_delegate.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/testing_profile.h"
#include "extensions/common/constants.h"
#include "ui/gfx/image/image_unittest_util.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
#include "chrome/browser/ui/app_list/extension_app_model_builder.h"
#include "chrome/browser/ui/app_list/search/extension_app_result.h"
#include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h"
#include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
#include "components/arc/test/fake_app_instance.h"
#endif  // defined(OS_CHROMEOS)

namespace extensions {

namespace {

constexpr char kTestAppId[] = "emfkafnhnpcmabnnkckkchdilgeoekbo";

// Receives icon image updates from ChromeAppIcon.
class TestAppIcon : public ChromeAppIconDelegate {
 public:
  TestAppIcon(content::BrowserContext* context,
              const std::string& app_id,
              int size) {
    app_icon_ =
        ChromeAppIconService::Get(context)->CreateIcon(this, app_id, size);
    DCHECK(app_icon_);
  }

  ~TestAppIcon() override = default;

  void Reset() { app_icon_.reset(); }

  int GetIconUpdateCountAndReset() {
    int icon_update_count = icon_update_count_;
    icon_update_count_ = 0;
    return icon_update_count;
  }

  size_t icon_update_count() const { return icon_update_count_; }
  ChromeAppIcon* app_icon() { return app_icon_.get(); }
  const gfx::ImageSkia& image_skia() const { return app_icon_->image_skia(); }

  void WaitForIconUpdates() {
    base::RunLoop run_loop;
    icon_update_count_expected_ =
        icon_update_count_ + image_skia().image_reps().size();
    icon_updated_callback_ = run_loop.QuitClosure();
    run_loop.Run();
  }

 private:
  void OnIconUpdated(ChromeAppIcon* icon) override {
    ++icon_update_count_;
    if (icon_update_count_ == icon_update_count_expected_ &&
        !icon_updated_callback_.is_null()) {
      base::ResetAndReturn(&icon_updated_callback_).Run();
    }
  }

  std::unique_ptr<ChromeAppIcon> app_icon_;

  size_t icon_update_count_ = 0;
  size_t icon_update_count_expected_ = 0;

  base::OnceClosure icon_updated_callback_;

  DISALLOW_COPY_AND_ASSIGN(TestAppIcon);
};

// Receives icon image updates from ChromeAppIconLoader.
class TestAppIconLoader : public AppIconLoaderDelegate {
 public:
  TestAppIconLoader() = default;
  ~TestAppIconLoader() override = default;

  // AppIconLoaderDelegate:
  void OnAppImageUpdated(const std::string& app_id,
                         const gfx::ImageSkia& image) override {
    image_skia_ = image;
  }

  gfx::ImageSkia& icon() { return image_skia_; }
  const gfx::ImageSkia& icon() const { return image_skia_; }

 private:
  gfx::ImageSkia image_skia_;

  DISALLOW_COPY_AND_ASSIGN(TestAppIconLoader);
};

// Returns true if provided |image| consists from only empty pixels.
bool IsBlankImage(const gfx::ImageSkia& image) {
  if (!image.width() || !image.height())
    return false;

  const SkBitmap* bitmap = image.bitmap();
  DCHECK(bitmap);
  DCHECK_EQ(bitmap->width(), image.width());
  DCHECK_EQ(bitmap->height(), image.height());

  for (int x = 0; x < bitmap->width(); ++x) {
    for (int y = 0; y < bitmap->height(); ++y) {
      if (*bitmap->getAddr32(x, y))
        return false;
    }
  }
  return true;
}

// Returns true if provided |image| is grayscale.
bool IsGrayscaleImage(const gfx::ImageSkia& image) {
  const SkBitmap* bitmap = image.bitmap();
  DCHECK(bitmap);
  for (int x = 0; x < bitmap->width(); ++x) {
    for (int y = 0; y < bitmap->height(); ++y) {
      const unsigned int pixel = *bitmap->getAddr32(x, y);
      if ((pixel & 0xff) != ((pixel >> 8) & 0xff) ||
          (pixel & 0xff) != ((pixel >> 16) & 0xff)) {
        return false;
      }
    }
  }
  return true;
}

// Returns true if provided |image1| and |image2| are equal.
bool AreEqual(const gfx::ImageSkia& image1, const gfx::ImageSkia& image2) {
  return gfx::test::AreImagesEqual(gfx::Image(image1), gfx::Image(image2));
}

#if defined(OS_CHROMEOS)

bool AreAllImageRepresentationsDifferent(const gfx::ImageSkia& image1,
                                         const gfx::ImageSkia& image2) {
  const std::vector<gfx::ImageSkiaRep> image1_reps = image1.image_reps();
  const std::vector<gfx::ImageSkiaRep> image2_reps = image2.image_reps();
  DCHECK_EQ(image1_reps.size(), image2_reps.size());
  for (size_t i = 0; i < image1_reps.size(); ++i) {
    const float scale = image1_reps[i].scale();
    const gfx::ImageSkiaRep& image_rep2 = image2.GetRepresentation(scale);
    if (gfx::test::AreBitmapsClose(image1_reps[i].sk_bitmap(),
                                   image_rep2.sk_bitmap(), 0)) {
      return false;
    }
  }
  return true;
}

// Waits until icon content of the item is changed for all representations.
template <typename T>
void WaitForIconUpdates(const T& item) {
  item.icon().EnsureRepsForSupportedScales();
  std::unique_ptr<gfx::ImageSkia> reference_image = item.icon().DeepCopy();
  while (!AreAllImageRepresentationsDifferent(*reference_image, item.icon()))
    base::RunLoop().RunUntilIdle();
}

#endif  // defined(OS_CHROMEOS)

}  // namespace

class ChromeAppIconTest : public ExtensionServiceTestBase {
 public:
  ChromeAppIconTest() = default;
  ~ChromeAppIconTest() override = default;

  // ExtensionServiceTestBase:
  void SetUp() override {
    ExtensionServiceTestBase::SetUp();

    const base::FilePath source_install_dir =
        data_dir().AppendASCII("app_list").AppendASCII("Extensions");
    const base::FilePath pref_path =
        source_install_dir.DirName().Append(chrome::kPreferencesFilename);
    InitializeInstalledExtensionService(pref_path, source_install_dir);
    service_->Init();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ChromeAppIconTest);
};

TEST_F(ChromeAppIconTest, IconLifeCycle) {
  TestAppIcon reference_icon(profile(), kTestAppId,
                             extension_misc::EXTENSION_ICON_MEDIUM);
  EXPECT_EQ(1U, reference_icon.icon_update_count());
  // By default no representation in image.
  EXPECT_FALSE(reference_icon.image_skia().HasRepresentation(1.0f));

  // Default blank image must be provided without an update.
  EXPECT_FALSE(reference_icon.image_skia().GetRepresentation(1.0f).is_null());
  EXPECT_EQ(1U, reference_icon.icon_update_count());
  EXPECT_TRUE(reference_icon.image_skia().HasRepresentation(1.0f));
  EXPECT_EQ(extension_misc::EXTENSION_ICON_MEDIUM,
            reference_icon.image_skia().width());
  EXPECT_EQ(extension_misc::EXTENSION_ICON_MEDIUM,
            reference_icon.image_skia().height());
  EXPECT_TRUE(IsBlankImage(reference_icon.image_skia()));

  // Wait until real image is loaded.
  reference_icon.WaitForIconUpdates();
  EXPECT_EQ(2U, reference_icon.icon_update_count());
  EXPECT_FALSE(IsBlankImage(reference_icon.image_skia()));
  EXPECT_FALSE(IsGrayscaleImage(reference_icon.image_skia()));

  const gfx::ImageSkia image_before_disable = reference_icon.image_skia();
  // Disable extension. This should update icon and provide grayed image inline.
  // Note update might be sent twice in CrOS.
  service()->DisableExtension(kTestAppId, disable_reason::DISABLE_CORRUPTED);
  const size_t update_count_after_disable = reference_icon.icon_update_count();
  EXPECT_NE(2U, update_count_after_disable);
  EXPECT_FALSE(IsBlankImage(reference_icon.image_skia()));
  EXPECT_TRUE(IsGrayscaleImage(reference_icon.image_skia()));

  // Reenable extension. It should match previous enabled image
  service()->EnableExtension(kTestAppId);
  EXPECT_NE(update_count_after_disable, reference_icon.icon_update_count());
  EXPECT_TRUE(AreEqual(reference_icon.image_skia(), image_before_disable));
}

// Validates that icon release is safe.
TEST_F(ChromeAppIconTest, IconRelease) {
  TestAppIcon test_icon1(profile(), kTestAppId,
                         extension_misc::EXTENSION_ICON_MEDIUM);
  TestAppIcon test_icon2(profile(), kTestAppId,
                         extension_misc::EXTENSION_ICON_MEDIUM);
  EXPECT_FALSE(test_icon1.image_skia().GetRepresentation(1.0f).is_null());
  EXPECT_FALSE(test_icon2.image_skia().GetRepresentation(1.0f).is_null());

  // Reset before service is stopped.
  test_icon1.Reset();

  // Reset after service is stopped.
  profile_.reset();
  test_icon2.Reset();
}

#if defined(OS_CHROMEOS)

class ChromeAppIconWithModelTest : public ChromeAppIconTest {
 public:
  ChromeAppIconWithModelTest() = default;
  ~ChromeAppIconWithModelTest() override = default;

 protected:
  void CreateBuilder() {
    model_updater_ = std::make_unique<FakeAppListModelUpdater>();
    controller_ = std::make_unique<test::TestAppListControllerDelegate>();
    builder_ = std::make_unique<ExtensionAppModelBuilder>(controller_.get());
    builder_->Initialize(nullptr, profile(), model_updater_.get());
  }

  void ResetBuilder() {
    builder_.reset();
    controller_.reset();
    model_updater_.reset();
  }

  ChromeAppListItem* FindAppListItem(const std::string& app_id) {
    return model_updater_->FindItem(app_id);
  }

  test::TestAppListControllerDelegate* app_list_controller() {
    return controller_.get();
  }

 private:
  std::unique_ptr<FakeAppListModelUpdater> model_updater_;
  std::unique_ptr<test::TestAppListControllerDelegate> controller_;
  std::unique_ptr<ExtensionAppModelBuilder> builder_;

  DISALLOW_COPY_AND_ASSIGN(ChromeAppIconWithModelTest);
};

// Validates that icons are the same for different consumers.
TEST_F(ChromeAppIconWithModelTest, IconsTheSame) {
  CreateBuilder();

  // App list item is already created. Wait until all image representations are
  // updated and take image snapshot.
  ChromeAppListItem* app_list_item = FindAppListItem(kTestAppId);
  ASSERT_TRUE(app_list_item);
  WaitForIconUpdates<ChromeAppListItem>(*app_list_item);
  std::unique_ptr<gfx::ImageSkia> app_list_item_image =
      app_list_item->icon().DeepCopy();

  // Load reference icon.
  TestAppIcon reference_icon(profile(), kTestAppId,
                             extension_misc::EXTENSION_ICON_MEDIUM);

  // Wait until reference data is loaded.
  reference_icon.image_skia().EnsureRepsForSupportedScales();
  reference_icon.WaitForIconUpdates();
  EXPECT_FALSE(IsBlankImage(reference_icon.image_skia()));

  // Now compare with app list icon snapshot.
  EXPECT_TRUE(AreEqual(reference_icon.image_skia(), *app_list_item_image));

  app_list::ExtensionAppResult search(profile(), kTestAppId,
                                      app_list_controller(), true);
  WaitForIconUpdates<app_list::ExtensionAppResult>(search);
  EXPECT_TRUE(AreEqual(reference_icon.image_skia(), search.icon()));

  TestAppIconLoader loader_delegate;
  ChromeAppIconLoader loader(profile(), extension_misc::EXTENSION_ICON_MEDIUM,
                             &loader_delegate);
  loader.FetchImage(kTestAppId);
  WaitForIconUpdates<TestAppIconLoader>(loader_delegate);
  EXPECT_TRUE(AreEqual(reference_icon.image_skia(), loader_delegate.icon()));

  ResetBuilder();
}

TEST_F(ChromeAppIconTest, ChromeBadging) {
  ArcAppTest arc_test;
  arc_test.SetUp(profile());

  TestAppIcon reference_icon(profile(), kTestAppId,
                             extension_misc::EXTENSION_ICON_MEDIUM);
  // Wait until reference data is loaded.
  EXPECT_FALSE(reference_icon.image_skia().GetRepresentation(1.0f).is_null());
  reference_icon.WaitForIconUpdates();
  EXPECT_FALSE(IsBlankImage(reference_icon.image_skia()));

  reference_icon.GetIconUpdateCountAndReset();
  const gfx::ImageSkia image_before_badging = reference_icon.image_skia();

  // Badging should be applied once package is installed.
  arc_test.app_instance()->RefreshAppList();
  std::vector<arc::mojom::AppInfo> fake_apps = arc_test.fake_apps();
  fake_apps[0].package_name = arc_test.fake_packages()[0].package_name;
  arc_test.app_instance()->SendRefreshAppList(fake_apps);
  arc_test.app_instance()->SendRefreshPackageList(arc_test.fake_packages());
  EXPECT_EQ(1U, reference_icon.icon_update_count());
  EXPECT_FALSE(AreEqual(reference_icon.image_skia(), image_before_badging));

  // Opts out the Play Store. Badge should be gone and icon image is the same
  // as it was before badging.
  arc::SetArcPlayStoreEnabledForProfile(profile(), false);
  EXPECT_EQ(2U, reference_icon.icon_update_count());
  EXPECT_TRUE(AreEqual(reference_icon.image_skia(), image_before_badging));
}

#endif  // defined(OS_CHROMEOS)

}  // namespace extensions
