// Copyright 2016 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/renderer_context_menu/open_with_menu_factory_ash.h"

#include <algorithm>
#include <memory>
#include <unordered_map>
#include <utility>
#include <vector>

#include "ash/link_handler_model.h"
#include "ash/link_handler_model_factory.h"
#include "ash/shell.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/renderer_context_menu/open_with_menu_factory.h"
#include "chrome/grit/generated_resources.h"
#include "components/renderer_context_menu/render_view_context_menu_proxy.h"
#include "content/public/common/context_menu_params.h"
#include "ui/base/l10n/l10n_util.h"

const int OpenWithMenuObserver::kNumMainMenuCommands = 4;
const int OpenWithMenuObserver::kNumSubMenuCommands = 10;

bool OpenWithMenuObserver::SubMenuDelegate::IsCommandIdChecked(
    int command_id) const {
  return false;
}

bool OpenWithMenuObserver::SubMenuDelegate::IsCommandIdEnabled(
    int command_id) const {
  return true;
}

void OpenWithMenuObserver::SubMenuDelegate::ExecuteCommand(int command_id,
                                                           int event_flags) {
  parent_->ExecuteCommand(command_id);
}

OpenWithMenuObserver::OpenWithMenuObserver(RenderViewContextMenuProxy* proxy)
    : proxy_(proxy),
      submenu_delegate_(this),
      more_apps_label_(
          l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_MORE_APPS)) {}

OpenWithMenuObserver::~OpenWithMenuObserver() {}

void OpenWithMenuObserver::InitMenu(const content::ContextMenuParams& params) {
  if (!ash::Shell::HasInstance())
    return;
  ash::LinkHandlerModelFactory* factory =
      ash::Shell::Get()->link_handler_model_factory();
  if (!factory)
    return;

  link_url_ = params.link_url;
  menu_model_ = factory->CreateModel(link_url_);
  if (!menu_model_)
    return;

  // Add placeholder items.
  std::unique_ptr<ui::SimpleMenuModel> submenu(
      new ui::SimpleMenuModel(&submenu_delegate_));
  AddPlaceholderItems(proxy_, submenu.get());
  submenu_ = std::move(submenu);

  menu_model_->AddObserver(this);
}

bool OpenWithMenuObserver::IsCommandIdSupported(int command_id) {
  return command_id >= IDC_CONTENT_CONTEXT_OPEN_WITH1 &&
         command_id <= IDC_CONTENT_CONTEXT_OPEN_WITH_LAST;
}

bool OpenWithMenuObserver::IsCommandIdChecked(int command_id) {
  return false;
}

bool OpenWithMenuObserver::IsCommandIdEnabled(int command_id) {
  return true;
}

void OpenWithMenuObserver::ExecuteCommand(int command_id) {
  // Note: SubmenuDelegate also calls this method with a command_id for the
  // submenu.
  const auto it = handlers_.find(command_id);
  if (it == handlers_.end())
    return;
  menu_model_->OpenLinkWithHandler(link_url_, it->second.id);
}

void OpenWithMenuObserver::ModelChanged(
    const std::vector<ash::LinkHandlerInfo>& handlers) {
  auto result = BuildHandlersMap(handlers);
  handlers_ = std::move(result.first);
  const int submenu_parent_id = result.second;
  for (int command_id = IDC_CONTENT_CONTEXT_OPEN_WITH1;
       command_id <= IDC_CONTENT_CONTEXT_OPEN_WITH_LAST; ++command_id) {
    const auto it = handlers_.find(command_id);
    if (command_id == submenu_parent_id) {
      // Show the submenu parent.
      proxy_->UpdateMenuItem(command_id, true, false, more_apps_label_);
    } else if (it == handlers_.end()) {
      // Hide the menu or submenu parent.
      proxy_->UpdateMenuItem(command_id, false, true, base::EmptyString16());
    } else {
      // Update the menu with the new model.
      const base::string16 label =
          l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_OPEN_WITH_APP,
                                     base::UTF8ToUTF16(it->second.name));
      proxy_->UpdateMenuItem(command_id, true, false, label);
      if (!it->second.icon.IsEmpty())
        proxy_->UpdateMenuIcon(command_id, it->second.icon);
    }
  }
}

void OpenWithMenuObserver::AddPlaceholderItemsForTesting(
    RenderViewContextMenuProxy* proxy,
    ui::SimpleMenuModel* submenu) {
  return AddPlaceholderItems(proxy, submenu);
}

std::pair<OpenWithMenuObserver::HandlerMap, int>
OpenWithMenuObserver::BuildHandlersMapForTesting(
    const std::vector<ash::LinkHandlerInfo>& handlers) {
  return BuildHandlersMap(handlers);
}

void OpenWithMenuObserver::AddPlaceholderItems(
    RenderViewContextMenuProxy* proxy,
    ui::SimpleMenuModel* submenu) {
  for (int i = 0; i < kNumSubMenuCommands; ++i) {
    const int command_id =
        IDC_CONTENT_CONTEXT_OPEN_WITH1 + kNumMainMenuCommands + i;
    submenu->AddItem(command_id, base::EmptyString16());
  }
  int command_id;
  for (int i = 0; i < kNumMainMenuCommands - 1; ++i) {
    command_id = IDC_CONTENT_CONTEXT_OPEN_WITH1 + i;
    proxy->AddMenuItem(command_id, base::EmptyString16());
  }
  proxy->AddSubMenu(++command_id, base::EmptyString16(), submenu);
}

std::pair<OpenWithMenuObserver::HandlerMap, int>
OpenWithMenuObserver::BuildHandlersMap(
    const std::vector<ash::LinkHandlerInfo>& handlers) {
  const int kInvalidCommandId = -1;
  const int submenu_id_start =
      IDC_CONTENT_CONTEXT_OPEN_WITH1 + kNumMainMenuCommands;

  OpenWithMenuObserver::HandlerMap handler_map;
  int submenu_parent_command_id = kInvalidCommandId;

  const int num_apps = handlers.size();
  size_t handlers_index = 0;
  // We use the last item in the main menu (IDC_CONTENT_CONTEXT_OPEN_WITH1 +
  // kNumMainMenuCommands- 1) as a parent of a submenu, and others as regular
  // menu items.
  if (num_apps < kNumMainMenuCommands) {
    // All apps can be shown with the regular main menu items.
    for (int i = 0; i < num_apps; ++i) {
      handler_map[IDC_CONTENT_CONTEXT_OPEN_WITH1 + i] =
          handlers[handlers_index++];
    }
  } else {
    // Otherwise, use the submenu too. In this case, disable the last item of
    // the regular main menu (hence '-2').
    for (int i = 0; i < kNumMainMenuCommands - 2; ++i) {
      handler_map[IDC_CONTENT_CONTEXT_OPEN_WITH1 + i] =
          handlers[handlers_index++];
    }
    submenu_parent_command_id =
        IDC_CONTENT_CONTEXT_OPEN_WITH1 + kNumMainMenuCommands - 1;
    const int sub_items =
        std::min(num_apps - (kNumMainMenuCommands - 2), kNumSubMenuCommands);
    for (int i = 0; i < sub_items; ++i) {
      handler_map[submenu_id_start + i] = handlers[handlers_index++];
    }
  }

  return std::make_pair(std::move(handler_map), submenu_parent_command_id);
}

RenderViewContextMenuObserver* OpenWithMenuFactory::CreateMenu(
    RenderViewContextMenuProxy* proxy) {
  return new OpenWithMenuObserver(proxy);
}
