// Copyright (c) 2012 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 "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/extensions/context_menu_matcher.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "content/public/common/context_menu_params.h"
#include "ui/gfx/favicon_size.h"
#include "ui/gfx/image/image.h"

namespace extensions {

// static
const size_t ContextMenuMatcher::kMaxExtensionItemTitleLength = 75;

ContextMenuMatcher::ContextMenuMatcher(
    Profile* profile,
    ui::SimpleMenuModel::Delegate* delegate,
    ui::SimpleMenuModel* menu_model,
    const base::Callback<bool(const MenuItem*)>& filter)
    : profile_(profile), menu_model_(menu_model), delegate_(delegate),
      filter_(filter) {
}

void ContextMenuMatcher::AppendExtensionItems(
    const std::string& extension_id,
    const base::string16& selection_text,
    int* index) {
  DCHECK_GE(*index, 0);
  int max_index =
      IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST - IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST;
  if (*index >= max_index)
    return;

  const Extension* extension = NULL;
  MenuItem::List items;
  bool can_cross_incognito;
  if (!GetRelevantExtensionTopLevelItems(extension_id, &extension,
                                         &can_cross_incognito, items))
    return;

  if (items.empty())
    return;

  // If this is the first extension-provided menu item, and there are other
  // items in the menu, and the last item is not a separator add a separator.
  if (*index == 0 && menu_model_->GetItemCount())
    menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);

  // Extensions (other than platform apps) are only allowed one top-level slot
  // (and it can't be a radio or checkbox item because we are going to put the
  // extension icon next to it).
  // If they have more than that, we automatically push them into a submenu.
  if (extension->is_platform_app()) {
    RecursivelyAppendExtensionItems(items, can_cross_incognito, selection_text,
                                    menu_model_, index);
  } else {
    int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++;
    base::string16 title;
    MenuItem::List submenu_items;

    if (items.size() > 1 || items[0]->type() != MenuItem::NORMAL) {
      title = UTF8ToUTF16(extension->name());
      submenu_items = items;
    } else {
      MenuItem* item = items[0];
      extension_item_map_[menu_id] = item->id();
      title = item->TitleWithReplacement(selection_text,
                                       kMaxExtensionItemTitleLength);
      submenu_items = GetRelevantExtensionItems(item->children(),
                                                can_cross_incognito);
    }

    // Now add our item(s) to the menu_model_.
    if (submenu_items.empty()) {
      menu_model_->AddItem(menu_id, title);
    } else {
      ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_);
      extension_menu_models_.push_back(submenu);
      menu_model_->AddSubMenu(menu_id, title, submenu);
      RecursivelyAppendExtensionItems(submenu_items, can_cross_incognito,
                                      selection_text, submenu, index);
    }
    SetExtensionIcon(extension_id);
  }
}

void ContextMenuMatcher::Clear() {
  extension_item_map_.clear();
  extension_menu_models_.clear();
}

base::string16 ContextMenuMatcher::GetTopLevelContextMenuTitle(
    const std::string& extension_id,
    const base::string16& selection_text) {
  const Extension* extension = NULL;
  MenuItem::List items;
  bool can_cross_incognito;
  GetRelevantExtensionTopLevelItems(extension_id, &extension,
      &can_cross_incognito, items);

  base::string16 title;

  if (items.empty() ||
      items.size() > 1 ||
      items[0]->type() != MenuItem::NORMAL) {
    title = UTF8ToUTF16(extension->name());
  } else {
    MenuItem* item = items[0];
    title = item->TitleWithReplacement(
        selection_text, kMaxExtensionItemTitleLength);
  }
  return title;
}

bool ContextMenuMatcher::IsCommandIdChecked(int command_id) const {
  MenuItem* item = GetExtensionMenuItem(command_id);
  if (!item)
    return false;
  return item->checked();
}

bool ContextMenuMatcher::IsCommandIdEnabled(int command_id) const {
  MenuItem* item = GetExtensionMenuItem(command_id);
  if (!item)
    return true;
  return item->enabled();
}

void ContextMenuMatcher::ExecuteCommand(int command_id,
    content::WebContents* web_contents,
    const content::ContextMenuParams& params) {
  MenuItem* item = GetExtensionMenuItem(command_id);
  if (!item)
    return;

  MenuManager* manager = MenuManager::Get(profile_);
  manager->ExecuteCommand(profile_, web_contents, params, item->id());
}

bool ContextMenuMatcher::GetRelevantExtensionTopLevelItems(
    const std::string& extension_id,
    const Extension** extension,
    bool* can_cross_incognito,
    MenuItem::List& items) {
  ExtensionService* service =
      extensions::ExtensionSystem::Get(profile_)->extension_service();
  *extension = service->GetExtensionById(extension_id, false);

  if (!*extension)
    return false;

  // Find matching items.
  MenuManager* manager = MenuManager::Get(profile_);
  const MenuItem::List* all_items = manager->MenuItems(extension_id);
  if (!all_items || all_items->empty())
    return false;

  *can_cross_incognito = extension_util::CanCrossIncognito(*extension, service);
  items = GetRelevantExtensionItems(*all_items,
                                    *can_cross_incognito);

  return true;
}

MenuItem::List ContextMenuMatcher::GetRelevantExtensionItems(
    const MenuItem::List& items,
    bool can_cross_incognito) {
  MenuItem::List result;
  for (MenuItem::List::const_iterator i = items.begin();
       i != items.end(); ++i) {
    const MenuItem* item = *i;

    if (!filter_.Run(item))
      continue;

    if (item->id().incognito == profile_->IsOffTheRecord() ||
        can_cross_incognito)
      result.push_back(*i);
  }
  return result;
}

void ContextMenuMatcher::RecursivelyAppendExtensionItems(
    const MenuItem::List& items,
    bool can_cross_incognito,
    const base::string16& selection_text,
    ui::SimpleMenuModel* menu_model,
    int* index)
{
  MenuItem::Type last_type = MenuItem::NORMAL;
  int radio_group_id = 1;

  for (MenuItem::List::const_iterator i = items.begin();
       i != items.end(); ++i) {
    MenuItem* item = *i;

    // If last item was of type radio but the current one isn't, auto-insert
    // a separator.  The converse case is handled below.
    if (last_type == MenuItem::RADIO &&
        item->type() != MenuItem::RADIO) {
      menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
      last_type = MenuItem::SEPARATOR;
    }

    int menu_id = IDC_EXTENSIONS_CONTEXT_CUSTOM_FIRST + (*index)++;
    if (menu_id >= IDC_EXTENSIONS_CONTEXT_CUSTOM_LAST)
      return;
    extension_item_map_[menu_id] = item->id();
    base::string16 title = item->TitleWithReplacement(selection_text,
                                                kMaxExtensionItemTitleLength);
    if (item->type() == MenuItem::NORMAL) {
      MenuItem::List children =
          GetRelevantExtensionItems(item->children(), can_cross_incognito);
      if (children.empty()) {
        menu_model->AddItem(menu_id, title);
      } else {
        ui::SimpleMenuModel* submenu = new ui::SimpleMenuModel(delegate_);
        extension_menu_models_.push_back(submenu);
        menu_model->AddSubMenu(menu_id, title, submenu);
        RecursivelyAppendExtensionItems(children, can_cross_incognito,
                                        selection_text, submenu, index);
      }
    } else if (item->type() == MenuItem::CHECKBOX) {
      menu_model->AddCheckItem(menu_id, title);
    } else if (item->type() == MenuItem::RADIO) {
      if (i != items.begin() &&
          last_type != MenuItem::RADIO) {
        radio_group_id++;

        // Auto-append a separator if needed.
        menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
      }

      menu_model->AddRadioItem(menu_id, title, radio_group_id);
    } else if (item->type() == MenuItem::SEPARATOR) {
      menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
    }
    last_type = item->type();
  }
}

MenuItem* ContextMenuMatcher::GetExtensionMenuItem(int id) const {
  MenuManager* manager = MenuManager::Get(profile_);
  std::map<int, MenuItem::Id>::const_iterator i =
      extension_item_map_.find(id);
  if (i != extension_item_map_.end()) {
    MenuItem* item = manager->GetItemById(i->second);
    if (item)
      return item;
  }
  return NULL;
}

void ContextMenuMatcher::SetExtensionIcon(const std::string& extension_id) {
  MenuManager* menu_manager = MenuManager::Get(profile_);

  int index = menu_model_->GetItemCount() - 1;
  DCHECK_GE(index, 0);

  const SkBitmap& icon = menu_manager->GetIconForExtension(extension_id);
  DCHECK(icon.width() == gfx::kFaviconSize);
  DCHECK(icon.height() == gfx::kFaviconSize);

  menu_model_->SetIcon(index, gfx::Image::CreateFrom1xBitmap(icon));
}

}  // namespace extensions
