// 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.

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

#include <stddef.h>

#include "base/strings/string_number_conversions.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/context_menu_matcher.h"
#include "components/renderer_context_menu/render_view_context_menu_base.h"
#include "content/public/browser/context_menu_params.h"
#include "third_party/blink/public/mojom/context_menu/context_menu.mojom-shared.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/text_elider.h"

using blink::mojom::ContextMenuDataMediaType;

namespace extensions {
namespace context_menu_helpers {
namespace {

// Helper function to determine if a given URL matches a URLPatternSet.
// This is primarily a wrapper around URLPatternSet::MatchesURL but includes an
// important special case: An empty pattern set is considered a match.
// This convention is used throughout the extension system to mean that an item
// has no URL-specific restrictions.
//
// @param patterns The set of URL patterns to check against.
// @param url The URL to be tested.
// @return true if the URL is matched by the patterns or if the pattern set
//     is empty, false otherwise.
bool ExtensionPatternMatch(const URLPatternSet& patterns, const GURL& url) {
  // No patterns means no restriction, so that implicitly matches.
  if (patterns.is_empty()) {
    return true;
  }
  return patterns.MatchesURL(url);
}

// Escapes ampersands in a string by replacing each `&` with `&&`.
// This is necessary for strings that will be displayed in UI elements like
// menus or labels, as a single ampersand is often interpreted as a prefix for
// a mnemonic character (e.g., "S&ave" would display as "Save" with 'a'
// underlined). Doubling the ampersand displays a literal '&'. The string is
// modified in-place.
//
// @param text The string to modify.
void EscapeAmpersands(std::u16string* text) {
  base::ReplaceChars(*text, u"&", u"&&", text);
}

}  // namespace

const char kActionNotAllowedError[] =
    "Only extensions are allowed to use action contexts";
const char kCannotFindItemError[] = "Cannot find menu item with id *";
const char kCheckedError[] =
    "Only items with type \"radio\" or \"checkbox\" can be checked";
const char kDuplicateIDError[] =
    "Cannot create item with duplicate id *";
const char kGeneratedIdKey[] = "generatedId";
const char kLauncherNotAllowedError[] =
    "Only packaged apps are allowed to use 'launcher' context";
const char kOnclickDisallowedError[] =
    "Extensions using event pages or "
    "Service Workers cannot pass an onclick parameter to "
    "chrome.contextMenus.create. Instead, use the "
    "chrome.contextMenus.onClicked event.";
const char kParentsMustBeNormalError[] =
    "Parent items must have type \"normal\"";
const char kTitleNeededError[] =
    "All menu items except for separators must have a title";
const char kTooManyMenuItems[] =
    "An extension can create a maximum of * menu items.";

std::string GetIDString(const MenuItem::Id& id) {
  if (id.uid == 0) {
    return id.string_uid;
  } else {
    return base::NumberToString(id.uid);
  }
}

MenuItem* GetParent(MenuItem::Id parent_id,
                    const MenuManager* menu_manager,
                    std::string* error) {
  MenuItem* parent = menu_manager->GetItemById(parent_id);
  if (!parent) {
    *error = ErrorUtils::FormatErrorMessage(
        kCannotFindItemError, GetIDString(parent_id));
    return nullptr;
  }
  if (parent->type() != MenuItem::NORMAL) {
    *error = kParentsMustBeNormalError;
    return nullptr;
  }
  return parent;
}

MenuItem::ContextList GetContexts(
    const std::vector<api::context_menus::ContextType>& in_contexts) {
  MenuItem::ContextList contexts;
  for (auto context : in_contexts) {
    switch (context) {
      case api::context_menus::ContextType::kAll:
        contexts.Add(MenuItem::ALL);
        break;
      case api::context_menus::ContextType::kPage:
        contexts.Add(MenuItem::PAGE);
        break;
      case api::context_menus::ContextType::kSelection:
        contexts.Add(MenuItem::SELECTION);
        break;
      case api::context_menus::ContextType::kLink:
        contexts.Add(MenuItem::LINK);
        break;
      case api::context_menus::ContextType::kEditable:
        contexts.Add(MenuItem::EDITABLE);
        break;
      case api::context_menus::ContextType::kImage:
        contexts.Add(MenuItem::IMAGE);
        break;
      case api::context_menus::ContextType::kVideo:
        contexts.Add(MenuItem::VIDEO);
        break;
      case api::context_menus::ContextType::kAudio:
        contexts.Add(MenuItem::AUDIO);
        break;
      case api::context_menus::ContextType::kFrame:
        contexts.Add(MenuItem::FRAME);
        break;
      case api::context_menus::ContextType::kLauncher:
        // Not available for <webview>.
        contexts.Add(MenuItem::LAUNCHER);
        break;
      case api::context_menus::ContextType::kBrowserAction:
        // Not available for <webview>.
        contexts.Add(MenuItem::BROWSER_ACTION);
        break;
      case api::context_menus::ContextType::kPageAction:
        // Not available for <webview>.
        contexts.Add(MenuItem::PAGE_ACTION);
        break;
      case api::context_menus::ContextType::kAction:
        // Not available for <webview>.
        contexts.Add(MenuItem::ACTION);
        break;
      case api::context_menus::ContextType::kNone:
        NOTREACHED();
    }
  }
  return contexts;
}

MenuItem::Type GetType(api::context_menus::ItemType type,
                       MenuItem::Type default_type) {
  switch (type) {
    case api::context_menus::ItemType::kNone:
      return default_type;
    case api::context_menus::ItemType::kNormal:
      return MenuItem::NORMAL;
    case api::context_menus::ItemType::kCheckbox:
      return MenuItem::CHECKBOX;
    case api::context_menus::ItemType::kRadio:
      return MenuItem::RADIO;
    case api::context_menus::ItemType::kSeparator:
      return MenuItem::SEPARATOR;
  }
  return MenuItem::NORMAL;
}

bool ExtensionContextAndPatternMatch(const content::ContextMenuParams& params,
                                     const MenuItem::ContextList& contexts,
                                     const URLPatternSet& target_url_patterns) {
  const bool has_link = !params.link_url.is_empty();
  const bool has_selection = !params.selection_text.empty();
  const bool in_subframe = params.is_subframe;

  if (contexts.Contains(MenuItem::ALL) ||
      (has_selection && contexts.Contains(MenuItem::SELECTION)) ||
      (params.is_editable && contexts.Contains(MenuItem::EDITABLE)) ||
      (in_subframe && contexts.Contains(MenuItem::FRAME))) {
    return true;
  }

  if (has_link && contexts.Contains(MenuItem::LINK) &&
      ExtensionPatternMatch(target_url_patterns, params.link_url)) {
    return true;
  }

  switch (params.media_type) {
    case ContextMenuDataMediaType::kImage:
      if (contexts.Contains(MenuItem::IMAGE) &&
          ExtensionPatternMatch(target_url_patterns, params.src_url)) {
        return true;
      }
      break;

    case ContextMenuDataMediaType::kVideo:
      if (contexts.Contains(MenuItem::VIDEO) &&
          ExtensionPatternMatch(target_url_patterns, params.src_url)) {
        return true;
      }
      break;

    case ContextMenuDataMediaType::kAudio:
      if (contexts.Contains(MenuItem::AUDIO) &&
          ExtensionPatternMatch(target_url_patterns, params.src_url)) {
        return true;
      }
      break;

    default:
      break;
  }

  // PAGE is the least specific context, so we only examine that if none of the
  // other contexts apply (except for FRAME, which is included in PAGE for
  // backwards compatibility).
  if (!has_link && !has_selection && !params.is_editable &&
      params.media_type == ContextMenuDataMediaType::kNone &&
      contexts.Contains(MenuItem::PAGE)) {
    return true;
  }

  return false;
}

bool MenuItemMatchesParams(const content::ContextMenuParams& params,
                           const MenuItem* item) {
  bool match = ExtensionContextAndPatternMatch(params, item->contexts(),
                                               item->target_url_patterns());
  if (!match) {
    return false;
  }

  return ExtensionPatternMatch(item->document_url_patterns(), params.frame_url);
}

std::u16string PrintableSelectionText(const std::u16string& selection_text) {
  std::u16string result = gfx::TruncateString(
      selection_text, RenderViewContextMenuBase::kMaxSelectionTextLength,
      gfx::WORD_BREAK);
  EscapeAmpersands(&result);
  return result;
}

void PopulateExtensionItems(content::BrowserContext* browser_context,
                            const content::ContextMenuParams& params,
                            ContextMenuMatcher& matcher) {
  matcher.Clear();

  ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context);
  MenuManager* menu_manager = MenuManager::Get(browser_context);

  if (!menu_manager || !registry) {
    return;
  }

  std::u16string printable_selection_text =
      context_menu_helpers::PrintableSelectionText(params.selection_text);

  // Get a list of extension id's that have context menu items, and sort by the
  // top level context menu title of the extension.
  std::vector<std::u16string> sorted_menu_titles;
  std::map<std::u16string, std::vector<const Extension*>>
      title_to_extensions_map;

  for (const auto& id : menu_manager->ExtensionIds()) {
    const Extension* extension =
        registry->enabled_extensions().GetByID(id.extension_id);
    // Platform apps have their context menus created directly in
    // AppendPlatformAppItems.
    if (extension && !extension->is_platform_app()) {
      std::u16string menu_title =
          matcher.GetTopLevelContextMenuTitle(id, printable_selection_text);
      title_to_extensions_map[menu_title].push_back(extension);
      sorted_menu_titles.push_back(menu_title);
    }
  }

  if (sorted_menu_titles.empty()) {
    return;
  }

  const std::string app_locale = g_browser_process->GetApplicationLocale();
  l10n_util::SortStrings16(app_locale, &sorted_menu_titles);
  sorted_menu_titles.erase(
      std::unique(sorted_menu_titles.begin(), sorted_menu_titles.end()),
      sorted_menu_titles.end());
  sorted_menu_titles.erase(
      std::unique(sorted_menu_titles.begin(), sorted_menu_titles.end()),
      sorted_menu_titles.end());

  int index = 0;
  for (const auto& title : sorted_menu_titles) {
    const std::vector<const Extension*>& extensions =
        title_to_extensions_map[title];
    for (const Extension* extension : extensions) {
      MenuItem::ExtensionKey extension_key(extension->id());
      matcher.AppendExtensionItems(extension_key, printable_selection_text,
                                   &index,
                                   /*is_action_menu=*/false);
    }
  }
}

}  // namespace context_menu_helpers
}  // namespace extensions
