// 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/extensions/extension_action_storage_manager.h"

#include <stdint.h>

#include <memory>
#include <utility>

#include "base/base64.h"
#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/browser/extensions/extension_action_manager.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extension_system.h"
#include "extensions/browser/state_store.h"
#include "extensions/common/constants.h"
#include "ui/base/layout.h"
#include "ui/gfx/codec/png_codec.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"

namespace extensions {

namespace {

const char kBrowserActionStorageKey[] = "browser_action";
const char kPopupUrlStorageKey[] = "poupup_url";
const char kTitleStorageKey[] = "title";
const char kIconStorageKey[] = "icon";
const char kBadgeTextStorageKey[] = "badge_text";
const char kBadgeBackgroundColorStorageKey[] = "badge_background_color";
const char kBadgeTextColorStorageKey[] = "badge_text_color";
const char kAppearanceStorageKey[] = "appearance";

// Only add values to the end of this enum, since it's stored in the user's
// Extension State, under the kAppearanceStorageKey.  It represents the
// ExtensionAction's default visibility.
enum StoredAppearance {
  // The action icon is hidden.
  INVISIBLE = 0,
  // The action is trying to get the user's attention but isn't yet
  // running on the page.  Was only used for script badges.
  OBSOLETE_WANTS_ATTENTION = 1,
  // The action icon is visible with its normal appearance.
  ACTIVE = 2,
};

// Conversion function for reading/writing to storage.
SkColor RawStringToSkColor(const std::string& str) {
  uint64_t value = 0;
  base::StringToUint64(str, &value);
  SkColor color = static_cast<SkColor>(value);
  DCHECK(value == color);  // ensure value fits into color's 32 bits
  return color;
}

// Conversion function for reading/writing to storage.
std::string SkColorToRawString(SkColor color) {
  return base::NumberToString(color);
}

// Conversion function for reading/writing to storage.
bool StringToSkBitmap(const std::string& str, SkBitmap* bitmap) {
  // TODO(mpcomplete): Remove the base64 encode/decode step when
  // http://crbug.com/140546 is fixed.
  std::string raw_str;
  if (!base::Base64Decode(str, &raw_str))
    return false;

  bool success = gfx::PNGCodec::Decode(
      reinterpret_cast<unsigned const char*>(raw_str.data()), raw_str.size(),
      bitmap);
  return success;
}

// Conversion function for reading/writing to storage.
std::string BitmapToString(const SkBitmap& bitmap) {
  std::vector<unsigned char> data;
  bool success = gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &data);
  if (!success)
    return std::string();

  base::StringPiece raw_str(
      reinterpret_cast<const char*>(&data[0]), data.size());
  std::string base64_str;
  base::Base64Encode(raw_str, &base64_str);
  return base64_str;
}

// Set |action|'s default values to those specified in |dict|.
void SetDefaultsFromValue(const base::DictionaryValue* dict,
                          ExtensionAction* action) {
  const int kDefaultTabId = ExtensionAction::kDefaultTabId;
  std::string str_value;

  // For each value, don't set it if it has been modified already.
  if (dict->GetString(kPopupUrlStorageKey, &str_value) &&
      !action->HasPopupUrl(kDefaultTabId)) {
    action->SetPopupUrl(kDefaultTabId, GURL(str_value));
  }
  if (dict->GetString(kTitleStorageKey, &str_value) &&
      !action->HasTitle(kDefaultTabId)) {
    action->SetTitle(kDefaultTabId, str_value);
  }
  if (dict->GetString(kBadgeTextStorageKey, &str_value) &&
      !action->HasBadgeText(kDefaultTabId)) {
    action->SetBadgeText(kDefaultTabId, str_value);
  }
  if (dict->GetString(kBadgeBackgroundColorStorageKey, &str_value) &&
      !action->HasBadgeBackgroundColor(kDefaultTabId)) {
    action->SetBadgeBackgroundColor(kDefaultTabId,
                                    RawStringToSkColor(str_value));
  }
  if (dict->GetString(kBadgeTextColorStorageKey, &str_value) &&
      !action->HasBadgeTextColor(kDefaultTabId)) {
    action->SetBadgeTextColor(kDefaultTabId, RawStringToSkColor(str_value));
  }

  int appearance_storage = 0;
  if (dict->GetInteger(kAppearanceStorageKey, &appearance_storage) &&
      !action->HasIsVisible(kDefaultTabId)) {
    switch (appearance_storage) {
      case INVISIBLE:
      case OBSOLETE_WANTS_ATTENTION:
        action->SetIsVisible(kDefaultTabId, false);
        break;
      case ACTIVE:
        action->SetIsVisible(kDefaultTabId, true);
        break;
    }
  }

  const base::DictionaryValue* icon_value = NULL;
  if (dict->GetDictionary(kIconStorageKey, &icon_value) &&
      !action->HasIcon(kDefaultTabId)) {
    gfx::ImageSkia icon;
    SkBitmap bitmap;
    for (base::DictionaryValue::Iterator iter(*icon_value); !iter.IsAtEnd();
         iter.Advance()) {
      int icon_size = 0;
      std::string icon_string;
      if (base::StringToInt(iter.key(), &icon_size) &&
          iter.value().GetAsString(&icon_string) &&
          StringToSkBitmap(icon_string, &bitmap)) {
        CHECK(!bitmap.isNull());
        float scale =
            static_cast<float>(icon_size) / ExtensionAction::ActionIconSize();
        icon.AddRepresentation(gfx::ImageSkiaRep(bitmap, scale));
      }
    }
    action->SetIcon(kDefaultTabId, gfx::Image(icon));
  }
}

// Store |action|'s default values in a DictionaryValue for use in storing to
// disk.
std::unique_ptr<base::DictionaryValue> DefaultsToValue(
    ExtensionAction* action) {
  const int kDefaultTabId = ExtensionAction::kDefaultTabId;
  std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());

  dict->SetString(kPopupUrlStorageKey,
                  action->GetPopupUrl(kDefaultTabId).spec());
  dict->SetString(kTitleStorageKey, action->GetTitle(kDefaultTabId));
  dict->SetString(kBadgeTextStorageKey, action->GetBadgeText(kDefaultTabId));
  dict->SetString(
      kBadgeBackgroundColorStorageKey,
      SkColorToRawString(action->GetBadgeBackgroundColor(kDefaultTabId)));
  dict->SetString(kBadgeTextColorStorageKey,
                  SkColorToRawString(action->GetBadgeTextColor(kDefaultTabId)));
  dict->SetInteger(kAppearanceStorageKey,
                   action->GetIsVisible(kDefaultTabId) ? ACTIVE : INVISIBLE);

  gfx::ImageSkia icon =
      action->GetExplicitlySetIcon(kDefaultTabId).AsImageSkia();
  if (!icon.isNull()) {
    std::unique_ptr<base::DictionaryValue> icon_value(
        new base::DictionaryValue());
    std::vector<gfx::ImageSkiaRep> image_reps = icon.image_reps();
    for (const gfx::ImageSkiaRep& rep : image_reps) {
      int size = static_cast<int>(rep.scale() * icon.width());
      std::string size_string = base::NumberToString(size);
      icon_value->SetString(size_string, BitmapToString(rep.GetBitmap()));
    }
    dict->Set(kIconStorageKey, std::move(icon_value));
  }
  return dict;
}

}  // namespace

ExtensionActionStorageManager::ExtensionActionStorageManager(
    content::BrowserContext* context)
    : browser_context_(context),
      extension_action_observer_(this),
      extension_registry_observer_(this),
      weak_factory_(this) {
  extension_action_observer_.Add(ExtensionActionAPI::Get(browser_context_));
  extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_));

  StateStore* store = GetStateStore();
  if (store)
    store->RegisterKey(kBrowserActionStorageKey);
}

ExtensionActionStorageManager::~ExtensionActionStorageManager() {
}

void ExtensionActionStorageManager::OnExtensionLoaded(
    content::BrowserContext* browser_context,
    const Extension* extension) {
  ExtensionAction* action = ExtensionActionManager::Get(browser_context_)
                                ->GetExtensionAction(*extension);
  if (!action || action->action_type() != ActionInfo::TYPE_BROWSER)
    return;

  StateStore* store = GetStateStore();
  if (store) {
    store->GetExtensionValue(
        extension->id(),
        kBrowserActionStorageKey,
        base::Bind(&ExtensionActionStorageManager::ReadFromStorage,
                   weak_factory_.GetWeakPtr(),
                   extension->id()));
  }
}

void ExtensionActionStorageManager::OnExtensionActionUpdated(
    ExtensionAction* extension_action,
    content::WebContents* web_contents,
    content::BrowserContext* browser_context) {
  // This is an update to the default settings of the action iff |web_contents|
  // is null. We only persist the default settings to disk, since per-tab
  // settings can't be persisted across browser sessions.
  bool for_default_tab = !web_contents;
  // TODO(devlin): We should probably persist for TYPE_ACTION as well.
  if (browser_context_ == browser_context &&
      extension_action->action_type() == ActionInfo::TYPE_BROWSER &&
      for_default_tab) {
    WriteToStorage(extension_action);
  }
}

void ExtensionActionStorageManager::OnExtensionActionAPIShuttingDown() {
  extension_action_observer_.RemoveAll();
}

void ExtensionActionStorageManager::WriteToStorage(
    ExtensionAction* extension_action) {
  StateStore* store = GetStateStore();
  if (store) {
    std::unique_ptr<base::DictionaryValue> defaults =
        DefaultsToValue(extension_action);
    store->SetExtensionValue(extension_action->extension_id(),
                             kBrowserActionStorageKey, std::move(defaults));
  }
}

void ExtensionActionStorageManager::ReadFromStorage(
    const std::string& extension_id,
    std::unique_ptr<base::Value> value) {
  const Extension* extension = ExtensionRegistry::Get(browser_context_)->
      enabled_extensions().GetByID(extension_id);
  if (!extension)
    return;

  ExtensionAction* action = ExtensionActionManager::Get(browser_context_)
                                ->GetExtensionAction(*extension);
  if (!action || action->action_type() != ActionInfo::TYPE_BROWSER) {
    // This can happen if the extension is updated between startup and when the
    // storage read comes back, and the update removes the browser action.
    // http://crbug.com/349371
    return;
  }

  const base::DictionaryValue* dict = NULL;
  if (!value.get() || !value->GetAsDictionary(&dict))
    return;

  SetDefaultsFromValue(dict, action);
}

StateStore* ExtensionActionStorageManager::GetStateStore() {
  return ExtensionSystem::Get(browser_context_)->state_store();
}

}  // namespace extensions
