// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_
#define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_

#include <stddef.h>

#include <map>
#include <memory>
#include <string>
#include <string_view>

#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list_types.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/ui/omnibox/omnibox_view.h"
#include "components/omnibox/browser/autocomplete_controller.h"
#include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/autocomplete_match.h"
#include "components/omnibox/browser/omnibox.mojom-shared.h"
#include "components/omnibox/browser/omnibox_popup_selection.h"
#include "components/omnibox/common/omnibox_focus_state.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/native_ui_types.h"
#include "url/gurl.h"

class OmniboxController;
class OmniboxPopupView;
namespace gfx {
class Image;
}

class OmniboxEditModel {
 public:
  struct State {
    State(bool user_input_in_progress,
          const std::u16string& user_text,
          const std::u16string& keyword,
          const std::u16string& keyword_placeholder,
          bool is_keyword_hint,
          metrics::OmniboxEventProto::KeywordModeEntryMethod
              keyword_mode_entry_method,
          OmniboxFocusState focus_state,
          const AutocompleteInput& autocomplete_input);
    State(const State& other);
    ~State();
    State& operator=(const State&) = delete;

    bool user_input_in_progress;
    const std::u16string user_text;
    const std::u16string keyword;
    const std::u16string keyword_placeholder;
    const bool is_keyword_hint;
    metrics::OmniboxEventProto::KeywordModeEntryMethod
        keyword_mode_entry_method;
    OmniboxFocusState focus_state;
    const AutocompleteInput autocomplete_input;
  };

  // Intended for view code to update itself when the model changes. Most view
  // updates are propagated by calling methods on `view_` & `popup_view_`
  // directly. But it's possible to have multiple views interested in being
  // updates (e.g. when the side-by-side debugging feature
  // `kWebUIOmniboxPopupDebug` is enabled). So updates that multiple views might
  // be interested in use the observer pattern. In the future, perhaps all
  // model->view updates can go through the observer.
  class Observer : public base::CheckedObserver {
   public:
    // Invoked when the selection changes. The `line` field in either selection
    // may be `OmniboxPopupSelection::kNoMatch`.
    virtual void OnSelectionChanged(OmniboxPopupSelection old_selection,
                                    OmniboxPopupSelection new_selection) = 0;

    // Invoked when the icon used for the given match has been updated.
    virtual void OnMatchIconUpdated(size_t index) = 0;

    ~Observer() override = default;
  };

  OmniboxEditModel(OmniboxController* controller, OmniboxView* view);
  virtual ~OmniboxEditModel();
  OmniboxEditModel(const OmniboxEditModel&) = delete;
  OmniboxEditModel& operator=(const OmniboxEditModel&) = delete;

  void set_popup_view(OmniboxPopupView* popup_view);
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  metrics::OmniboxEventProto::PageClassification GetPageClassification() const;

  // Returns the current state.  This assumes we are switching tabs, and changes
  // the internal state appropriately.
  State GetStateForTabSwitch() const;

  // Resets the tab state, then restores local state from |state|. |state| may
  // be nullptr if there is no saved state.
  void RestoreState(const State* state);

  // Returns the match for the current text. If the user has not edited the text
  // this is the match corresponding to the permanent text. Returns the
  // alternate nav URL, if |alternate_nav_url| is non-NULL and there is such a
  // URL. Virtual for testing.
  virtual AutocompleteMatch CurrentMatch(GURL* alternate_nav_url) const;

  // Called when the user wants to export the entire current text as a URL.
  // Sets the url, and if known, the title and favicon.
  void GetDataForURLExport(GURL* url,
                           std::u16string* title,
                           gfx::Image* favicon);

  // Returns true if the current edit contents will be treated as a
  // URL/navigation, as opposed to a search.
  bool CurrentTextIsURL() const;

  // Adjusts the copied text before writing it to the clipboard. If the copied
  // text is a URL with the scheme elided, this method reattaches the scheme.
  // Copied text that looks like a search query will not be modified.
  //
  // |sel_min| gives the minimum of the selection, e.g. min(sel_start, sel_end).
  // |text| is the currently selected text, and may be modified by this method.
  // |url_from_text| is the GURL interpretation of the selected text, and may
  // be used for drag-and-drop models or writing hyperlink data types to
  // system clipboards.
  //
  // If the copied text is interpreted as a URL:
  //  - |write_url| is set to true.
  //  - |url_from_text| is set to the URL.
  //  - |text| is set to the URL's spec. The output will be pure ASCII and
  //    %-escaped, since canonical URLs are always encoded to ASCII.
  //
  // If the copied text is *NOT* interpreted as a URL:
  //  - |write_url| is set to false.
  //  - |url_from_text| may be modified, but might not contain a valid GURL.
  //  - |text| is full UTF-16 and not %-escaped. This is because we are not
  //    interpreting |text| as a URL, so we leave the Unicode characters as-is.
  void AdjustTextForCopy(int sel_min,
                         std::u16string* text,
                         GURL* url_from_text,
                         bool* write_url);

  bool user_input_in_progress() const { return user_input_in_progress_; }

  std::u16string user_text() const { return user_text_; }

  // Encapsulates all the varied conditions for whether to override the
  // permanent page icon (associated with the currently displayed page),
  // with a temporary icon (associated with the current match or user text).
  bool ShouldShowCurrentPageIcon() const;

  // Returns the SuperGIcon for chrome builds. Otherwise return an empty
  // ImageModel. If `dark_mode` is enabled, return the monochrome version of the
  // icon.
  ui::ImageModel GetSuperGIcon(int image_size, bool dark_mode) const;

  // Returns the Agentspace icon for chrome builds. Otherwise return an empty
  // Image. If `dark_mode` is enabled, return the monochrome version of the
  // icon.
  gfx::Image GetAgentspaceIcon(bool dark_mode) const;

  // Sets the state of user_input_in_progress_, and notifies the observer if
  // that state has changed.
  void SetInputInProgress(bool in_progress);

  // Calls SetInputInProgress, via SetInputInProgressNoNotify and
  // NotifyObserversInputInProgress, calling the latter after
  // StartAutocomplete, so that the result is only updated once.
  void UpdateInput(bool has_selected_text, bool prevent_inline_autocomplete);

  // Resets the permanent display texts (display_text_ and url_for_editing_)
  // to those provided by the controller. Returns true if the display texts
  // have changed and the change should be immediately user-visible, because
  // either the user is not editing or the edit does not have focus.
  bool ResetDisplayTexts();

  // Returns the permanent display text for the current page and Omnibox state.
  std::u16string GetPermanentDisplayText() const;

  // Sets the user_text_ to |text|. Also enters user-input-in-progress mode.
  // Virtual for testing.
  virtual void SetUserText(const std::u16string& text);

  // If the omnibox is currently displaying elided text, this method will
  // restore the full URL into the user text. After unelision, this selects-all,
  // enters user-input-in-progress mode, and then returns true.
  //
  // If the omnibox is not currently displaying elided text, this method will
  // no-op and return false.
  bool Unelide();

  // Invoked any time the text may have changed in the edit. Notifies the
  // controller.
  void OnChanged();

  // Reverts the edit model back to its unedited state (permanent text showing,
  // no user input in progress).
  void Revert();

  // Directs the popup to start autocomplete.  Makes use of the |view_| text and
  // selection, so make sure to set those before calling StartAutocomplete().
  void StartAutocomplete(bool has_selected_text,
                         bool prevent_inline_autocomplete);

  // Determines whether the user can "paste and go", given the specified text.
  bool CanPasteAndGo(const std::u16string& text) const;

  // Navigates to the destination last supplied to CanPasteAndGo.
  void PasteAndGo(
      const std::u16string& text,
      base::TimeTicks match_selection_timestamp = base::TimeTicks());

  // Sets |match| and |alternate_nav_url| based on classifying |text|.
  // |alternate_nav_url| may be nullptr.
  void ClassifyString(const std::u16string& text,
                      AutocompleteMatch* match,
                      GURL* alternate_nav_url) const;

  // Navigates to AI Mode, with the contents of the currently selected match, if
  // any.
  // `via_keyboard` is set to `true` if AI Mode was invoked via keyboard event
  // and is set to `false` if AI Mode was invoked via mouse / gesture event.
  void OpenAiMode(bool via_keyboard);

  // Opens given selection. Most kinds of selection invoke an action or
  // otherwise call `OpenMatch`, but some may `AcceptInput` which is not
  // guaranteed to open a match or commit the omnibox.
  // `via_keyboard` is set to `true` if the selection was opened due to a
  // keyboard event and is set to `false` if the selection was opened due
  // to a mouse / gesture event.
  virtual void OpenSelection(
      OmniboxPopupSelection selection,
      base::TimeTicks timestamp = base::TimeTicks(),
      WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB,
      bool via_keyboard = false);

  // A simplified version of `OpenSelection()` that opens the model's current
  // selection.
  void OpenSelectionForTesting(
      base::TimeTicks timestamp = base::TimeTicks(),
      WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB,
      bool via_keyboard = false);

  OmniboxFocusState focus_state() const { return focus_state_; }
  bool has_focus() const { return focus_state_ != OMNIBOX_FOCUS_NONE; }

  base::TimeTicks last_omnibox_focus() const { return last_omnibox_focus_; }

  // This is the same as when the Omnibox is visibly focused.
  bool is_caret_visible() const {
    return focus_state_ == OMNIBOX_FOCUS_VISIBLE;
  }

  // Accessors for keyword-related state (see comments on `keyword_`,
  // `keyword_placeholder_` and `is_keyword_hint_`).
  const std::u16string& keyword() const { return keyword_; }
  const std::u16string& keyword_placeholder() const {
    return keyword_placeholder_;
  }
  bool is_keyword_hint() const { return is_keyword_hint_; }
  bool is_keyword_selected() const {
    return !is_keyword_hint_ && !keyword_.empty();
  }

  // Accepts the current keyword hint as a keyword. It always returns true for
  // caller convenience. |entry_method| indicates how the user entered
  // keyword mode.
  bool AcceptKeyword(
      metrics::OmniboxEventProto::KeywordModeEntryMethod entry_method);

  // Sets the current keyword to that of the given `template_url` and updates
  // the view so the user sees the keyword chip in the omnibox.  Adjusts
  // user_text_ and the selection based on the display text and the keyword
  // entry method. Note, the default match may be updated in this process
  // so the match must support this keyword mode or it will be exited.
  void EnterKeywordMode(
      metrics::OmniboxEventProto::KeywordModeEntryMethod entry_method,
      const TemplateURL* template_url,
      const std::u16string& placeholder_text);

  // Enters keyword mode for user's default search provider, if enabled.
  void EnterKeywordModeForDefaultSearchProvider(
      metrics::OmniboxEventProto::KeywordModeEntryMethod entry_method);

  // Accepts the current temporary text as the user text.
  void AcceptTemporaryTextAsUserText();

  // Clears the current keyword.
  void ClearKeyword();

  // Clears additional text.
  void ClearAdditionalText();

  // Called when the view is gaining focus.  |control_down| is whether the
  // control key is down (at the time we're gaining focus).
  void OnSetFocus(bool control_down);

  // Starts a request for zero-prefix suggestions if no query is currently
  // running and the popup is closed. This can be called multiple times without
  // harm, since it will early-exit if an earlier request is in progress or
  // done.
  void StartZeroSuggestRequest(bool user_clobbered_permanent_text = false);

  // Sets the visibility of the caret in the omnibox, if it has focus. The
  // visibility of the caret is reset to visible if either
  //   - The user starts typing, or
  //   - We explicitly focus the omnibox again.
  // The latter case must be handled in three separate places--OnSetFocus(),
  // OmniboxView::SetFocus(), and the mouse handlers in OmniboxView. See
  // accompanying comments for why each of these is necessary.
  //
  // Caret visibility is tracked per-tab and updates automatically upon
  // switching tabs.
  void SetCaretVisibility(bool visible);

  // If the ctrl key is down, marks it as consumed to prevent it from triggering
  // ctrl-enter behavior unless it is released and re-pressed.
  void ConsumeCtrlKey();

  // Sent before |OnKillFocus| and before the popup is closed.
  void OnWillKillFocus();

  // Called when the view is losing focus.  Resets some state.
  void OnKillFocus();

  // Called when the user presses the escape key.  Decides what, if anything, to
  // revert about any current edits.  Returns whether the key was handled.
  bool OnEscapeKeyPressed();

  // Called when the user presses or releases the control key.  Changes state as
  // necessary.
  void OnControlKeyChanged(bool pressed);

  // Called when the user pastes in text.
  void OnPaste();

  // Returns true if pasting is in progress.
  bool is_pasting() const { return paste_state_ == PASTING; }

  // Called when the user presses arrow up, arrow down, page up, or page down.
  void OnUpOrDownPressed(bool down, bool page);

  // Called when the user presses tab or shift+tab. The latter will traverse up
  // the selections instead of down.
  void OnTabPressed(bool shift);

  // Called when the user presses the space key without modifiers.
  // Returns true if the space is handled in a special way, for example
  // entering keyword mode on a match somewhere down the list.
  bool OnSpacePressed();

  // Called when any relevant data changes.  This rolls together several
  // separate pieces of data into one call so we can update all the UI
  // efficiently. Specifically, it's invoked for temporary text, autocompletion,
  // and keyword changes.
  //   `temporary_text` is the new temporary text from the user selecting a
  //     different match. This will be empty when selecting a suggestion
  //     without a `fill_into_edit` (e.g. FOCUSED_BUTTON_HEADER) and when
  //     `is_temporary_test` is false.
  //   `is_temporary_text` is true if invoked because of a temporary text change
  //     or false if `temporary_text` should be ignored.
  //   `inline_autocompletion` is the autocompletion.
  //   `destination_for_temporary_text_change` is NULL (if temporary text should
  //     not change) or the pre-change destination URL (if temporary text should
  //     change) so we can save it off to restore later.
  //   `keyword` is the keyword to show a hint for if `is_keyword_hint` is true,
  //     or the currently selected keyword if `is_keyword_hint` is false (see
  //     comments on keyword_ and is_keyword_hint_).
  //   `additional_text` is additional omnibox text to be displayed adjacent to
  //     the omnibox view.
  //   `new_match` is the selected match when the user is changing selection,
  //     the default match if the user is typing, or an empty match when
  //     selecting a header.
  // Virtual to allow testing.
  virtual void OnPopupDataChanged(const std::u16string& temporary_text,
                                  bool is_temporary_text,
                                  const std::u16string& inline_autocompletion,
                                  const std::u16string& keyword,
                                  const std::u16string& keyword_placeholder,
                                  bool is_keyword_hint,
                                  const std::u16string& additional_text,
                                  const AutocompleteMatch& new_match);

  // Called by the OmniboxView after something changes, with details about what
  // state changes occurred.  Updates internal state, updates the popup if
  // necessary, and returns true if any significant changes occurred.  Note that
  // |text_change.text_differs| may be set even if |text_change.old_text| ==
  // |text_change.new_text|, e.g. if we've just committed an IME composition.
  //
  // If |allow_keyword_ui_change| is false then the change should not affect
  // keyword ui state, even if the text matches a keyword exactly. This value
  // may be false when the user is composing a text with an IME.
  bool OnAfterPossibleChange(const OmniboxView::StateChanges& state_changes,
                             bool allow_keyword_ui_change);

  // Called when the current match has changed in the OmniboxController.
  void OnCurrentMatchChanged();

  AutocompleteInput GetInputForTesting() const { return input_; }

  // Name of the histogram tracking cut or copy omnibox commands.
  static const char kCutOrCopyAllTextHistogram[];

  // Just forwards the call to the OmniboxView referred within.
  void SetAccessibilityLabel(const AutocompleteMatch& match);

  // Reverts the edit box from a temporary text back to the original user text.
  // Also resets the popup to the initial state.
  void RevertTemporaryTextAndPopup();

  // Returns true if the destination URL of the match is bookmarked.
  bool IsStarredMatch(const AutocompleteMatch& match) const;

  // Gets the icon for the given `match`.
  gfx::Image GetMatchIcon(const AutocompleteMatch& match,
                          SkColor vector_icon_color,
                          bool dark_mode = false) const;
  // Gets the icon for the given `match` if the match was provided by an omnibox
  // API extension, otherwise returns empty image.
  gfx::Image GetMatchIconIfExtension(const AutocompleteMatch& match) const;

  // Gets the suggestion group header text associated with the given suggestion
  // group ID.
  // In addition to calling `AutocompleteResult::GetHeaderForSuggestionGroup()`,
  // this function takes into account certain header visibility criteria (e.g.
  // experiment flags) to determine the proper header text, which will then be
  // used by the relevant code to conditionally show suggestion group headers
  // in the Omnibox/Realbox popup.
  std::u16string GetSuggestionGroupHeaderText(
      const std::optional<omnibox::GroupId>& suggestion_group_id) const;

  // Returns true if the popup exists and is open. Virtual for testing.
  virtual bool PopupIsOpen() const;

  // Called when the user hits escape after arrowing around the popup.  This
  // will reset the popup to the initial state.
  void ResetPopupToInitialState();

  // Gets popup's current selection.
  OmniboxPopupSelection GetPopupSelection() const;

  // Sets the current popup selection to |new_selection|. Caller is responsible
  // for making sure |new_selection| is valid. This assumes the popup is open.
  // This will update all state and repaint the necessary parts of the window,
  // as well as updating the textfield with the new temporary text.
  // |reset_to_default| restores the original inline autocompletion.
  // |force_update_ui| updates the UI even if the selection has not changed.
  void SetPopupSelection(OmniboxPopupSelection new_selection,
                         bool reset_to_default = false,
                         bool force_update_ui = false);

  // Returns true if popup selection is on the initial line, which is usually
  // the default match (except in the no-default-match case).
  bool IsPopupSelectionOnInitialLine() const;

  // Returns true if the control represented by |selection.state| is present on
  // the match in |selection.line|. This is the source-of-truth the UI code
  // should query to decide whether or not to draw the control.
  bool IsPopupControlPresentOnMatch(OmniboxPopupSelection selection) const;

  // From popup, tries to erase the suggestion at |line|. This should determine
  // if the item at |line| can be removed from history, and if so, remove it
  // and update the popup.
  void TryDeletingPopupLine(size_t line);

  // Returns the popup's accessibility label for current selection. This is an
  // extended version of AutocompleteMatchType::ToAccessibilityLabel() which
  // also returns narration about the any focused secondary button.
  // Never call this when the current selection is kNoMatch.
  std::u16string GetPopupAccessibilityLabelForCurrentSelection(
      const std::u16string& match_text,
      bool include_positional_info,
      int* label_prefix_length = nullptr);

  std::u16string GetPopupAccessibilityLabelForAimButton();

  // The IPH message that sometimes appears at the bottom of the Omnibox is
  // informational only and cannot be selected/focused. Its a11y label therefore
  // has to be read at the end of the last suggestion.  Returns the label for
  // the IPH row if the current selection is the one right before the IPH row.
  // Otherwise, returns an empty string.
  std::u16string MaybeGetPopupAccessibilityLabelForIPHSuggestion();

  // Invoked any time the result set of the controller changes.
  // TODO(orinj): This method seems like a good candidate for removal; it is
  // preserved here only to prevent possible behavior change while refactoring.
  void OnPopupResultChanged();

  // Lookup the bitmap for |result_index|. Returns nullptr if not found.
  const SkBitmap* GetPopupRichSuggestionBitmap(int result_index) const;

  // Lookup the bitmap for the first `match` in
  // `autocomplete_controller()->result()` that has `keyword` as its
  // `associated_keyword`. Used to fetch bitmap where the `result_index` is
  // unknown.  Returns nullptr if not found.
  const SkBitmap* GetPopupRichSuggestionBitmap(
      const std::u16string& keyword) const;

  // Lookup the bitmap based on the image URL.  Similar to above,
  // but used to fetch bitmap where the `result_index` is unknown and where
  // there are possibly multiple suggestions with the same `keyword` but not the
  // `image_url` being looked up. Returns nullptr if not found.
  const SkBitmap* GetPopupRichSuggestionBitmap(const GURL& image_url) const;

  // Lookup the icon bitmap based on the icon URL. Returns nullptr
  // if not found.
  const SkBitmap* GetIconBitmap(const GURL& icon_url) const;

  // Stores the image in a local data member and schedules a repaint.
  void SetPopupRichSuggestionBitmap(int result_index, const SkBitmap& bitmap);

  // Stores the icon in a local data member and schedules a repaint.
  void SetIconBitmap(const GURL& icon_url, const SkBitmap& bitmap);

  void SetAutocompleteInput(AutocompleteInput input);

  // Called to indicate a navigation may occur based on
  // |navigation_predictor| to the suggestion on |line|.
  void OnNavigationLikely(
      size_t line,
      omnibox::mojom::NavigationPredictor navigation_predictor);

  // This calls `OpenMatch` directly for the few remaining `OmniboxEditModel`
  // test cases that require explicit control over match content. For new
  // tests, and for non-test code, use `OpenSelection`.
  void OpenMatchForTesting(
      AutocompleteMatch match,
      WindowOpenDisposition disposition,
      const GURL& alternate_nav_url,
      const std::u16string& pasted_text,
      size_t index,
      base::TimeTicks match_selection_timestamp = base::TimeTicks());

 protected:
  // Utility method to get current PrefService; protected instead of private
  // because it may be overridden by derived test classes.
  virtual PrefService* GetPrefService();
  virtual const PrefService* GetPrefService() const;

 private:
  friend class OmniboxControllerTest;
  friend class TestOmniboxEditModel;
  FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKey);
  FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKeyOnRequestFocus);
  FRIEND_TEST_ALL_PREFIXES(OmniboxEditModelTest, ConsumeCtrlKeyOnCtrlAction);
  FRIEND_TEST_ALL_PREFIXES(
      OmniboxEditModelPopupTest,
      GetPopupRichSuggestionBitmapForMatchWithoutAssociatedKeyword);
  FRIEND_TEST_ALL_PREFIXES(
      OmniboxEditModelPopupTest,
      GetPopupRichSuggestionBitmapForMatchWithAssociatedKeyword);

  enum PasteState {
    NONE,     // Most recent edit was not a paste.
    PASTING,  // In the middle of doing a paste. We need this intermediate state
              // because `OnPaste()` does the actual detection of paste, but
              // `OnAfterPossibleChange()` has to update the paste state for
              // every edit. If `OnPaste()` set the state directly to PASTED,
              // `OnAfterPossibleChange()` wouldn't know whether that
              // represented the current edit or a past one.
    PASTED,   // Most recent edit was a paste.
  };

  enum ControlKeyState {
    UP,                // The control key is not depressed.
    DOWN,              // The control key is depressed and should trigger the
                       // "ctrl-enter" behavior when the user hits enter.
    DOWN_AND_CONSUMED  // The control key is depressed, but has been consumed
                       // and should not trigger the "ctrl-enter" behavior.
                       // The control key becomes consumed if it has been used
                       // for another action such as focusing the location bar
                       // with ctrl-l or copying the selected text with ctrl-c.
  };

  AutocompleteController* autocomplete_controller() const;

  // If no query is in progress, starts working on an autocomplete query.
  // Returns true if started; false otherwise.
  bool MaybeStartQueryForPopup();

  // Changes the popup selection to the next available selection. Stepping the
  // popup selection gives special consideration for keyword mode state.
  void StepPopupSelection(OmniboxPopupSelection::Direction direction,
                          OmniboxPopupSelection::Step step);

  // Asks the browser to load the popup's currently selected item, using the
  // supplied disposition.  This may close the popup.
  void AcceptInput(
      WindowOpenDisposition disposition,
      base::TimeTicks match_selection_timestamp = base::TimeTicks());

  // Asks the browser to load |match| or execute one of its actions
  // according to |selection|.
  //
  // OpenMatch() needs to know the original text that drove this action.  If
  // |pasted_text| is non-empty, this is a Paste-And-Go/Search action, and
  // that's the relevant input text.  Otherwise, the relevant input text is
  // either the user text or the display URL, depending on if user input is
  // in progress.
  //
  // |match| is passed by value for two reasons:
  // (1) This function needs to modify |match|, so a const ref isn't
  //     appropriate.  Callers don't actually care about the modifications, so a
  //     pointer isn't required.
  // (2) The passed-in match is, on the caller side, typically coming from data
  //     associated with the popup.  Since this call can close the popup, that
  //     could clear that data, leaving us with a pointer-to-garbage.  So at
  //     some point someone needs to make a copy of the match anyway, to
  //     preserve it past the popup closure.
  void OpenMatch(OmniboxPopupSelection selection,
                 AutocompleteMatch match,
                 WindowOpenDisposition disposition,
                 const GURL& alternate_nav_url,
                 const std::u16string& pasted_text,
                 base::TimeTicks match_selection_timestamp = base::TimeTicks());

  // Updates the feedback type on the match at the given index and schedules a
  // repaint to update the suggestion view. On negative feedback, also shows the
  // feedback form.
  void UpdateFeedbackOnMatch(size_t match_index, FeedbackType feedback_type);

  // An internal method to set the user text. Notably, this differs from
  // SetUserText because it does not change the user-input-in-progress state.
  void InternalSetUserText(const std::u16string& text);

  // Conversion between user text and display text. User text is the text the
  // user has input. Display text is the text being shown in the edit. The
  // two are different if a keyword is selected.
  std::u16string MaybeStripKeyword(const std::u16string& text) const;
  std::u16string MaybePrependKeyword(const std::u16string& text) const;

  // Copies a match corresponding to the current text into |match|, and
  // populates |alternate_nav_url| as well if it's not nullptr. If the popup
  // is closed, the match is generated from the autocomplete classifier.
  void GetInfoForCurrentText(AutocompleteMatch* match,
                             GURL* alternate_nav_url) const;

  // Checks whether keyword mode space-triggering has been disabled either by
  // a pref or relevant feature flags. If the setting isn't available on the
  // search engines page, the pref should be ignored.  Returns true if space
  // triggering is enabled, false otherwise.
  bool AllowKeywordSpaceTriggering() const;

  // Accepts current keyword if the user just typed a space at the end of
  // |new_text|.  This handles both of the following cases:
  //   (assume "foo" is a keyword, | is the input caret, [] is selected text)
  //   foo| -> foo |      (a space was appended to a keyword)
  //   foo[bar] -> foo |  (a space replaced other text after a keyword)
  // Returns true if the current keyword is accepted.
  bool MaybeAcceptKeywordBySpace(const std::u16string& new_text);

  // Checks whether the user inserted a space into |old_text| and by doing so
  // created a |new_text| that looks like "<keyword> <search phrase>".
  bool CreatedKeywordSearchByInsertingSpaceInMiddle(
      const std::u16string& old_text,
      const std::u16string& new_text,
      size_t caret_position) const;

  // Checks if a given character is a valid space character for accepting
  // keyword.
  static bool IsSpaceCharForAcceptingKeyword(wchar_t c);

  // Sets the state of user_input_in_progress_. Returns whether said state
  // changed, so that the caller can evoke NotifyObserversInputInProgress().
  bool SetInputInProgressNoNotify(bool in_progress);

  // Notifies the observers that the state has changed.
  void NotifyObserversInputInProgress(bool in_progress);

  // If focus_state_ does not match |state|, we update it and notify the
  // InstantController about the change (passing along the |reason| for the
  // change). If the caret visibility changes, we call ApplyCaretVisibility() on
  // the view.
  void SetFocusState(OmniboxFocusState state, OmniboxFocusChangeReason reason);

  // This is an event handler that notifies the popup view of match icon
  // changes.
  void OnFaviconFetched(const GURL& page_url, const gfx::Image& icon) const;

  // Returns view text if there is a view. Until the model is made the
  // primary data source, this should not be called when there's no view.
  std::u16string GetText() const;

  // Always use these to set keyword members instead of mutating them directly.
  void SetKeyword(const std::u16string& keyword);
  void SetKeywordPlaceholder(const std::u16string& keyword_placeholder);

  // Record various UMA metrics associated with the AIM page action.
  // `query_text` represents the text entered by the user at activation time.
  // `activated` represents whether or not the user activated the page action.
  // `via_keyboard` represents the page action entry method (i.e. `true` =
  // keyboard event / `false` = mouse/gesture event).
  void RecordAiModeMetrics(const std::u16string& query_text,
                           bool activated,
                           bool via_keyboard);

  // Owns this.
  raw_ptr<OmniboxController> controller_;

  // Owns `OmniboxController` which owns this.
  raw_ptr<OmniboxView> view_;

  OmniboxFocusState focus_state_ = OMNIBOX_FOCUS_NONE;

  // Display-only text representing the current page. This could either:
  //  - The same as |url_for_editing_| if Steady State Elisions is OFF.
  //  - A simplified version of |url_for_editing_| with some destructive
  //    elisions applied. This is the case if Steady State Elisions is ON.
  //
  // This should not be considered suitable for editing.
  std::u16string display_text_;

  // The initial text representing the current URL suitable for editing.
  // This should fully represent the current URL without any meaning-changing
  // elisions applied - and is suitable for user editing.
  std::u16string url_for_editing_;

  // This flag is true when the user has modified the contents of the edit, but
  // not yet accepted them.  We use this to determine when we need to save
  // state (on switching tabs) and whether changes to the page URL should be
  // immediately displayed.
  // This flag *should* be true in a superset of the cases where the popup is
  // open. Except (crbug.com/1340378) for zero suggestions when the popup was
  // opened with ctrl+L or a mouse click (as opposed to the down arrow).
  bool user_input_in_progress_;

  // The text that the user has entered.  This does not include inline
  // autocomplete text that has not yet been accepted.  |user_text_| can
  // contain a string without |user_input_in_progress_| being true.
  // For instance, this is the case when the user has unelided a URL without
  // modifying its contents.
  std::u16string user_text_;

  // Used to know what should be displayed. Updated when e.g. the popup
  // selection changes, the results change, on navigation, on tab switch etc; it
  // should always be up-to-date.
  AutocompleteMatch current_match_;

  // We keep track of when the user last focused on the omnibox.
  base::TimeTicks last_omnibox_focus_;

  // Indicates whether the current interaction with the Omnibox resulted in
  // navigation (true), or user leaving the omnibox without taking any action
  // (false).
  // The value is initialized when the Omnibox receives focus and available for
  // use when the focus is about to be cleared.
  bool focus_resulted_in_navigation_;

  // We keep track of when the user began modifying the omnibox text.
  // This should be valid whenever user_input_in_progress_ is true.
  base::TimeTicks time_user_first_modified_omnibox_;

  // When the user closes the popup, we need to remember the URL for their
  // desired choice, so that if they hit enter without reopening the popup we
  // know where to go.  We could simply rerun autocomplete in this case, but
  // we'd need to either wait for all results to come in (unacceptably slow) or
  // do the wrong thing when the user had chosen some provider whose results
  // were not returned instantaneously.
  //
  // This variable is only valid when user_input_in_progress_ is true, since
  // when it is false the user has either never input anything (so there won't
  // be a value here anyway) or has canceled their input, which should be
  // treated the same way.  Also, since this is for preserving a desired URL
  // after the popup has been closed, we ignore this if the popup is open, and
  // simply ask the popup for the desired URL directly.  As a result, the
  // contents of this variable only need to be updated when the popup is closed
  // but user_input_in_progress_ is not being cleared.
  std::u16string url_for_remembered_user_selection_;

  // Inline autocomplete is allowed if the user has not just deleted text, and
  // no temporary text is showing.  In this case, inline_autocompletion_ is
  // appended to the user_text_ and displayed selected (at least initially).
  //
  // NOTE: When the popup is closed there should never be inline autocomplete
  // text (actions that close the popup should either accept the text, convert
  // it to a normal selection, or change the edit entirely).
  bool just_deleted_text_;
  std::u16string inline_autocompletion_;

  // Used by OnPopupDataChanged to keep track of whether there is currently a
  // temporary text.
  //
  // Example of use: If the user types "goog", then arrows down in the
  // autocomplete popup until, say, "google.com" appears in the edit box, then
  // the user_text_ is still "goog", and "google.com" is "temporary text".
  // When the user hits <esc>, the edit box reverts to "goog".  Hit <esc> again
  // and the popup is closed and "goog" is replaced by the permanent display
  // URL, which is the URL of the current page.
  //
  // original_user_text_with_keyword_ tracks the user_text_ before keywords are
  // removed. When accepting a keyword (from either a default match or another
  // lower in the dropdown), the user_text_ is destructively trimmed of its 1st
  // word. In order to restore the user_text_ properly when the omnibox reverts,
  // e.g. by pressing <escape> or pressing <up> until the first result is
  // selected, we track original_user_text_with_keyword_.
  // original_user_text_with_keyword_ is null if a keyword has not been
  // accepted.
  bool has_temporary_text_;
  std::u16string original_user_text_with_keyword_;

  // When the user's last action was to paste, we disallow inline autocomplete
  // (on the theory that the user is trying to paste in a new URL or part of
  // one, and in either case inline autocomplete would get in the way).
  PasteState paste_state_;

  // Whether the control key is depressed.  We track this to avoid calling
  // UpdatePopup() repeatedly if the user holds down the key, and to know
  // whether to trigger "ctrl-enter" behavior.
  ControlKeyState control_key_state_;

  // The keyword associated with the current match.  The user may have an actual
  // selected keyword, or just some input text that looks like a keyword (so we
  // can show a hint to press <tab>).  This is the keyword in either case;
  // is_keyword_hint_ (below) distinguishes the two cases.
  std::u16string keyword_;

  // The placeholder text displayed for the keyword the user has selected.
  // Usually empty. Only used when the user input is empty.
  std::u16string keyword_placeholder_;

  // True if the keyword associated with this match is merely a hint, i.e. the
  // user hasn't actually selected a keyword yet.  When this is true, we can use
  // keyword_ to show a "Press <tab> to search" sort of hint.
  bool is_keyword_hint_;

  // Indicates how the user entered keyword mode if the user is actually in
  // keyword mode.  Otherwise, the value of this variable is INVALID.  This
  // is used to restore the user's search terms upon a call to ClearKeyword().
  metrics::OmniboxEventProto::KeywordModeEntryMethod keyword_mode_entry_method_;

  // This is needed to properly update the SearchModel state when the user
  // presses escape.
  bool in_revert_;

  // Indicates if the upcoming autocomplete search is allowed to be treated as
  // an exact keyword match.  If this is true then keyword mode will be
  // triggered automatically if the input is "<keyword> <search string>".  We
  // allow this when CreatedKeywordSearchByInsertingSpaceInMiddle() is true.
  // This has no effect if we're already in keyword mode.
  bool allow_exact_keyword_match_;

  // The input that was sent to the AutocompleteController. Since no
  // autocomplete query is started after a tab switch, it is possible for this
  // |input_| to differ from the one currently stored in AutocompleteController.
  AutocompleteInput input_;

  // Rich suggestion bitmaps for popup keyed by `result_index`. These are
  // cleared when `OmniboxPopupViewViews` is initialized and destroyed, and on
  // `OnPopupResultChanged()`.
  std::map<int, SkBitmap> rich_suggestion_bitmaps_;

  // Icon bitmaps for popup keyed by `icon_url`. These are cleared when
  // `OmniboxPopupViewViews` is initialized and destroyed. This differs from
  // `rich_suggestion_bitmaps_` since they are not cleared on
  // `OnPopupResultChanged()`, which allows for fetching the icon even when the
  // popup is closed.
  std::map<GURL, SkBitmap> icon_bitmaps_;

  // The popup view is nullptr when there's no popup, and is non-null when
  // a popup view exists (i.e. between calls to `set_popup_view`).
  raw_ptr<OmniboxPopupView> popup_view_ = nullptr;

  // The current popup selection; set to normal kNoMatch when there's no popup.
  OmniboxPopupSelection popup_selection_ =
      OmniboxPopupSelection(OmniboxPopupSelection::kNoMatch,
                            OmniboxPopupSelection::NORMAL);

  // When a result changes, this informs of the URL in the previously selected
  // suggestion whose tab switch button was focused, so that we may compare
  // if equal.
  GURL old_focused_url_;

  // See comment on `Observer`.
  mutable base::ObserverList<Observer> observers_;

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

#endif  // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_EDIT_MODEL_H_
