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

#ifndef CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_
#define CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_

#include <stddef.h>
#include <stdint.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/containers/span.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_multi_source_observation.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/browser/ui/tabs/tab_group_controller.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
#include "chrome/browser/ui/tabs/tab_switch_event_latency_recorder.h"
#include "components/sessions/core/session_id.h"
#include "components/tab_groups/tab_group_id.h"
#include "components/tab_groups/tab_group_visual_data.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
#include "ui/base/models/list_selection_model.h"
#include "ui/base/page_transition_types.h"

#if BUILDFLAG(IS_ANDROID)
#error This file should only be included on desktop.
#endif

class Profile;
class TabGroupModel;
class TabStripModelDelegate;
class TabStripModelObserver;

namespace content {
class WebContents;
}

class TabGroupModelFactory {
 public:
  TabGroupModelFactory();
  TabGroupModelFactory(const TabGroupModelFactory&) = delete;
  TabGroupModelFactory& operator=(const TabGroupModelFactory&) = delete;

  static TabGroupModelFactory* GetInstance();
  std::unique_ptr<TabGroupModel> Create(TabGroupController* controller);
};

////////////////////////////////////////////////////////////////////////////////
//
// TabStripModel
//
// A model & low level controller of a Browser Window tabstrip. Holds a vector
// of WebContents, and provides an API for adding, removing and
// shuffling them, as well as a higher level API for doing specific Browser-
// related tasks like adding new Tabs from just a URL, etc.
//
// Each tab may be pinned. Pinned tabs are locked to the left side of the tab
// strip and rendered differently (small tabs with only a favicon). The model
// makes sure all pinned tabs are at the beginning of the tab strip. For
// example, if a non-pinned tab is added it is forced to be with non-pinned
// tabs. Requests to move tabs outside the range of the tab type are ignored.
// For example, a request to move a pinned tab after non-pinned tabs is ignored.
//
// A TabStripModel has one delegate that it relies on to perform certain tasks
// like creating new TabStripModels (probably hosted in Browser windows) when
// required. See TabStripDelegate above for more information.
//
// A TabStripModel also has N observers (see TabStripModelObserver above),
// which can be registered via Add/RemoveObserver. An Observer is notified of
// tab creations, removals, moves, and other interesting events. The
// TabStrip implements this interface to know when to create new tabs in
// the View, and the Browser object likewise implements to be able to update
// its bookkeeping when such events happen.
//
// This implementation of TabStripModel is not thread-safe and should only be
// accessed on the UI thread.
//
////////////////////////////////////////////////////////////////////////////////
class TabStripModel : public TabGroupController {
 public:
  // Used to specify what should happen when the tab is closed.
  enum CloseTypes {
    CLOSE_NONE                     = 0,

    // Indicates the tab was closed by the user. If true,
    // WebContents::SetClosedByUserGesture(true) is invoked.
    CLOSE_USER_GESTURE             = 1 << 0,

    // If true the history is recorded so that the tab can be reopened later.
    // You almost always want to set this.
    CLOSE_CREATE_HISTORICAL_TAB    = 1 << 1,
  };

  // Constants used when adding tabs.
  enum AddTabTypes {
    // Used to indicate nothing special should happen to the newly inserted tab.
    ADD_NONE = 0,

    // The tab should be active.
    ADD_ACTIVE = 1 << 0,

    // The tab should be pinned.
    ADD_PINNED = 1 << 1,

    // If not set the insertion index of the WebContents is left up to the Order
    // Controller associated, so the final insertion index may differ from the
    // specified index. Otherwise the index supplied is used.
    ADD_FORCE_INDEX = 1 << 2,

    // If set the newly inserted tab's opener is set to the active tab. If not
    // set the tab may still inherit the opener under certain situations.
    ADD_INHERIT_OPENER = 1 << 3,
  };

  // Enumerates different ways to open a new tab. Does not apply to opening
  // existing links or searches in a new tab, only to brand new empty tabs.
  // KEEP IN SYNC WITH THE NewTabType ENUM IN enums.xml.
  // NEW VALUES MUST BE APPENDED AND AVOID CHANGING ANY PRE-EXISTING VALUES.
  enum NewTab {
    // New tab was opened using the new tab button on the tab strip.
    NEW_TAB_BUTTON = 0,

    // New tab was opened using the menu command - either through the keyboard
    // shortcut, or by opening the menu and selecting the command. Applies to
    // both app menu and the menu bar's File menu (on platforms that have one).
    NEW_TAB_COMMAND = 1,

    // New tab was opened through the context menu on the tab strip.
    NEW_TAB_CONTEXT_MENU = 2,

    // New tab was opened through the new tab button in the toolbar for the
    // WebUI touch-optimized tab strip.
    NEW_TAB_BUTTON_IN_TOOLBAR_FOR_TOUCH = 3,

    // New tab was opened through the new tab button inside of the WebUI tab
    // strip.
    NEW_TAB_BUTTON_IN_WEBUI_TAB_STRIP = 4,

    // Number of enum entries, used for UMA histogram reporting macros.
    NEW_TAB_ENUM_COUNT = 5,
  };

  // Enumerates different types of tab activation. Mainly used for
  // comparison between classic tab strip and WebUI tab strip.
  // KEEP IN SYNC WITH THE TabActivationTypes ENUM IN enums.xml.
  // NEW VALUES MUST BE APPENDED AND AVOID CHANGING ANY PRE-EXISTING VALUES.
  enum class TabActivationTypes {
    // Switch to a tab.
    kTab = 0,
    // Open the context menu of a tab.
    kContextMenu = 1,
    kMaxValue = kContextMenu,
  };

  // Holds state for a WebContents that has been detached from the tab strip.
  // Will also handle WebContents deletion if |remove_reason| is kDeleted, or
  // WebContents caching if |remove_reason| is kCached.
  // TODO(https://crbug.com/1234327): Don't make DetachedWebContents an inner
  // class, so it can be forward declared in TabStripModelDelegate.
  struct DetachedWebContents {
    DetachedWebContents(int index_before_any_removals,
                        int index_at_time_of_removal,
                        std::unique_ptr<content::WebContents> owned_contents,
                        content::WebContents* contents,
                        TabStripModelChange::RemoveReason remove_reason,
                        absl::optional<SessionID> id);
    DetachedWebContents(const DetachedWebContents&) = delete;
    DetachedWebContents& operator=(const DetachedWebContents&) = delete;
    ~DetachedWebContents();
    DetachedWebContents(DetachedWebContents&&);

    // When a WebContents is removed the delegate is given a chance to
    // take ownership of it (generally for caching). If the delegate takes
    // ownership, `owned_contents` will be null, and `contents` will be
    // non-null. In other words, all observers should use `contents`, it is
    // guaranteed to be valid for the life time of the notification (and
    // possibly longer).
    std::unique_ptr<content::WebContents> owned_contents;
    raw_ptr<content::WebContents> contents;

    // The index of the WebContents in the original selection model of the tab
    // strip [prior to any tabs being removed, if multiple tabs are being
    // simultaneously removed].
    const int index_before_any_removals;

    // The index of the WebContents at the time it is being removed. If multiple
    // tabs are being simultaneously removed, the index reflects previously
    // removed tabs in this batch.
    const int index_at_time_of_removal;

    TabStripModelChange::RemoveReason remove_reason;

    // The |contents| associated optional SessionID, used as key for
    // ClosedTabCache. We only cache |contents| if |remove_reason| is kCached.
    absl::optional<SessionID> id;
  };

  static constexpr int kNoTab = -1;

  TabStripModel() = delete;

  // Construct a TabStripModel with a delegate to help it do certain things
  // (see the TabStripModelDelegate documentation). |delegate| cannot be NULL.
  // the TabGroupModelFactory can be replaced with a nullptr to set the
  // group_model to null in cases where groups are not supported.
  explicit TabStripModel(TabStripModelDelegate* delegate,
                         Profile* profile,
                         TabGroupModelFactory* group_model_factory =
                             TabGroupModelFactory::GetInstance());

  TabStripModel(const TabStripModel&) = delete;
  TabStripModel& operator=(const TabStripModel&) = delete;

  ~TabStripModel() override;

  // Retrieves the TabStripModelDelegate associated with this TabStripModel.
  TabStripModelDelegate* delegate() const { return delegate_; }

  // Sets the TabStripModelObserver used by the UI showing the tabs. As other
  // observers may query the UI for state, the UI's observer must be first.
  void SetTabStripUI(TabStripModelObserver* observer);

  // Add and remove observers to changes within this TabStripModel.
  void AddObserver(TabStripModelObserver* observer);
  void RemoveObserver(TabStripModelObserver* observer);

  // Retrieve the number of WebContentses/emptiness of the TabStripModel.
  int count() const { return static_cast<int>(contents_data_.size()); }
  bool empty() const { return contents_data_.empty(); }

  // Retrieve the Profile associated with this TabStripModel.
  Profile* profile() const { return profile_; }

  // Retrieve the index of the currently active WebContents. This will be
  // ui::ListSelectionModel::kUnselectedIndex if no tab is currently selected
  // (this happens while the tab strip is being initialized or is empty).
  int active_index() const { return selection_model_.active(); }

  // Returns true if the tabstrip is currently closing all open tabs (via a
  // call to CloseAllTabs). As tabs close, the selection in the tabstrip
  // changes which notifies observers, which can use this as an optimization to
  // avoid doing meaningless or unhelpful work.
  bool closing_all() const { return closing_all_; }

  // Basic API /////////////////////////////////////////////////////////////////

  // Determines if the specified index is contained within the TabStripModel.
  bool ContainsIndex(int index) const;

  // Adds the specified WebContents in the default location. Tabs opened
  // in the foreground inherit the opener of the previously active tab.
  void AppendWebContents(std::unique_ptr<content::WebContents> contents,
                         bool foreground);

  // Adds the specified WebContents at the specified location.
  // |add_types| is a bitmask of AddTabTypes; see it for details.
  //
  // All append/insert methods end up in this method.
  //
  // NOTE: adding a tab using this method does NOT query the order controller,
  // as such the ADD_FORCE_INDEX AddTabTypes is meaningless here. The only time
  // the |index| is changed is if using the index would result in breaking the
  // constraint that all pinned tabs occur before non-pinned tabs. It returns
  // the index the web contents is actually inserted to. See also
  // AddWebContents.
  int InsertWebContentsAt(
      int index,
      std::unique_ptr<content::WebContents> contents,
      int add_types,
      absl::optional<tab_groups::TabGroupId> group = absl::nullopt);
  // Closes the WebContents at the specified index. This causes the
  // WebContents to be destroyed, but it may not happen immediately.
  // |close_types| is a bitmask of CloseTypes. Returns true if the
  // WebContents was closed immediately, false if it was not closed (we
  // may be waiting for a response from an onunload handler, or waiting for the
  // user to confirm closure).
  bool CloseWebContentsAt(int index, uint32_t close_types);

  // Replaces the WebContents at |index| with |new_contents|. The
  // WebContents that was at |index| is returned and its ownership returns
  // to the caller.
  std::unique_ptr<content::WebContents> ReplaceWebContentsAt(
      int index,
      std::unique_ptr<content::WebContents> new_contents);

  // Detaches the WebContents at the specified index for reinsertion into
  // another tab strip. Returns the detached WebContents.
  std::unique_ptr<content::WebContents> DetachWebContentsAtForInsertion(
      int index);

  // Detaches the WebContents at the specified index and immediately deletes it.
  void DetachAndDeleteWebContentsAt(int index);

  // Makes the tab at the specified index the active tab. |gesture_detail.type|
  // contains the gesture type that triggers the tab activation.
  // |gesture_detail.time_stamp| contains the timestamp of the user gesture, if
  // any.
  void ActivateTabAt(
      int index,
      TabStripUserGestureDetails gesture_detail = TabStripUserGestureDetails(
          TabStripUserGestureDetails::GestureType::kNone));

  // Report histogram metrics for the number of tabs 'scrubbed' within a given
  // interval of time. Scrubbing is considered to be a tab activated for <= 1.5
  // seconds for this metric.
  void RecordTabScrubbingMetrics();

  // Move the WebContents at the specified index to another index. This
  // method does NOT send Detached/Attached notifications, rather it moves the
  // WebContents inline and sends a Moved notification instead.
  // EnsureGroupContiguity() is called after the move, so this will never result
  // in non-contiguous group (though the moved tab's group may change).
  // If |select_after_move| is false, whatever tab was selected before the move
  // will still be selected, but its index may have incremented or decremented
  // one slot. It returns the index the web contents is actually moved to.
  int MoveWebContentsAt(int index, int to_position, bool select_after_move);

  // Moves the selected tabs to |index|. |index| is treated as if the tab strip
  // did not contain any of the selected tabs. For example, if the tabstrip
  // contains [A b c D E f] (upper case selected) and this is invoked with 1 the
  // result is [b A D E c f].
  // This method maintains that all pinned tabs occur before non-pinned tabs.
  // When pinned tabs are selected the move is processed in two chunks: first
  // pinned tabs are moved, then non-pinned tabs are moved. If the index is
  // after (pinned-tab-count - selected-pinned-tab-count), then the index the
  // non-pinned selected tabs are moved to is (index +
  // selected-pinned-tab-count). For example, if the model consists of
  // [A b c D E f] (A b c are pinned) and this is invoked with 2, the result is
  // [b c A D E f]. In this example nothing special happened because the target
  // index was <= (pinned-tab-count - selected-pinned-tab-count). If the target
  // index were 3, then the result would be [b c A f D F]. A, being pinned, can
  // move no further than index 2. The non-pinned tabs are moved to the target
  // index + selected-pinned tab-count (3 + 1).
  void MoveSelectedTabsTo(int index);

  // Moves all tabs in |group| to |to_index|. This has no checks to make sure
  // the position is valid for a group to move to.
  void MoveGroupTo(const tab_groups::TabGroupId& group, int to_index);

  // Returns the currently active WebContents, or NULL if there is none.
  content::WebContents* GetActiveWebContents() const;

  // Returns the WebContents at the specified index, or NULL if there is
  // none.
  content::WebContents* GetWebContentsAt(int index) const override;

  // Returns the index of the specified WebContents, or TabStripModel::kNoTab
  // if the WebContents is not in this TabStripModel.
  int GetIndexOfWebContents(const content::WebContents* contents) const;

  // Notify any observers that the WebContents at the specified index has
  // changed in some way. See TabChangeType for details of |change_type|.
  void UpdateWebContentsStateAt(int index, TabChangeType change_type);

  // Cause a tab to display a UI indication to the user that it needs their
  // attention.
  void SetTabNeedsAttentionAt(int index, bool attention);

  // Close all tabs at once. Code can use closing_all() above to defer
  // operations that might otherwise by invoked by the flurry of detach/select
  // notifications this method causes.
  void CloseAllTabs();

  // Close all tabs in the given |group| at once.
  void CloseAllTabsInGroup(const tab_groups::TabGroupId& group);

  // Returns true if there are any WebContentses that are currently loading.
  bool TabsAreLoading() const;

  // Returns the WebContents that opened the WebContents at |index|, or NULL if
  // there is no opener on record.
  content::WebContents* GetOpenerOfWebContentsAt(const int index) const;

  // Changes the |opener| of the WebContents at |index|.
  // Note: |opener| must be in this tab strip. Also a tab must not be its own
  // opener.
  void SetOpenerOfWebContentsAt(int index, content::WebContents* opener);

  // Returns the index of the last WebContents in the model opened by the
  // specified opener, starting at |start_index|.
  int GetIndexOfLastWebContentsOpenedBy(const content::WebContents* opener,
                                        int start_index) const;

  // To be called when a navigation is about to occur in the specified
  // WebContents. Depending on the tab, and the transition type of the
  // navigation, the TabStripModel may adjust its selection behavior and opener
  // inheritance.
  void TabNavigating(content::WebContents* contents,
                     ui::PageTransition transition);

  // Changes the blocked state of the tab at |index|.
  void SetTabBlocked(int index, bool blocked);

  // Changes the pinned state of the tab at |index|. See description above
  // class for details on this.
  void SetTabPinned(int index, bool pinned);

  // Returns true if the tab at |index| is pinned.
  // See description above class for details on pinned tabs.
  bool IsTabPinned(int index) const;

  bool IsTabCollapsed(int index) const;

  bool IsGroupCollapsed(const tab_groups::TabGroupId& group) const;

  // Returns true if the tab at |index| is blocked by a tab modal dialog.
  bool IsTabBlocked(int index) const;

  // Returns the group that contains the tab at |index|, or nullopt if the tab
  // index is invalid or not grouped.
  absl::optional<tab_groups::TabGroupId> GetTabGroupForTab(
      int index) const override;

  // If a tab inserted at |index| would be within a tab group, return that
  // group's ID. Otherwise, return nullopt. If |index| points to the first tab
  // in a group, it will return nullopt since a new tab would be either between
  // two different groups or just after a non-grouped tab.
  absl::optional<tab_groups::TabGroupId> GetSurroundingTabGroup(
      int index) const;

  // Returns the index of the first tab that is not a pinned tab. This returns
  // |count()| if all of the tabs are pinned tabs, and 0 if none of the tabs are
  // pinned tabs.
  int IndexOfFirstNonPinnedTab() const;

  // Extends the selection from the anchor to |index|.
  void ExtendSelectionTo(int index);

  // Returns true if the selection was toggled; this can fail if the tabstrip
  // is not editable.
  bool ToggleSelectionAt(int index);

  // Makes sure the tabs from the anchor to |index| are selected. This only
  // adds to the selection.
  void AddSelectionFromAnchorTo(int index);

  // Returns true if the tab at |index| is selected.
  bool IsTabSelected(int index) const;

  // Sets the selection to match that of |source|.
  void SetSelectionFromModel(ui::ListSelectionModel source);

  const ui::ListSelectionModel& selection_model() const;

  // Command level API /////////////////////////////////////////////////////////

  // Adds a WebContents at the best position in the TabStripModel given
  // the specified insertion index, transition, etc. |add_types| is a bitmask of
  // AddTabTypes; see it for details. This method ends up calling into
  // InsertWebContentsAt to do the actual insertion. Pass kNoTab for |index| to
  // append the contents to the end of the tab strip.
  void AddWebContents(
      std::unique_ptr<content::WebContents> contents,
      int index,
      ui::PageTransition transition,
      int add_types,
      absl::optional<tab_groups::TabGroupId> group = absl::nullopt);

  // Closes the selected tabs.
  void CloseSelectedTabs();

  // Select adjacent tabs
  void SelectNextTab(
      TabStripUserGestureDetails detail = TabStripUserGestureDetails(
          TabStripUserGestureDetails::GestureType::kOther));
  void SelectPreviousTab(
      TabStripUserGestureDetails detail = TabStripUserGestureDetails(
          TabStripUserGestureDetails::GestureType::kOther));

  // Selects the last tab in the tab strip.
  void SelectLastTab(
      TabStripUserGestureDetails detail = TabStripUserGestureDetails(
          TabStripUserGestureDetails::GestureType::kOther));

  // Moves the active in the specified direction. Respects group boundaries.
  void MoveTabNext();
  void MoveTabPrevious();

  // Create a new tab group and add the set of tabs pointed to be |indices| to
  // it. Pins all of the tabs if any of them were pinned, and reorders the tabs
  // so they are contiguous and do not split an existing group in half. Returns
  // the new group. |indices| must be sorted in ascending order.
  tab_groups::TabGroupId AddToNewGroup(const std::vector<int>& indices);

  // Add the set of tabs pointed to by |indices| to the given tab group |group|.
  // The tabs take on the pinnedness of the tabs already in the group, and are
  // moved to immediately follow the tabs already in the group. |indices| must
  // be sorted in ascending order.
  void AddToExistingGroup(const std::vector<int>& indices,
                          const tab_groups::TabGroupId& group);

  // Moves the set of tabs indicated by |indices| to precede the tab at index
  // |destination_index|, maintaining their order and the order of tabs not
  // being moved, and adds them to the tab group |group|.
  void MoveTabsAndSetGroup(const std::vector<int>& indices,
                           int destination_index,
                           absl::optional<tab_groups::TabGroupId> group);

  // Similar to AddToExistingGroup(), but creates a group with id |group| if it
  // doesn't exist. This is only intended to be called from session restore
  // code.
  void AddToGroupForRestore(const std::vector<int>& indices,
                            const tab_groups::TabGroupId& group);

  // Updates the tab group of the tab at |index|. If |group| is nullopt, the tab
  // will be removed from the current group. If |group| does not exist, it will
  // create the group then add the tab to the group.
  void UpdateGroupForDragRevert(
      int index,
      absl::optional<tab_groups::TabGroupId> group_id,
      absl::optional<tab_groups::TabGroupVisualData> group_data);

  // Removes the set of tabs pointed to by |indices| from the the groups they
  // are in, if any. The tabs are moved out of the group if necessary. |indices|
  // must be sorted in ascending order.
  void RemoveFromGroup(const std::vector<int>& indices);

  TabGroupModel* group_model() const { return group_model_.get(); }

  bool SupportsTabGroups() const { return group_model_.get() != nullptr; }

  // Returns true if one or more of the tabs pointed to by |indices| are
  // supported by read later.
  bool IsReadLaterSupportedForAny(const std::vector<int>& indices);

  // Saves tabs with url supported by Read Later.
  void AddToReadLater(const std::vector<int>& indices);

  // Follows/unfollows a web feed for a set of website.
  void FollowSites(const std::vector<int>& indices);
  void UnfollowSites(const std::vector<int>& indices);

  // TabGroupController:
  Profile* GetProfile() override;
  void CreateTabGroup(const tab_groups::TabGroupId& group) override;
  void OpenTabGroupEditor(const tab_groups::TabGroupId& group) override;
  void ChangeTabGroupContents(const tab_groups::TabGroupId& group) override;
  void ChangeTabGroupVisuals(
      const tab_groups::TabGroupId& group,
      const TabGroupChange::VisualsChange& visuals) override;
  void MoveTabGroup(const tab_groups::TabGroupId& group) override;
  void CloseTabGroup(const tab_groups::TabGroupId& group) override;
  // The same as count(), but overridden for TabGroup to access.
  int GetTabCount() const override;

  // View API //////////////////////////////////////////////////////////////////

  // Context menu functions. Tab groups uses command ids following CommandLast
  // for entries in the 'Add to existing group' submenu.
  enum ContextMenuCommand {
    CommandFirst,
    CommandNewTabToRight,
    CommandReload,
    CommandDuplicate,
    CommandCloseTab,
    CommandCloseOtherTabs,
    CommandCloseTabsToRight,
    CommandTogglePinned,
    CommandToggleGrouped,
    CommandToggleSiteMuted,
    CommandSendTabToSelf,
    CommandAddToReadLater,
    CommandAddToNewGroup,
    CommandAddToExistingGroup,
    CommandRemoveFromGroup,
    CommandMoveToExistingWindow,
    CommandMoveTabsToNewWindow,
    CommandFollowSite,
    CommandUnfollowSite,
    CommandLast
  };

  // Returns true if the specified command is enabled. If |context_index| is
  // selected the response applies to all selected tabs.
  bool IsContextMenuCommandEnabled(int context_index,
                                   ContextMenuCommand command_id) const;

  // Performs the action associated with the specified command for the given
  // TabStripModel index |context_index|.  If |context_index| is selected the
  // command applies to all selected tabs.
  void ExecuteContextMenuCommand(int context_index,
                                 ContextMenuCommand command_id);

  // Adds the tab at |context_index| to the given tab group |group|. If
  // |context_index| is selected the command applies to all selected tabs.
  void ExecuteAddToExistingGroupCommand(int context_index,
                                        const tab_groups::TabGroupId& group);

  // Adds the tab at |context_index| to the browser window at |browser_index|.
  // If |context_index| is selected the command applies to all selected tabs.
  void ExecuteAddToExistingWindowCommand(int context_index, int browser_index);

  // Returns true if 'CommandToggleSiteMuted' will mute. |index| is the
  // index supplied to |ExecuteContextMenuCommand|.
  bool WillContextMenuMuteSites(int index);

  // Returns true if 'CommandTogglePinned' will pin. |index| is the index
  // supplied to |ExecuteContextMenuCommand|.
  bool WillContextMenuPin(int index);

  // Returns true if 'CommandToggleGrouped' will group. |index| is the index
  // supplied to |ExecuteContextMenuCommand|.
  bool WillContextMenuGroup(int index);

  // Convert a ContextMenuCommand into a browser command. Returns true if a
  // corresponding browser command exists, false otherwise.
  static bool ContextMenuCommandToBrowserCommand(int cmd_id, int* browser_cmd);

  // Returns the index of the next WebContents in the sequence of WebContentses
  // spawned by the specified WebContents after |start_index|.
  int GetIndexOfNextWebContentsOpenedBy(const content::WebContents* opener,
                                        int start_index) const;

  // Finds the next available tab to switch to as the active tab starting at
  // |index|. This method will check the indices to the right of |index| before
  // checking the indices to the left of |index|. |index| cannot be returned.
  // |collapsing_group| is optional and used in cases where the group is
  // collapsing but not yet reflected in the model. Returns absl::nullopt if
  // there are no valid tabs.
  absl::optional<int> GetNextExpandedActiveTab(
      int index,
      absl::optional<tab_groups::TabGroupId> collapsing_group) const;

  // Forget all opener relationships, to reduce unpredictable tab switching
  // behavior in complex session states.
  void ForgetAllOpeners();

  // Forgets the opener relationship of the specified WebContents.
  void ForgetOpener(content::WebContents* contents);

  // Determine where to place a newly opened tab by using the supplied
  // transition and foreground flag to figure out how it was opened.
  int DetermineInsertionIndex(ui::PageTransition transition, bool foreground);

  // Serialise this object into a trace.
  void WriteIntoTrace(perfetto::TracedValue context) const;

 private:
  FRIEND_TEST_ALL_PREFIXES(TabStripModelTest, GetIndicesClosedByCommand);

  class WebContentsData;
  struct DetachNotifications;

  // Perform tasks associated with changes to the model. Change the Active Index
  // and notify observers.
  void OnChange(const TabStripModelChange& change,
                const TabStripSelectionChange& selection);

  // Detaches the WebContents at the specified |index| from this strip. |reason|
  // is used to indicate to observers what is going to happen to the WebContents
  // (i.e. deleted or reinserted into another tab strip). Returns the detached
  // WebContents.
  std::unique_ptr<TabStripModel::DetachedWebContents>
  DetachWebContentsWithReasonAt(int index,
                                TabStripModelChange::RemoveReason reason);

  // Performs all the work to detach a WebContents instance but avoids sending
  // most notifications. TabClosingAt() and TabDetachedAt() are sent because
  // observers are reliant on the selection model being accurate at the time
  // that TabDetachedAt() is called.
  std::unique_ptr<DetachedWebContents> DetachWebContentsImpl(
      int index_before_any_removals,
      int index_at_time_of_removal,
      bool create_historical_tab,
      TabStripModelChange::RemoveReason reason);

  // We batch send notifications. This has two benefits:
  //   1) This allows us to send the minimal number of necessary notifications.
  //   This is important because some notifications cause the main thread to
  //   synchronously communicate with the GPU process and cause jank.
  //   https://crbug.com/826287.
  //   2) This allows us to avoid some problems caused by re-entrancy [e.g.
  //   using destroyed WebContents instances]. Ideally, this second check
  //   wouldn't be necessary because we would enforce that there is no
  //   re-entrancy in the TabStripModel, but that condition is currently
  //   violated in tests [and possibly in the wild as well].
  void SendDetachWebContentsNotifications(DetachNotifications* notifications);

  bool RunUnloadListenerBeforeClosing(content::WebContents* contents);
  bool ShouldRunUnloadListenerBeforeClosing(content::WebContents* contents);

  int ConstrainInsertionIndex(int index, bool pinned_tab) const;

  int ConstrainMoveIndex(int index, bool pinned_tab) const;

  // If |index| is selected all the selected indices are returned, otherwise a
  // vector with |index| is returned. This is used when executing commands to
  // determine which indices the command applies to. Indices are sorted in
  // increasing order.
  std::vector<int> GetIndicesForCommand(int index) const;

  // Returns a vector of indices of the tabs that will close when executing the
  // command |id| for the tab at |index|. The returned indices are sorted in
  // descending order.
  std::vector<int> GetIndicesClosedByCommand(int index,
                                             ContextMenuCommand id) const;

  // Returns true if the specified WebContents is a New Tab at the end of
  // the tabstrip. We check for this because opener relationships are _not_
  // forgotten for the New Tab page opened as a result of a New Tab gesture
  // (e.g. Ctrl+T, etc) since the user may open a tab transiently to look up
  // something related to their current activity.
  bool IsNewTabAtEndOfTabStrip(content::WebContents* contents) const;

  // Adds the specified WebContents at the specified location.
  // |add_types| is a bitmask of AddTabTypes; see it for details.
  //
  // All append/insert methods end up in this method.
  //
  // NOTE: adding a tab using this method does NOT query the order controller,
  // as such the ADD_FORCE_INDEX AddTabTypes is meaningless here. The only time
  // the |index| is changed is if using the index would result in breaking the
  // constraint that all pinned tabs occur before non-pinned tabs. It returns
  // the index the web contents is actually inserted to. See also
  // AddWebContents.
  int InsertWebContentsAtImpl(int index,
                              std::unique_ptr<content::WebContents> contents,
                              int add_types,
                              absl::optional<tab_groups::TabGroupId> group);

  // Closes the WebContentses at the specified indices. This causes the
  // WebContentses to be destroyed, but it may not happen immediately. If
  // the page in question has an unload event the WebContents will not be
  // destroyed until after the event has completed, which will then call back
  // into this method.
  //
  // Returns true if the WebContentses were closed immediately, false if we
  // are waiting for the result of an onunload handler.
  bool CloseTabs(base::span<content::WebContents* const> items,
                 uint32_t close_types);

  // |close_types| is a bitmask of the types in CloseTypes.
  // Returns true if all the tabs have been deleted. A return value of false
  // means some portion (potentially none) of the WebContents were deleted.
  // WebContents not deleted by this function are processing unload handlers
  // which may eventually be deleted based on the results of the unload handler.
  // Additionally processing the unload handlers may result in needing to show
  // UI for the WebContents. See UnloadController for details on how unload
  // handlers are processed.
  bool CloseWebContentses(base::span<content::WebContents* const> items,
                          uint32_t close_types,
                          DetachNotifications* notifications);

  // Gets the WebContents at an index. Does no bounds checking.
  content::WebContents* GetWebContentsAtImpl(int index) const;

  // Returns the WebContentses at the specified indices. This does no checking
  // of the indices, it is assumed they are valid.
  std::vector<content::WebContents*> GetWebContentsesByIndices(
      const std::vector<int>& indices);

  // Sets the selection to |new_model| and notifies any observers.
  // Note: This function might end up sending 0 to 3 notifications in the
  // following order: TabDeactivated, ActiveTabChanged, TabSelectionChanged.
  // |selection| will be filled with information corresponding to 3 notification
  // above. When it's |triggered_by_other_operation|, This won't notify
  // observers that selection was changed. Callers should notify it by
  // themselves.
  TabStripSelectionChange SetSelection(
      ui::ListSelectionModel new_model,
      TabStripModelObserver::ChangeReason reason,
      bool triggered_by_other_operation);

  // direction of relative tab movements or selections. kNext indicates moving
  // forward (positive increment) in the tab strip. kPrevious indicates
  // backward (negative increment).
  enum class TabRelativeDirection {
    kNext,
    kPrevious,
  };

  // Selects either the next tab (kNext), or the previous tab (kPrevious).
  void SelectRelativeTab(TabRelativeDirection direction,
                         TabStripUserGestureDetails detail);

  // Moves the active tabs into the next slot (kNext), or the
  // previous slot (kPrevious). Respects group boundaries and creates
  // movement slots into and out of groups.
  void MoveTabRelative(TabRelativeDirection direction);

  // Does the work of MoveWebContentsAt. This has no checks to make sure the
  // position is valid, those are done in MoveWebContentsAt.
  void MoveWebContentsAtImpl(int index,
                             int to_position,
                             bool select_after_move);

  // Implementation of MoveSelectedTabsTo. Moves |length| of the selected tabs
  // starting at |start| to |index|. See MoveSelectedTabsTo for more details.
  void MoveSelectedTabsToImpl(int index, size_t start, size_t length);

  // Adds tabs to newly-allocated group id |new_group|. This group must be new
  // and have no tabs in it.
  void AddToNewGroupImpl(const std::vector<int>& indices,
                         const tab_groups::TabGroupId& new_group);

  // Adds tabs to existing group |group|. This group must have been initialized
  // by a previous call to |AddToNewGroupImpl()|.
  void AddToExistingGroupImpl(const std::vector<int>& indices,
                              const tab_groups::TabGroupId& group);

  // Implementation of MoveTabsAndSetGroupImpl. Moves the set of tabs in
  // |indices| to the |destination_index| and updates the tabs to the
  // appropriate |group|.
  void MoveTabsAndSetGroupImpl(const std::vector<int>& indices,
                               int destination_index,
                               absl::optional<tab_groups::TabGroupId> group);

  // Moves the tab at |index| to |new_index| and sets its group to |new_group|.
  // Notifies any observers that group affiliation has changed for the tab.
  void MoveAndSetGroup(int index,
                       int new_index,
                       absl::optional<tab_groups::TabGroupId> new_group);

  void AddToReadLaterImpl(const std::vector<int>& indices);

  // Helper function for MoveAndSetGroup. Removes the tab at |index| from the
  // group that contains it, if any. Also deletes that group, if it now contains
  // no tabs. Returns that group.
  absl::optional<tab_groups::TabGroupId> UngroupTab(int index);

  // Helper function for MoveAndSetGroup. Adds the tab at |index| to |group|,
  // updates the group model, and notifies the observers if the group at that
  // index would change.
  void GroupTab(int index, const tab_groups::TabGroupId& group);

  // Changes the pinned state of the tab at |index|.
  void SetTabPinnedImpl(int index, bool pinned);

  // Ensures all tabs indicated by |indices| are pinned, moving them in the
  // process if necessary. Returns the new locations of all of those tabs.
  std::vector<int> SetTabsPinned(const std::vector<int>& indices, bool pinned);

  // Sets the sound content setting for each site at the |indices|.
  void SetSitesMuted(const std::vector<int>& indices, bool mute) const;

  // Sets the opener of any tabs that reference the tab at |index| to that tab's
  // opener or null if there's a cycle.
  void FixOpeners(int index);

  // Makes sure the tab at |index| is not causing a group contiguity error. Will
  // make the minimum change to ensure that the tab's group is not non-
  // contiguous as well as ensuring that it is not breaking up a non-contiguous
  // group, possibly by setting or clearing its group.
  void EnsureGroupContiguity(int index);

  // Returns a valid index to be selected after the tab at |removing_index| is
  // closed. If |index| is after |removing_index|, |index| is adjusted to
  // reflect the fact that |removing_index| is going away.
  int GetTabIndexAfterClosing(int index, int removing_index) const;

  // Takes the |selection| change and decides whether to forget the openers.
  void OnActiveTabChanged(const TabStripSelectionChange& selection);

  // Determine where to shift selection after a tab is closed.
  absl::optional<int> DetermineNewSelectedIndex(int removed_index) const;

  // The WebContents data currently hosted within this TabStripModel. This must
  // be kept in sync with |selection_model_|.
  std::vector<std::unique_ptr<WebContentsData>> contents_data_;

  // The model for tab groups hosted within this TabStripModel.
  std::unique_ptr<TabGroupModel> group_model_;

  raw_ptr<TabStripModelDelegate> delegate_;

  bool tab_strip_ui_was_set_ = false;

  base::ObserverList<TabStripModelObserver>::Unchecked observers_;

  // A profile associated with this TabStripModel.
  raw_ptr<Profile> profile_;

  // True if all tabs are currently being closed via CloseAllTabs.
  bool closing_all_ = false;

  // This must be kept in sync with |contents_data_|.
  ui::ListSelectionModel selection_model_;

  // TabStripModel is not re-entrancy safe. This member is used to guard public
  // methods that mutate state of |selection_model_| or |contents_data_|.
  bool reentrancy_guard_ = false;

  // A recorder for recording tab switching input latency to UMA
  TabSwitchEventLatencyRecorder tab_switch_event_latency_recorder_;

  // Timer used to mark intervals for metric collection on how many tabs are
  // scrubbed over a certain interval of time.
  base::RepeatingTimer tab_scrubbing_interval_timer_;
  // Timestamp marking the last time a tab was activated by mouse press. This is
  // used in determining how long a tab was active for metrics.
  base::TimeTicks last_tab_switch_timestamp_ = base::TimeTicks();
  // Counter used to keep track of tab scrubs during intervals set by
  // |tab_scrubbing_interval_timer_|.
  size_t tabs_scrubbed_by_mouse_press_count_ = 0;
  // Counter used to keep track of tab scrubs during intervals set by
  // |tab_scrubbing_interval_timer_|.
  size_t tabs_scrubbed_by_key_press_count_ = 0;

  base::WeakPtrFactory<TabStripModel> weak_factory_{this};
};

// Forbid construction of ScopedObservation and ScopedMultiSourceObservation
// with TabStripModel: TabStripModelObserver already implements their
// functionality natively.
namespace base {

template <>
class ScopedObservation<TabStripModel, TabStripModelObserver> {
 public:
  // Deleting the constructor gives a clear error message traceable back to here.
  explicit ScopedObservation(TabStripModelObserver* observer) = delete;
};

template <>
class ScopedMultiSourceObservation<TabStripModel, TabStripModelObserver> {
 public:
  // Deleting the constructor gives a clear error message traceable back to
  // here.
  explicit ScopedMultiSourceObservation(TabStripModelObserver* observer) =
      delete;
};

}  // namespace base

#endif  // CHROME_BROWSER_UI_TABS_TAB_STRIP_MODEL_H_
