// Copyright 2021 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/ui/commander/tab_command_source.h"

#include <numeric>
#include <string>

#include "base/bind.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ui/accelerator_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/commander/entity_match.h"
#include "chrome/browser/ui/commander/fuzzy_finder.h"
#include "chrome/browser/ui/tabs/tab_group_model.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/grit/generated_resources.h"
#include "components/sessions/content/session_tab_helper.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/list_selection_model.h"

namespace commander {

namespace {

// TODO(lgrey): It *might* make to pull this out later into a CommandSource
// method or a free function in some common place. Not committing yet.
std::unique_ptr<CommandItem> ItemForTitle(const std::u16string& title,
                                          FuzzyFinder& finder,
                                          std::vector<gfx::Range>* ranges) {
  double score = finder.Find(title, ranges);
  if (score > 0)
    return std::make_unique<CommandItem>(title, score, *ranges);
  return nullptr;
}

// Returns the tab group that the currently selected tabs can *not* be moved to.
// In practice, this is the tab group that *all* selected tabs belong to, if
// any. In the common special case of single selection, this will return that
// tab's group if it has one.
base::Optional<tab_groups::TabGroupId> IneligibleGroupForSelected(
    TabStripModel* tab_strip_model) {
  base::Optional<tab_groups::TabGroupId> excluded_group = base::nullopt;
  for (int index : tab_strip_model->selection_model().selected_indices()) {
    auto group = tab_strip_model->GetTabGroupForTab(index);
    if (group.has_value()) {
      if (!excluded_group.has_value()) {
        excluded_group = group;
      } else if (group != excluded_group) {
        // More than one group in the selection, so don't exclude anything.
        return base::nullopt;
      }
    }
  }
  return excluded_group;
}

// Returns true only if `browser` is alive, and the contents at `index` match
// `tab_session_id`.
bool DoesTabAtIndexMatchSessionId(base::WeakPtr<Browser> browser,
                                  int index,
                                  int tab_session_id) {
  if (!browser.get())
    return false;
  if (browser->tab_strip_model()->count() <= index)
    return false;
  content::WebContents* contents =
      browser->tab_strip_model()->GetWebContentsAt(index);
  DCHECK(contents);
  return sessions::SessionTabHelper::IdForTab(contents).id() == tab_session_id;
}

// Commands:

// TODO(lgrey): If this command ships, upstream these to TabStripModel
// (and get access to private methods for consistency).
bool CanCloseTabsToLeft(const TabStripModel* model) {
  const ui::ListSelectionModel& selection = model->selection_model();
  if (selection.empty())
    return false;
  int left_selected = *(selection.selected_indices().cbegin());
  for (int i = 0; i < left_selected; ++i) {
    if (!model->IsTabPinned(i))
      return true;
  }
  return false;
}

void CloseTabsToLeft(Browser* browser) {
  TabStripModel* model = browser->tab_strip_model();
  const ui::ListSelectionModel& selection = model->selection_model();
  if (selection.empty())
    return;
  int left_selected = *(selection.selected_indices().cbegin());
  for (int i = left_selected - 1; i >= 0; --i) {
    model->CloseWebContentsAt(i, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB |
                                     TabStripModel::CLOSE_USER_GESTURE);
  }
}

bool HasUnpinnedTabs(const TabStripModel* model) {
  return model->IndexOfFirstNonPinnedTab() < model->count();
}

bool HasPinnedTabs(const TabStripModel* model) {
  return model->IndexOfFirstNonPinnedTab() > 0;
}

void CloseUnpinnedTabs(Browser* browser) {
  TabStripModel* model = browser->tab_strip_model();
  for (int i = model->count() - 1; i >= 0; --i) {
    if (!model->IsTabPinned(i))
      model->CloseWebContentsAt(i, TabStripModel::CLOSE_CREATE_HISTORICAL_TAB |
                                       TabStripModel::CLOSE_USER_GESTURE);
  }
}

bool CanMoveTabsToExistingWindow(const Browser* browser_to_exclude) {
  const BrowserList* browser_list = BrowserList::GetInstance();
  return std::any_of(
      browser_list->begin(), browser_list->end(),
      [browser_to_exclude](Browser* browser) {
        return browser != browser_to_exclude && browser->is_type_normal() &&
               browser->profile() == browser_to_exclude->profile();
      });
}

void MoveTabsToExistingWindow(base::WeakPtr<Browser> source,
                              base::WeakPtr<Browser> target) {
  if (!source.get() || !target.get())
    return;
  const ui::ListSelectionModel::SelectedIndices& sel =
      source->tab_strip_model()->selection_model().selected_indices();
  chrome::MoveTabsToExistingWindow(source.get(), target.get(),
                                   std::vector<int>(sel.begin(), sel.end()));
}

bool CanAddAllToNewGroup(const TabStripModel* model) {
  return model->group_model()->ListTabGroups().size() == 0;
}

void AddAllToNewGroup(Browser* browser) {
  std::vector<int> indices(browser->tab_strip_model()->count());
  std::iota(indices.begin(), indices.end(), 0);
  browser->tab_strip_model()->AddToNewGroup(indices);
}

void AddSelectedToNewGroup(Browser* browser) {
  TabStripModel* model = browser->tab_strip_model();
  const ui::ListSelectionModel::SelectedIndices& sel =
      model->selection_model().selected_indices();
  model->AddToNewGroup(std::vector<int>(sel.begin(), sel.end()));
}

void MuteAllTabs(Browser* browser, bool exclude_active) {
  TabStripModel* model = browser->tab_strip_model();
  for (int i = 0; i < model->count(); ++i) {
    if (exclude_active && i == model->active_index())
      return;
    content::WebContents* contents = model->GetWebContentsAt(i);
    if (contents->IsCurrentlyAudible())
      contents->SetAudioMuted(true);
  }
}

// TODO(lgrey): Precalculate tab strip properties like "has audible tabs", "has
// pinned tabs" etc. in one iteration at search time.
bool HasAudibleTabs(const TabStripModel* model) {
  for (int i = 0; i < model->count(); ++i) {
    content::WebContents* contents = model->GetWebContentsAt(i);
    if (contents->IsCurrentlyAudible())
      return true;
  }
  return false;
}

bool HasMutedTabs(const TabStripModel* model) {
  for (int i = 0; i < model->count(); ++i) {
    content::WebContents* contents = model->GetWebContentsAt(i);
    if (contents->IsAudioMuted())
      return true;
  }
  return false;
}

void ScrollToTop(Browser* browser) {
  browser->tab_strip_model()->GetActiveWebContents()->ScrollToTopOfDocument();
}

void ScrollToBottom(Browser* browser) {
  browser->tab_strip_model()
      ->GetActiveWebContents()
      ->ScrollToBottomOfDocument();
}

// Multiphase commands:

void MuteUnmuteTab(base::WeakPtr<Browser> browser,
                   int tab_index,
                   int tab_session_id,
                   bool mute) {
  if (!DoesTabAtIndexMatchSessionId(browser, tab_index, tab_session_id))
    return;
  browser->tab_strip_model()->GetWebContentsAt(tab_index)->SetAudioMuted(mute);
}

std::unique_ptr<CommandItem> CreateMuteUnmuteTabItem(const TabMatch& match,
                                                     Browser* browser,
                                                     bool mute) {
  auto item = match.ToCommandItem();
  item->command = base::BindOnce(&MuteUnmuteTab, browser->AsWeakPtr(),
                                 match.index, match.session_id, mute);
  return item;
}

CommandSource::CommandResults MuteUnmuteTabItemsForTabsMatching(
    Browser* browser,
    bool mute,
    const std::u16string& input) {
  CommandSource::CommandResults results;
  TabSearchOptions options;
  if (mute)
    options.only_audible = true;
  else
    options.only_muted = true;
  for (auto& match : TabsMatchingInput(browser, input, options)) {
    results.push_back(CreateMuteUnmuteTabItem(match, browser, mute));
  }
  return results;
}

void TogglePinTab(base::WeakPtr<Browser> browser,
                  int tab_index,
                  int tab_session_id,
                  bool pin) {
  if (!DoesTabAtIndexMatchSessionId(browser, tab_index, tab_session_id))
    return;
  browser->tab_strip_model()->SetTabPinned(tab_index, pin);
}

std::unique_ptr<CommandItem> CreatePinTabItem(const TabMatch& match,
                                              Browser* browser,
                                              bool pin) {
  auto item = match.ToCommandItem();
  item->command = base::BindOnce(&TogglePinTab, browser->AsWeakPtr(),
                                 match.index, match.session_id, pin);
  return item;
}

CommandSource::CommandResults TogglePinTabCommandsForTabsMatching(
    Browser* browser,
    bool pin,
    const std::u16string& input) {
  CommandSource::CommandResults results;
  TabSearchOptions options;
  if (pin)
    options.only_unpinned = true;
  else
    options.only_pinned = true;
  for (auto& match : TabsMatchingInput(browser, input, options)) {
    results.push_back(CreatePinTabItem(match, browser, pin));
  }
  return results;
}

std::unique_ptr<CommandItem> CreateMoveTabsToWindowItem(
    Browser* source,
    const WindowMatch& match) {
  auto item = match.ToCommandItem();
  item->command = base::BindOnce(&MoveTabsToExistingWindow, source->AsWeakPtr(),
                                 match.browser->AsWeakPtr());
  return item;
}

CommandSource::CommandResults MoveTabsToWindowCommandsForWindowsMatching(
    Browser* source,
    const std::u16string& input) {
  CommandSource::CommandResults results;
  // Add "New Window", if appropriate. It should score highest with no input.
  std::u16string new_window_title = l10n_util::GetStringUTF16(IDS_NEW_WINDOW);
  base::Erase(new_window_title, '&');
  std::unique_ptr<CommandItem> item;
  if (input.empty()) {
    item = std::make_unique<CommandItem>(new_window_title, .99,
                                         std::vector<gfx::Range>());
  } else {
    FuzzyFinder finder(input);
    std::vector<gfx::Range> ranges;
    item = ItemForTitle(new_window_title, finder, &ranges);
  }
  if (item) {
    item->entity_type = CommandItem::Entity::kWindow;
    item->command = base::BindOnce(&chrome::MoveActiveTabToNewWindow,
                                   base::Unretained(source));
    results.push_back(std::move(item));
  }
  for (auto& match : WindowsMatchingInput(source, input))
    results.push_back(CreateMoveTabsToWindowItem(source, match));
  return results;
}

void AddTabsToGroup(base::WeakPtr<Browser> browser,
                    tab_groups::TabGroupId group) {
  if (!browser.get())
    return;
  const ui::ListSelectionModel::SelectedIndices& sel =
      browser->tab_strip_model()->selection_model().selected_indices();
  browser->tab_strip_model()->AddToExistingGroup(
      std::vector<int>(sel.begin(), sel.end()), group);
}

CommandSource::CommandResults AddTabsToGroupCommandsForGroupsMatching(
    Browser* browser,
    const std::u16string& input) {
  CommandSource::CommandResults results;
  TabStripModel* tab_strip_model = browser->tab_strip_model();
  // Add "New Group", if appropriate. It should score highest with no input.
  std::u16string new_group_title =
      l10n_util::GetStringUTF16(IDS_TAB_CXMENU_SUBMENU_NEW_GROUP);
  std::unique_ptr<CommandItem> item;
  if (input.empty()) {
    item = std::make_unique<CommandItem>(new_group_title, .99,
                                         std::vector<gfx::Range>());
  } else {
    FuzzyFinder finder(input);
    std::vector<gfx::Range> ranges;
    item = ItemForTitle(new_group_title, finder, &ranges);
  }
  if (item) {
    item->entity_type = CommandItem::Entity::kGroup;
    item->command =
        base::BindOnce(&AddSelectedToNewGroup, base::Unretained(browser));
    results.push_back(std::move(item));
  }
  for (auto& match : GroupsMatchingInput(
           browser, input, IneligibleGroupForSelected(tab_strip_model))) {
    auto item = match.ToCommandItem();
    item->command =
        base::BindOnce(&AddTabsToGroup, browser->AsWeakPtr(), match.group);
    results.push_back(std::move(item));
  }
  return results;
}

}  // namespace

TabCommandSource::TabCommandSource() = default;
TabCommandSource::~TabCommandSource() = default;

CommandSource::CommandResults TabCommandSource::GetCommands(
    const std::u16string& input,
    Browser* browser) const {
  CommandSource::CommandResults results;
  FuzzyFinder finder(input);
  std::vector<gfx::Range> ranges;
  ui::AcceleratorProvider* provider =
      chrome::AcceleratorProviderForBrowser(browser);

  TabStripModel* tab_strip_model = browser->tab_strip_model();
  // TODO(lgrey): Temporarily using hardcoded English titles instead of
  // translated strings so we can experiment without adding translation load.
  if (auto item = ItemForTitle(u"Close current tab", finder, &ranges)) {
    item->command =
        base::BindOnce(&chrome::CloseTab, base::Unretained(browser));
    ui::Accelerator accelerator;
    if (provider->GetAcceleratorForCommandId(IDC_CLOSE_TAB, &accelerator))
      item->annotation = accelerator.GetShortcutText();
    results.push_back(std::move(item));
  }
  if (chrome::CanCloseOtherTabs(browser)) {
    if (auto item = ItemForTitle(u"Close other tabs", finder, &ranges)) {
      item->command =
          base::BindOnce(&chrome::CloseOtherTabs, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }
  if (chrome::CanCloseTabsToRight(browser)) {
    if (auto item = ItemForTitle(u"Close tabs to the right", finder, &ranges)) {
      item->command =
          base::BindOnce(&chrome::CloseTabsToRight, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (CanCloseTabsToLeft(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Close tabs to the left", finder, &ranges)) {
      item->command =
          base::BindOnce(&CloseTabsToLeft, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (HasUnpinnedTabs(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Close unpinned tabs", finder, &ranges)) {
      item->command =
          base::BindOnce(&CloseUnpinnedTabs, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (chrome::CanMoveActiveTabToNewWindow(browser)) {
    if (auto item =
            ItemForTitle(l10n_util::GetStringUTF16(IDS_MOVE_TAB_TO_NEW_WINDOW),
                         finder, &ranges)) {
      item->command = base::BindOnce(chrome::MoveActiveTabToNewWindow,
                                     base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (CanMoveTabsToExistingWindow(browser)) {
    if (auto item = ItemForTitle(u"Move tabs to window...", finder, &ranges)) {
      item->command = std::make_pair(
          u"Move tabs to...",
          base::BindRepeating(&MoveTabsToWindowCommandsForWindowsMatching,
                              base::Unretained(browser)));
      results.push_back(std::move(item));
    }
  }

  if (CanAddAllToNewGroup(tab_strip_model)) {
    if (auto item =
            ItemForTitle(u"Move all tabs to new group", finder, &ranges)) {
      item->command =
          base::BindOnce(&AddAllToNewGroup, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (!tab_strip_model->WillContextMenuGroup(tab_strip_model->active_index())) {
    if (auto item = ItemForTitle(u"Ungroup tab", finder, &ranges)) {
      item->command =
          base::BindOnce(&chrome::GroupTab, base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }
  if (auto item = ItemForTitle(u"Add tab to group...", finder, &ranges)) {
    item->command = std::make_pair(
        u"Add to group...",
        base::BindRepeating(&AddTabsToGroupCommandsForGroupsMatching,
                            base::Unretained(browser)));
    results.push_back(std::move(item));
  }
  if (auto item = ItemForTitle(u"Mute all tabs", finder, &ranges)) {
    item->command =
        base::BindOnce(&MuteAllTabs, base::Unretained(browser), false);
    results.push_back(std::move(item));
  }

  if (auto item = ItemForTitle(u"Mute other tabs", finder, &ranges)) {
    item->command =
        base::BindOnce(&MuteAllTabs, base::Unretained(browser), false);
    results.push_back(std::move(item));
  }

  if (HasAudibleTabs(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Mute tab...", finder, &ranges)) {
      item->command =
          std::make_pair(u"Mute tab...",
                         base::BindRepeating(&MuteUnmuteTabItemsForTabsMatching,
                                             base::Unretained(browser), true));
      results.push_back(std::move(item));
    }
  }

  if (HasMutedTabs(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Unmute tab...", finder, &ranges)) {
      item->command =
          std::make_pair(u"Unmute tab...",
                         base::BindRepeating(&MuteUnmuteTabItemsForTabsMatching,
                                             base::Unretained(browser), false));
      results.push_back(std::move(item));
    }
  }

  if (HasUnpinnedTabs(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Pin tab...", finder, &ranges)) {
      item->command = std::make_pair(
          u"Pin tab...",
          base::BindRepeating(&TogglePinTabCommandsForTabsMatching,
                              base::Unretained(browser), true));
      results.push_back((std::move(item)));
    }
  }

  if (HasPinnedTabs(tab_strip_model)) {
    if (auto item = ItemForTitle(u"Unpin tab...", finder, &ranges)) {
      item->command = std::make_pair(
          u"Unpin tab...",
          base::BindRepeating(&TogglePinTabCommandsForTabsMatching,
                              base::Unretained(browser), false));
      results.push_back((std::move(item)));
    }
  }

  if (chrome::CanMoveActiveTabToReadLater(browser)) {
    if (auto item = ItemForTitle(u"Add to Read Later", finder, &ranges)) {
      item->command =
          base::BindOnce(IgnoreResult(&chrome::MoveCurrentTabToReadLater),
                         base::Unretained(browser));
      results.push_back(std::move(item));
    }
  }

  if (auto item = ItemForTitle(u"Scroll to top", finder, &ranges)) {
    item->command = base::BindOnce(&ScrollToTop, base::Unretained(browser));
    results.push_back(std::move(item));
  }

  if (auto item = ItemForTitle(u"Scroll to bottom", finder, &ranges)) {
    item->command = base::BindOnce(&ScrollToBottom, base::Unretained(browser));
    results.push_back(std::move(item));
  }

  return results;
}

}  // namespace commander
