// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/context_menu_matcher.h"

#include <string>

#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "chrome/browser/extensions/menu_manager.h"
#include "chrome/browser/extensions/menu_manager_factory.h"
#include "chrome/browser/extensions/test_extension_menu_icon_loader.h"
#include "chrome/browser/extensions/test_extension_prefs.h"
#include "chrome/common/extensions/api/context_menus.h"
#include "chrome/test/base/testing_profile.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/utils/extension_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/menus/simple_menu_model.h"

namespace extensions {

// A helper used to show all menu items added by the extension.
bool MenuItemHasAnyContext(const extensions::MenuItem* item) {
  return true;
}

class ContextMenuMatcherTest : public testing::Test {
 public:
  ContextMenuMatcherTest()
      : profile_(std::make_unique<TestingProfile>()),
        manager_(CreateMenuManager()),
        prefs_(base::SingleThreadTaskRunner::GetCurrentDefault()) {}

  ContextMenuMatcherTest(const ContextMenuMatcherTest&) = delete;
  ContextMenuMatcherTest& operator=(const ContextMenuMatcherTest&) = delete;

  // Returns a test item with the given string ID.
  std::unique_ptr<MenuItem> CreateTestItem(Extension* extension,
                                           const std::string& string_id,
                                           bool visible) {
    MenuItem::Id id(false, MenuItem::ExtensionKey(extension->id()));
    id.string_uid = string_id;
    return std::make_unique<MenuItem>(
        id, "test", false, visible, true, MenuItem::NORMAL,
        MenuItem::ContextList(MenuItem::LAUNCHER));
  }

  // Returns a test item with the given string ID for WebView.
  std::unique_ptr<MenuItem> CreateTestItem(Extension* extension,
                                           int webview_embedder_process_id,
                                           int webview_embedder_frame_id,
                                           int webview_instance_id,
                                           const std::string& string_id,
                                           bool visible) {
    const ExtensionId& extension_id = MaybeGetExtensionId(extension);
    MenuItem::Id id(false, MenuItem::ExtensionKey(
                               extension_id, webview_embedder_process_id,
                               webview_embedder_frame_id, webview_instance_id));
    id.string_uid = string_id;
    return std::make_unique<MenuItem>(
        id, "test", false, visible, true, MenuItem::NORMAL,
        MenuItem::ContextList(MenuItem::LAUNCHER));
  }

  // Creates and returns a test Extension.
  Extension* AddExtension(const std::string& name) {
    scoped_refptr<Extension> extension = prefs_.AddExtension(name);
    extensions_.push_back(extension);
    ExtensionRegistry* registry = ExtensionRegistry::Get(profile_.get());
    registry->AddEnabled(extension);
    return extension.get();
  }

  // Creates and returns a menu manager.
  MenuManager* CreateMenuManager() {
    return static_cast<MenuManager*>(
        MenuManagerFactory::GetInstance()->SetTestingFactoryAndUse(
            profile_.get(),
            base::BindRepeating(
                &MenuManagerFactory::BuildServiceInstanceForTesting)));
  }

 protected:
  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<TestingProfile> profile_;

  raw_ptr<MenuManager> manager_;
  ExtensionList extensions_;
  TestExtensionPrefs prefs_;
};

// Tests appending an extension item with an invisible submenu.
TEST_F(ContextMenuMatcherTest, AppendExtensionItemsWithInvisibleSubmenu) {
  Extension* extension = AddExtension("test");

  // Add a new item with an invisible child item.
  std::unique_ptr<MenuItem> parent = CreateTestItem(extension, "parent", false);
  MenuItem::Id parent_id = parent->id();
  int parent_index = 0;
  std::unique_ptr<MenuItem> child = CreateTestItem(extension, "child", false);
  int child_index = 1;
  ASSERT_TRUE(manager_->AddContextItem(extension, std::move(parent)));
  manager_->AddChildItem(parent_id, std::move(child));

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr);

  std::unique_ptr<extensions::ContextMenuMatcher> extension_items =
      std::make_unique<extensions::ContextMenuMatcher>(
          profile_.get(), nullptr, menu_model.get(),
          base::BindRepeating(MenuItemHasAnyContext));

  std::u16string printable_selection_text;
  int index = 0;

  // Add the items associated with the test extension.
  extension_items->AppendExtensionItems(MenuItem::ExtensionKey(extension->id()),
                                        printable_selection_text, &index,
                                        false);
  // Verify both parent and child are hidden.
  EXPECT_FALSE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(parent_index)));
  EXPECT_FALSE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child_index)));
}

// Tests appending an extension item with a visible submenu.
TEST_F(ContextMenuMatcherTest, AppendExtensionItemsWithVisibleSubmenu) {
  Extension* extension = AddExtension("test");

  // Add a parent item, with a visible child item.
  std::unique_ptr<MenuItem> parent = CreateTestItem(extension, "parent", true);
  MenuItem::Id parent_id = parent->id();
  int parent_index = 0;
  std::unique_ptr<MenuItem> child = CreateTestItem(extension, "child", true);
  int child_index = 1;
  ASSERT_TRUE(manager_->AddContextItem(extension, std::move(parent)));
  manager_->AddChildItem(parent_id, std::move(child));

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr);

  std::unique_ptr<extensions::ContextMenuMatcher> extension_items =
      std::make_unique<extensions::ContextMenuMatcher>(
          profile_.get(), nullptr, menu_model.get(),
          base::BindRepeating(MenuItemHasAnyContext));

  // Add the items associated with the test extension.
  std::u16string printable_selection_text;
  int index = 0;
  extension_items->AppendExtensionItems(MenuItem::ExtensionKey(extension->id()),
                                        printable_selection_text, &index,
                                        false);

  // Verify both parent and child are visible.
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(parent_index)));
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child_index)));
}

TEST_F(ContextMenuMatcherTest, AppendExtensionItemsGroupTitle) {
  Extension* extension = AddExtension("test");

  // Add a parent item, with a visible child item.
  std::unique_ptr<MenuItem> parent = CreateTestItem(extension, "parent", true);
  MenuItem::Id parent_id = parent->id();
  int parent_index = 0;
  std::unique_ptr<MenuItem> child = CreateTestItem(extension, "child", true);
  int child_index = 1;
  ASSERT_TRUE(manager_->AddContextItem(extension, std::move(parent)));
  manager_->AddChildItem(parent_id, std::move(child));

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr);

  std::unique_ptr<extensions::ContextMenuMatcher> extension_items =
      std::make_unique<extensions::ContextMenuMatcher>(
          profile_.get(), nullptr, menu_model.get(),
          base::BindRepeating(MenuItemHasAnyContext));

  // Add the items associated with the test extension.
  int index = 0;
  std::u16string group_title = base::UTF8ToUTF16(extension->name());
  extension_items->AppendExtensionItems(MenuItem::ExtensionKey(extension->id()),
                                        std::u16string(), &index, false,
                                        group_title);

  // Verify both parent and child are visible.
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(parent_index)));
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child_index)));
  EXPECT_EQ(menu_model->GetLabelAt(0), group_title);
}

TEST_F(ContextMenuMatcherTest,
       AppendExtensionItemsGroupTitleWithNullExtension) {
  static constexpr int kFakeWebViewEmbedderPid = 1;
  static constexpr int kFakeWebViewEmbedderFrameId = 1;
  static constexpr int kFakeWebViewInstanceId = 1;
  // Add a parent item, with a visible child item.
  std::unique_ptr<MenuItem> parent =
      CreateTestItem(/*extension=*/nullptr, kFakeWebViewEmbedderPid,
                     kFakeWebViewEmbedderFrameId, kFakeWebViewInstanceId,
                     "parent", /*visible=*/true);
  MenuItem::Id parent_id = parent->id();
  manager_->SetMenuIconLoader(parent->id().extension_key,
                              std::make_unique<TestExtensionMenuIconLoader>());

  int parent_index = 0;
  std::unique_ptr<MenuItem> child =
      CreateTestItem(/*extension=*/nullptr, kFakeWebViewEmbedderPid,
                     kFakeWebViewEmbedderFrameId, kFakeWebViewInstanceId,
                     "child", /*visible=*/true);
  int child_index = 1;
  ASSERT_TRUE(
      manager_->AddContextItem(/*extension=*/nullptr, std::move(parent)));
  manager_->AddChildItem(parent_id, std::move(child));

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr);

  std::unique_ptr<extensions::ContextMenuMatcher> extension_items =
      std::make_unique<extensions::ContextMenuMatcher>(
          profile_.get(), nullptr, menu_model.get(),
          base::BindRepeating(MenuItemHasAnyContext));

  // Add the items associated with the test extension.
  int index = 0;
  std::u16string group_title = u"test";
  extension_items->AppendExtensionItems(
      MenuItem::ExtensionKey(/*extension_id=*/"", kFakeWebViewEmbedderPid,
                             kFakeWebViewEmbedderFrameId,
                             kFakeWebViewInstanceId),
      /*selection_text=*/u"test", &index, /*is_action_menu=*/false,
      group_title);

  // Verify both parent and child are visible.
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(parent_index)));
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child_index)));
  EXPECT_EQ(menu_model->GetLabelAt(0), group_title);
}

// Tests appending a visible extension item with an invisible child.
// The child has an invisible submenu.
TEST_F(ContextMenuMatcherTest, AppendExtensionItemWithInvisibleSubmenu) {
  Extension* extension = AddExtension("test");

  // Add a visible parent item, with an invisible child item.
  std::unique_ptr<MenuItem> parent = CreateTestItem(extension, "parent", true);
  MenuItem::Id parent_id = parent->id();
  int parent_index = 0;
  std::unique_ptr<MenuItem> child1 = CreateTestItem(extension, "child1", false);
  int child1_index = 1;
  MenuItem::Id child1_id = child1->id();
  ASSERT_TRUE(manager_->AddContextItem(extension, std::move(parent)));
  manager_->AddChildItem(parent_id, std::move(child1));

  // Add two invisible item, child2 and child3, and make them child1's submenu
  // items
  std::unique_ptr<MenuItem> child2 = CreateTestItem(extension, "child2", false);
  int child2_index = 2;
  manager_->AddChildItem(child1_id, std::move(child2));

  std::unique_ptr<MenuItem> child3 = CreateTestItem(extension, "child3", false);
  int child3_index = 3;
  manager_->AddChildItem(child1_id, std::move(child3));

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(nullptr);

  std::unique_ptr<extensions::ContextMenuMatcher> extension_items =
      std::make_unique<extensions::ContextMenuMatcher>(
          profile_.get(), nullptr, menu_model.get(),
          base::BindRepeating(MenuItemHasAnyContext));

  // Add the items associated with the test extension.
  std::u16string printable_selection_text;
  int index = 0;
  extension_items->AppendExtensionItems(MenuItem::ExtensionKey(extension->id()),
                                        printable_selection_text, &index,
                                        false);

  // Verify parent is visible.
  EXPECT_TRUE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(parent_index)));
  // Verify child1 and its submenu are all invisible.
  EXPECT_FALSE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child1_index)));
  EXPECT_FALSE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child2_index)));
  EXPECT_FALSE(extension_items->IsCommandIdVisible(
      extension_items->ConvertToExtensionsCustomCommandId(child3_index)));
}

TEST_F(ContextMenuMatcherTest, GetIconFromMenuIconLoader) {
  Extension* extension = AddExtension("test");

  std::unique_ptr<MenuItem> item =
      CreateTestItem(extension, "id", /*visible=*/true);
  MenuItem::Id item_id = item->id();
  auto menu_icon_loader = std::make_unique<TestExtensionMenuIconLoader>();
  TestExtensionMenuIconLoader* extension_menu_icon_loader =
      menu_icon_loader.get();

  manager_->SetMenuIconLoader(item_id.extension_key,
                              std::move(menu_icon_loader));
  manager_->AddContextItem(extension, std::move(item));
  EXPECT_EQ(1, extension_menu_icon_loader->load_icon_calls());

  auto menu_model = std::make_unique<ui::SimpleMenuModel>(/*delegate=*/nullptr);
  auto extension_items = std::make_unique<extensions::ContextMenuMatcher>(
      profile_.get(), /*delegate=*/nullptr, menu_model.get(),
      base::BindRepeating(MenuItemHasAnyContext));

  // Add the items associated with the test extension.
  int index = 0;
  extension_items->AppendExtensionItems(MenuItem::ExtensionKey(extension->id()),
                                        std::u16string(), &index,
                                        /*is_action_menu=*/false);
  EXPECT_EQ(1, extension_menu_icon_loader->get_icon_calls());
}

}  // namespace extensions
