// 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 "chrome/browser/ui/webui/ntp/app_icon_webui_handler.h"

#include <stddef.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/url_constants.h"
#include "extensions/browser/extension_registry.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/color_analysis.h"

namespace {

std::unique_ptr<base::Value> GetDominantColorCssString(
    scoped_refptr<base::RefCountedMemory> png) {
  color_utils::GridSampler sampler;
  SkColor color = color_utils::CalculateKMeanColorOfPNG(png);
  return std::make_unique<base::Value>(
      base::StringPrintf("rgb(%d, %d, %d)", SkColorGetR(color),
                         SkColorGetG(color), SkColorGetB(color)));
}

}  // namespace

AppIconWebUIHandler::AppIconWebUIHandler() {
  extension_icon_manager_.set_observer(this);
}

AppIconWebUIHandler::~AppIconWebUIHandler() {}

void AppIconWebUIHandler::RegisterMessages() {
  web_ui()->RegisterMessageCallback(
      "getAppIconDominantColor",
      base::BindRepeating(&AppIconWebUIHandler::HandleGetAppIconDominantColor,
                          base::Unretained(this)));
}

void AppIconWebUIHandler::HandleGetAppIconDominantColor(
    const base::ListValue* args) {
  std::string extension_id;
  CHECK(args->GetString(0, &extension_id));

  Profile* profile = Profile::FromWebUI(web_ui());
  extensions::ExtensionRegistry* extension_registry =
      extensions::ExtensionRegistry::Get(profile);
  const extensions::Extension* extension =
      extension_registry->enabled_extensions().GetByID(extension_id);
  if (!extension)
    return;
  extension_icon_manager_.LoadIcon(profile, extension);
}

void AppIconWebUIHandler::OnImageLoaded(const std::string& extension_id) {
  gfx::Image icon = extension_icon_manager_.GetIcon(extension_id);
  // TODO(estade): would be nice to avoid a round trip through png encoding.
  std::vector<unsigned char> bits;
  if (!gfx::PNGCodec::EncodeBGRASkBitmap(*icon.ToSkBitmap(), true, &bits))
    return;
  scoped_refptr<base::RefCountedStaticMemory> bits_mem(
      new base::RefCountedStaticMemory(&bits.front(), bits.size()));
  std::unique_ptr<base::Value> color_value =
      GetDominantColorCssString(bits_mem);
  base::Value id(extension_id);
  web_ui()->CallJavascriptFunctionUnsafe("ntp.setFaviconDominantColor", id,
                                         *color_value);
}
