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

// Definition of helper functions for the ContextMenus API.

#ifndef CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_HELPERS_H_
#define CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_HELPERS_H_

#include "base/notreached.h"
#include "base/strings/string_number_conversions.h"
#include "base/types/optional_util.h"
#include "chrome/browser/extensions/menu_manager.h"
#include "chrome/common/extensions/api/context_menus.h"
#include "content/public/browser/browser_context.h"
#include "extensions/buildflags/buildflags.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "extensions/common/utils/extension_utils.h"

static_assert(BUILDFLAG(ENABLE_EXTENSIONS_CORE));

namespace content {
struct ContextMenuParams;
}  // namespace content

namespace extensions {
class ContextMenuMatcher;
}  // namespace extensions

namespace extensions::context_menu_helpers {

namespace {

template <typename PropertyWithEnumT>
std::unique_ptr<MenuItem::Id> GetParentId(const PropertyWithEnumT& property,
                                          bool is_off_the_record,
                                          const MenuItem::ExtensionKey& key) {
  if (!property.parent_id)
    return nullptr;

  std::unique_ptr<MenuItem::Id> parent_id(
      new MenuItem::Id(is_off_the_record, key));
  if (property.parent_id->as_integer) {
    parent_id->uid = *property.parent_id->as_integer;
  } else if (property.parent_id->as_string) {
    parent_id->string_uid = *property.parent_id->as_string;
  } else {
    NOTREACHED();
  }
  return parent_id;
}

}  // namespace

extern const char kActionNotAllowedError[];
extern const char kCannotFindItemError[];
extern const char kCheckedError[];
extern const char kDuplicateIDError[];
extern const char kGeneratedIdKey[];
extern const char kLauncherNotAllowedError[];
extern const char kOnclickDisallowedError[];
extern const char kParentsMustBeNormalError[];
extern const char kTitleNeededError[];
extern const char kTooManyMenuItems[];

std::string GetIDString(const MenuItem::Id& id);

MenuItem* GetParent(MenuItem::Id parent_id,
                    const MenuManager* menu_manager,
                    std::string* error);

MenuItem::ContextList GetContexts(
    const std::vector<api::context_menus::ContextType>& in_contexts);

MenuItem::Type GetType(api::context_menus::ItemType type,
                       MenuItem::Type default_type);

// Determines if a context menu item should be shown for a given click context.
// This checks if the properties of a right-click (the `params`) match the
// requirements of an extension's context menu item, which are defined by its
// allowed `contexts` and `target_url_patterns`.
//
// params The properties of the context menu click, such as the link
//     URL, selected text, and media type.
// contexts The set of contexts the menu item is registered for (e.g.,
//     `MenuItem::IMAGE`, `MenuItem::LINK`).
// target_url_patterns The set of URL patterns to match against for
//     applicable contexts like links and media.
// Returns whether the menu item is a match for the given context and should be
// shown.
bool ExtensionContextAndPatternMatch(const content::ContextMenuParams& params,
                                     const MenuItem::ContextList& contexts,
                                     const URLPatternSet& target_url_patterns);

// Determines if a given MenuItem should be shown for a context menu click,
// based on the context (e.g., link, image, or selection) and URL.
//
// params The properties of the context menu click.
// item The extension menu item to be evaluated.
// Returns whether the menu item should be displayed in the context menu.
bool MenuItemMatchesParams(const content::ContextMenuParams& params,
                           const MenuItem* item);

// Prepares user-selected text for display in a context menu item, by truncating
// the string to a maximum length (`kMaxSelectionTextLength`) and escaping
// ampersands to prevent them from being interpreted as UI mnemonic character
// shortcuts.
//
// selection_text The raw text selected by the user.
// Returns a truncated and escaped version of the input string suitable for
// display.
std::u16string PrintableSelectionText(const std::u16string& selection_text);

// Populates a ContextMenuMatcher with all relevant context menu items from
// enabled extensions, sorted and grouped appropriately.
//
// params The parameters of the context menu click. This is used to get
//     the selected text for menu items that include it (e.g., "Search for %s").
// matcher The `ContextMenuMatcher` that will be cleared and then
//     populated with the extension menu items.
void PopulateExtensionItems(content::BrowserContext* browser_context,
                            const content::ContextMenuParams& params,
                            ContextMenuMatcher& matcher);

// Creates and adds a menu item from `create_properties`.
template <typename PropertyWithEnumT>
bool CreateMenuItem(const PropertyWithEnumT& create_properties,
                    content::BrowserContext* browser_context,
                    const Extension* extension,
                    const MenuItem::Id& item_id,
                    std::string* error) {
  bool is_webview = item_id.extension_key.webview_instance_id != 0;
  MenuManager* menu_manager = MenuManager::Get(browser_context);

  if (menu_manager->MenuItemsSize(item_id.extension_key) >=
      MenuManager::kMaxItemsPerExtension) {
    *error = ErrorUtils::FormatErrorMessage(
        kTooManyMenuItems,
        base::NumberToString(MenuManager::kMaxItemsPerExtension));
    return false;
  }

  if (menu_manager->GetItemById(item_id)) {
    *error =
        ErrorUtils::FormatErrorMessage(kDuplicateIDError, GetIDString(item_id));
    return false;
  }

  if (!is_webview && BackgroundInfo::HasLazyContext(extension) &&
      create_properties.onclick) {
    *error = kOnclickDisallowedError;
    return false;
  }

  // Contexts.
  MenuItem::ContextList contexts;
  if (create_properties.contexts)
    contexts = GetContexts(*create_properties.contexts);
  else
    contexts.Add(MenuItem::PAGE);

  if (contexts.Contains(MenuItem::LAUNCHER)) {
    // Launcher item is not allowed for <webview>.
    if (is_webview || !extension->is_platform_app()) {
      *error = kLauncherNotAllowedError;
      return false;
    }
  }

  if (contexts.Contains(MenuItem::BROWSER_ACTION) ||
      contexts.Contains(MenuItem::PAGE_ACTION) ||
      contexts.Contains(MenuItem::ACTION)) {
    // Action items are not allowed for <webview>.
    if (is_webview || !extension->is_extension()) {
      *error = kActionNotAllowedError;
      return false;
    }
  }

  // Title.
  std::string title;
  if (create_properties.title)
    title = *create_properties.title;

  MenuItem::Type type = GetType(create_properties.type, MenuItem::NORMAL);
  if (title.empty() && type != MenuItem::SEPARATOR) {
    *error = kTitleNeededError;
    return false;
  }

  // Visibility state.
  bool visible = create_properties.visible.value_or(true);

  // Checked state.
  bool checked = create_properties.checked.value_or(false);

  // Enabled.
  bool enabled = create_properties.enabled.value_or(true);

  std::unique_ptr<MenuItem> item(
      new MenuItem(item_id, title, checked, visible, enabled, type, contexts));

  // URL Patterns.
  if (!item->PopulateURLPatterns(
          base::OptionalToPtr(create_properties.document_url_patterns),
          base::OptionalToPtr(create_properties.target_url_patterns), error)) {
    return false;
  }

  // Parent id.
  bool success = true;
  std::unique_ptr<MenuItem::Id> parent_id(
      GetParentId(create_properties, browser_context->IsOffTheRecord(),
                  item_id.extension_key));
  if (parent_id.get()) {
    MenuItem* parent = GetParent(*parent_id, menu_manager, error);
    if (!parent)
      return false;
    success = menu_manager->AddChildItem(parent->id(), std::move(item));
  } else {
    success = menu_manager->AddContextItem(extension, std::move(item));
  }

  if (!success)
    return false;

  menu_manager->WriteToStorage(extension, item_id.extension_key);
  return true;
}

// Updates a menu item from `update_properties`.
template <typename PropertyWithEnumT>
bool UpdateMenuItem(const PropertyWithEnumT& update_properties,
                    content::BrowserContext* browser_context,
                    const Extension* extension,
                    const MenuItem::Id& item_id,
                    std::string* error) {
  bool radio_item_updated = false;
  bool is_webview = item_id.extension_key.webview_instance_id != 0;
  MenuManager* menu_manager = MenuManager::Get(browser_context);

  MenuItem* item = menu_manager->GetItemById(item_id);
  const ExtensionId& extension_id = MaybeGetExtensionId(extension);
  if (!item || item->extension_id() != extension_id) {
    *error = ErrorUtils::FormatErrorMessage(kCannotFindItemError,
                                            GetIDString(item_id));
    return false;
  }

  // Type.
  MenuItem::Type type = GetType(update_properties.type, item->type());

  if (type != item->type()) {
    if (type == MenuItem::RADIO || item->type() == MenuItem::RADIO) {
      radio_item_updated = true;
    }
    item->set_type(type);
  }

  // Title.
  if (update_properties.title) {
    std::string title(*update_properties.title);
    if (title.empty() && item->type() != MenuItem::SEPARATOR) {
      *error = kTitleNeededError;
      return false;
    }
    item->set_title(title);
  }

  // Checked state.
  if (update_properties.checked) {
    bool checked = *update_properties.checked;
    if (checked && item->type() != MenuItem::CHECKBOX &&
        item->type() != MenuItem::RADIO) {
      *error = kCheckedError;
      return false;
    }

    const bool should_toggle_checked =
        // If radio item was unchecked nothing should happen. The radio item
        // should remain checked because there should always be one item checked
        // in the radio list.
        (item->type() == MenuItem::RADIO && checked) ||
        // Checkboxes are always updated.
        item->type() == MenuItem::CHECKBOX;

    if (should_toggle_checked) {
      if (!item->SetChecked(checked)) {
        *error = kCheckedError;
        return false;
      }
      radio_item_updated = true;
    }
  }

  // Visibility state.
  if (update_properties.visible)
    item->set_visible(*update_properties.visible);

  // Enabled.
  if (update_properties.enabled)
    item->set_enabled(*update_properties.enabled);

  // Contexts.
  MenuItem::ContextList contexts;
  if (update_properties.contexts) {
    contexts = GetContexts(*update_properties.contexts);

    if (contexts.Contains(MenuItem::LAUNCHER)) {
      // Launcher item is not allowed for <webview>.
      if (is_webview || !extension->is_platform_app()) {
        *error = kLauncherNotAllowedError;
        return false;
      }
    }

    if (contexts != item->contexts())
      item->set_contexts(contexts);
  }

  // Parent id.
  std::unique_ptr<MenuItem::Id> parent_id(
      GetParentId(update_properties, browser_context->IsOffTheRecord(),
                  item_id.extension_key));
  if (parent_id.get()) {
    MenuItem* parent = GetParent(*parent_id, menu_manager, error);
    if (!parent || !menu_manager->ChangeParent(item->id(), &parent->id()))
      return false;
  }

  // URL Patterns.
  if (!item->PopulateURLPatterns(
          base::OptionalToPtr(update_properties.document_url_patterns),
          base::OptionalToPtr(update_properties.target_url_patterns), error)) {
    return false;
  }

  // There is no need to call ItemUpdated if ChangeParent is called because
  // all sanitation is taken care of in ChangeParent.
  if (radio_item_updated && !menu_manager->ItemUpdated(item->id()))
    return false;

  menu_manager->WriteToStorage(extension, item_id.extension_key);
  return true;
}

}  // namespace extensions::context_menu_helpers

#endif  // CHROME_BROWSER_EXTENSIONS_CONTEXT_MENU_HELPERS_H_
