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

#include "base/strings/string_number_conversions.h"
#include "chrome/browser/extensions/extension_action.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_builder.h"
#include "extensions/common/manifest_handlers/icons_handler.h"
#include "extensions/common/value_builder.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

const char kBrowserAction[] = "browser_action";
const char kPageAction[] = "page_action";

}  // namespace

class ExtensionActionManagerTest : public testing::Test {
 public:
  ExtensionActionManagerTest();

 protected:
  // Build an extension, populating |action_type| key with |action|, and
  // "icons" key with |extension_icons|.
  scoped_refptr<Extension> BuildExtension(
      scoped_ptr<base::DictionaryValue> extension_icons,
      scoped_ptr<base::DictionaryValue> action,
      const char* action_type);

  // Returns true if |action|'s title matches |extension|'s name.
  bool TitlesMatch(const Extension& extension, const ExtensionAction& action);

  // Returns true if |action|'s icon for size |action_key| matches
  // |extension|'s icon for size |extension_key|;
  bool IconsMatch(const Extension& extension,
                  int extension_key,
                  const ExtensionAction& action,
                  int action_key);

  // Returns the appropriate action for |extension| according to |action_type|.
  ExtensionAction* GetAction(const char* action_type,
                             const Extension& extension);

  // Tests that values that are missing from the |action_type| key are properly
  // populated with values from the other keys in the manifest (e.g.
  // "default_icon" key of |action_type| is populated with "icons" key).
  void TestPopulateMissingValues(const char* action_type);

  ExtensionActionManager* manager() { return manager_; }

 private:
  content::TestBrowserThreadBundle thread_bundle_;
  ExtensionRegistry* registry_;
  int curr_id_;
  ExtensionActionManager* manager_;
  scoped_ptr<TestingProfile> profile_;
};

ExtensionActionManagerTest::ExtensionActionManagerTest()
    : curr_id_(0),
      profile_(new TestingProfile) {
  registry_ = ExtensionRegistry::Get(profile_.get());
  manager_ = ExtensionActionManager::Get(profile_.get());
}

scoped_refptr<Extension> ExtensionActionManagerTest::BuildExtension(
    scoped_ptr<base::DictionaryValue> extension_icons,
    scoped_ptr<base::DictionaryValue> action,
    const char* action_type) {
  std::string id = base::IntToString(curr_id_++);
  scoped_refptr<Extension> extension =
      ExtensionBuilder()
          .SetManifest(
              DictionaryBuilder()
                  .Set("version", "1")
                  .Set("manifest_version", 2)
                  .Set("icons", std::move(extension_icons))
                  .Set(action_type, std::move(action))
                  .Set("name", std::string("Test Extension").append(id))
                  .Build())
          .SetID(id)
          .Build();
  registry_->AddEnabled(extension);
  return extension;
}

bool ExtensionActionManagerTest::TitlesMatch(const Extension& extension,
                                             const ExtensionAction& action) {
  return action.GetTitle(ExtensionAction::kDefaultTabId) == extension.name();
}

bool ExtensionActionManagerTest::IconsMatch(const Extension& extension,
                                            int extension_key,
                                            const ExtensionAction& action,
                                            int action_key) {
  return action.default_icon()->Get(action_key,
                                    ExtensionIconSet::MATCH_BIGGER) ==
         IconsInfo::GetIcons(&extension)
             .Get(extension_key, ExtensionIconSet::MATCH_EXACTLY);
}

ExtensionAction* ExtensionActionManagerTest::GetAction(
    const char* action_type,
    const Extension& extension) {
  return (action_type == kBrowserAction) ?
      manager_->GetBrowserAction(extension) :
      manager_->GetPageAction(extension);
}

void ExtensionActionManagerTest::TestPopulateMissingValues(
    const char* action_type) {
  // Test that the largest icon from the extension's "icons" key is chosen as a
  // replacement for missing action default_icons keys. "19" should not be
  // replaced because "38" can always be used in its place.
  scoped_refptr<Extension> extension =
      BuildExtension(DictionaryBuilder()
                         .Set("48", "icon48.png")
                         .Set("128", "icon128.png")
                         .Build(),
                     DictionaryBuilder().Build(), action_type);

  ASSERT_TRUE(extension.get());
  const ExtensionAction* action = GetAction(action_type, *extension.get());
  ASSERT_TRUE(action);

  ASSERT_TRUE(TitlesMatch(*extension.get(), *action));
  ASSERT_TRUE(IconsMatch(*extension.get(), 48, *action, 38));

  // Test that the action's missing default_icons are not replaced with smaller
  // icons.
  extension =
      BuildExtension(DictionaryBuilder().Set("24", "icon24.png").Build(),
                     DictionaryBuilder().Build(), action_type);

  ASSERT_TRUE(extension.get());
  action = GetAction(action_type, *extension.get());
  ASSERT_TRUE(action);

  ASSERT_TRUE(IconsMatch(*extension.get(), 24, *action, 19));
  ASSERT_FALSE(IconsMatch(*extension.get(), 24, *action, 38));

  // Test that an action's 19px icon is not replaced if a 38px action icon
  // exists.
  extension = BuildExtension(
      DictionaryBuilder().Set("128", "icon128.png").Build(),
      DictionaryBuilder()
          .Set("default_icon",
               DictionaryBuilder().Set("38", "action38.png").Build())
          .Build(),
      action_type);

  ASSERT_TRUE(extension.get());
  action = GetAction(action_type, *extension.get());
  ASSERT_TRUE(action);

  ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 19));

  // Test that existing default_icons and default_title are not replaced.
  extension =
      BuildExtension(DictionaryBuilder().Set("128", "icon128.png").Build(),
                     DictionaryBuilder()
                         .Set("default_title", "Action!")
                         .Set("default_icon", DictionaryBuilder()
                                                  .Set("19", "action19.png")
                                                  .Set("38", "action38.png")
                                                  .Build())
                         .Build(),
                     action_type);

  ASSERT_TRUE(extension.get());
  action = GetAction(action_type, *extension.get());
  ASSERT_TRUE(action);

  ASSERT_FALSE(TitlesMatch(*extension.get(), *action));
  ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 19));
  ASSERT_FALSE(IconsMatch(*extension.get(), 128, *action, 38));
}

namespace {

TEST_F(ExtensionActionManagerTest, PopulateBrowserAction) {
  TestPopulateMissingValues(kBrowserAction);
}

TEST_F(ExtensionActionManagerTest, PopulatePageAction) {
  TestPopulateMissingValues(kPageAction);
}

TEST_F(ExtensionActionManagerTest, GetBestFitActionTest) {
  // Create an extension with page action defaults.
  scoped_refptr<Extension> extension = BuildExtension(
      DictionaryBuilder().Set("48", "icon48.png").Build(),
      DictionaryBuilder()
          .Set("default_title", "Action!")
          .Set("default_icon",
               DictionaryBuilder().Set("38", "action38.png").Build())
          .Build(),
      kPageAction);
  ASSERT_TRUE(extension.get());

  // Get a "best fit" browser action for |extension|.
  scoped_ptr<ExtensionAction> action =
      manager()->GetBestFitAction(*extension.get(), ActionInfo::TYPE_BROWSER);
  ASSERT_TRUE(action.get());
  ASSERT_EQ(action->action_type(), ActionInfo::TYPE_BROWSER);

  // |action|'s title and default icon should match |extension|'s page action's.
  ASSERT_EQ(action->GetTitle(ExtensionAction::kDefaultTabId), "Action!");
  ASSERT_EQ(action->default_icon()->Get(38, ExtensionIconSet::MATCH_EXACTLY),
            "action38.png");

  // Create a new extension without page action defaults.
  extension =
      BuildExtension(DictionaryBuilder().Set("48", "icon48.png").Build(),
                     DictionaryBuilder().Build(), kPageAction);
  ASSERT_TRUE(extension.get());

  action =
      manager()->GetBestFitAction(*extension.get(), ActionInfo::TYPE_BROWSER);

  // Now these values match because |extension| does not have page action
  // defaults.
  ASSERT_TRUE(TitlesMatch(*extension.get(), *action));
  ASSERT_TRUE(IconsMatch(*extension.get(), 48, *action, 38));
}

}  // namespace
}  // namespace extensions
