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

#import "chrome/browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller.h"

#include "base/i18n/break_iterator.h"
#include "base/strings/sys_string_conversions.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
#import "ui/base/cocoa/touch_bar_util.h"
#include "ui/gfx/range/range.h"

namespace {
// Touch bar identifier.
NSString* const kTextSuggestionsTouchBarId = @"text-suggestions";

// Touch bar item identifiers.
NSString* const kTextSuggestionsItemsTouchId = @"TEXT-SUGGESTIONS-ITEMS";
}  // namespace

namespace text_observer {
class WebContentsTextObserver : public content::WebContentsObserver {
 public:
  WebContentsTextObserver(content::WebContents* web_contents,
                          TextSuggestionsTouchBarController* owner)
      : WebContentsObserver(web_contents), owner_(owner) {}

  void UpdateWebContents(content::WebContents* web_contents) {
    Observe(web_contents);
  }

  void DidChangeTextSelection(const base::string16& text,
                              const gfx::Range& range,
                              size_t offset) override {
    [owner_ updateTextSelection:text range:range offset:offset];
  }

  void DidFinishLoad(content::RenderFrameHost* render_frame_host,
                     const GURL& validated_url) override {
    [owner_ updateTextSelection:base::string16() range:gfx::Range() offset:0];
  }

 private:
  TextSuggestionsTouchBarController* owner_;  // weak
};
}  // namespace text_observer

@interface TextSuggestionsTouchBarController () {
  // An observer for text selection changes.
  std::unique_ptr<text_observer::WebContentsTextObserver> observer_;

  // The WebContents in which text is being selected and replaced.
  content::WebContents* webContents_;  // weak

  // The WebTextfieldTouchBarController that invalidates the touch bar.
  WebTextfieldTouchBarController* controller_;  // weak

  // The text on which suggestions are based.
  base::scoped_nsobject<NSString> text_;

  // A list of NSTextCheckingResults containing text suggestions for |text_| at
  // |selectionRange_|.
  base::scoped_nsobject<NSArray> suggestions_;

  // The currently selected range. If the range has length = 0, it is simply a
  // cursor position.
  NSRange selectionRange_;

  // The range of the word that's currently being edited. Used when replacing
  // the current editing word with a selected suggestion. If length = 0, there
  // is no word currently being edited and the suggestion will be placed at the
  // cursor.
  NSRange editingWordRange_;

  // The location of |editingWordRange_| within the total text, which may be
  // longer than the text received on text selection update. Used for checking
  // when to ignore replacement text selections.
  NSRange offsetEditingWordRange_;

  // When YES, -updateTextSelection:range: should ignore a text selection that
  // is equal to the editing word range. Set to YES when
  // -replaceEditingWordWithSuggestion: modifies the current text selection.
  // Reset to NO when the text selection for replacing the editing word reaches
  // -updateTextSelection:range:.
  BOOL shouldIgnoreReplacementSelection_;
}
@end

@implementation TextSuggestionsTouchBarController

- (BOOL)isTextfieldFocused {
  return webContents_ && webContents_->IsFocusedElementEditable();
}

- (instancetype)initWithWebContents:(content::WebContents*)webContents
                         controller:
                             (WebTextfieldTouchBarController*)controller {
  if ((self = [super init])) {
    webContents_ = webContents;
    controller_ = controller;
    observer_.reset(
        new text_observer::WebContentsTextObserver(webContents_, self));
    shouldIgnoreReplacementSelection_ = NO;
  }

  return self;
}

- (NSTouchBar*)makeTouchBar {
  if (![self isTextfieldFocused] || ![suggestions_ count])
    return nil;

  base::scoped_nsobject<NSTouchBar> touchBar([[ui::NSTouchBar() alloc] init]);
  [touchBar
      setCustomizationIdentifier:ui::GetTouchBarId(kTextSuggestionsTouchBarId)];
  [touchBar setDelegate:self];

  [touchBar setDefaultItemIdentifiers:@[ kTextSuggestionsItemsTouchId ]];
  return touchBar.autorelease();
}

- (NSTouchBarItem*)touchBar:(NSTouchBar*)touchBar
      makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
  if (![identifier hasSuffix:kTextSuggestionsItemsTouchId])
    return nil;

  return [self createCandidateListItem];
}

- (NSCandidateListTouchBarItem*)createCandidateListItem {
  NSCandidateListTouchBarItem* candidateListItem =
      [[NSCandidateListTouchBarItem alloc]
          initWithIdentifier:kTextSuggestionsItemsTouchId];

  candidateListItem.delegate = self;
  if (selectionRange_.length)
    candidateListItem.collapsed = YES;

  [candidateListItem setCandidates:suggestions_
                  forSelectedRange:selectionRange_
                          inString:text_];

  return candidateListItem;
}

- (void)candidateListTouchBarItem:(NSCandidateListTouchBarItem*)anItem
     endSelectingCandidateAtIndex:(NSInteger)index {
  if (index == NSNotFound)
    return;

  if (anItem) {
    NSTextCheckingResult* selectedResult = anItem.candidates[index];
    [self replaceEditingWordWithSuggestion:[selectedResult replacementString]];
  }

  ui::LogTouchBarUMA(ui::TouchBarAction::TEXT_SUGGESTION);
}

- (void)updateTextSelection:(const base::string16&)text
                      range:(const gfx::Range&)range
                     offset:(size_t)offset {
  if (@available(macOS 10.12.2, *)) {
    if (shouldIgnoreReplacementSelection_ &&
        range == gfx::Range(offsetEditingWordRange_)) {
      shouldIgnoreReplacementSelection_ = NO;
      return;
    }

    if (![self isTextfieldFocused]) {
      [controller_ invalidateTouchBar];
      return;
    }

    text_.reset([base::SysUTF16ToNSString(text) retain]);
    selectionRange_ =
        NSMakeRange(range.start() - offset, range.end() - range.start());
    editingWordRange_ =
        [self editingWordRangeFromText:text
                        cursorPosition:selectionRange_.location];
    offsetEditingWordRange_ = NSMakeRange(editingWordRange_.location + offset,
                                          editingWordRange_.length);
    [self requestSuggestions];
  }
}

- (NSRange)editingWordRangeFromText:(const base::string16&)text
                     cursorPosition:(size_t)cursor {
  // The cursor should not be off the end of the text.
  DCHECK(cursor <= text.length());

  // Default range is just the cursor position. This is used if BreakIterator
  // cannot be initialized, there is no text in the textfield, or the cursor is
  // at the front of a word.
  size_t location = cursor;
  size_t length = 0;

  base::i18n::BreakIterator iter(text, base::i18n::BreakIterator::BREAK_WORD);

  if (iter.Init()) {
    // Repeat iter.Advance() until end of line is reached or
    // current iterator position passes cursor position.
    while (iter.pos() < cursor && iter.Advance()) {
    }

    // If BreakIterator stopped at the end of a word, the cursor is in/at the
    // end of a word so the editing word range is [word start, word end].
    if (iter.IsWord()) {
      location = iter.prev();
      length = iter.pos() - iter.prev();
    }

    // The suggestion text returned by AppKit has the necessary trailing
    // whitespace which should replace the existing trailing whitespace.
    // If the BreakIterator just iterated over whitespace or iterates over
    // whitespace when it advances, modify the length of the editing word
    // range to include the whitespace.
    if ((iter.pos() && !iter.IsWord()) || (iter.Advance() && !iter.IsWord()))
      length = iter.pos() - location;
  }

  return NSMakeRange(location, length);
}

- (void)requestSuggestions {
  NSSpellChecker* spell_checker = [NSSpellChecker sharedSpellChecker];
  [spell_checker
      requestCandidatesForSelectedRange:selectionRange_
                               inString:text_
                                  types:NSTextCheckingAllSystemTypes
                                options:nil
                 inSpellDocumentWithTag:0
                      completionHandler:^(
                          NSInteger sequenceNumber,
                          NSArray<NSTextCheckingResult*>* candidates) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                          suggestions_.reset([candidates copy]);
                          [controller_ invalidateTouchBar];
                        });

                      }];
}

- (void)replaceEditingWordWithSuggestion:(NSString*)text {
  // If the editing word is not selected in its entirety, modify the selection
  // to cover the current editing word.
  if (!NSEqualRanges(editingWordRange_, selectionRange_)) {
    shouldIgnoreReplacementSelection_ = YES;
    int start_adjust = editingWordRange_.location - selectionRange_.location;
    int end_adjust = (editingWordRange_.location + editingWordRange_.length) -
                     (selectionRange_.location + selectionRange_.length);
    webContents_->AdjustSelectionByCharacterOffset(start_adjust, end_adjust,
                                                   false);
  }
  webContents_->Replace(base::SysNSStringToUTF16(text));
}

- (void)setWebContents:(content::WebContents*)webContents {
  webContents_ = webContents;
  observer_->UpdateWebContents(webContents);

  if (![self isTextfieldFocused]) {
    [controller_ invalidateTouchBar];
    return;
  }

  const base::string16 text =
      webContents_->GetTopLevelRenderWidgetHostView()->GetSurroundingText();
  const gfx::Range range =
      webContents_->GetTopLevelRenderWidgetHostView()->GetSelectedRange();
  const size_t offset = webContents_->GetTopLevelRenderWidgetHostView()
                            ->GetOffsetForSurroundingText();
  if (range.IsValid())
    [self updateTextSelection:text range:range offset:offset];
  else
    [self updateTextSelection:base::string16() range:gfx::Range() offset:0];
}

- (content::WebContents*)webContents {
  return webContents_;
}

- (void)setText:(NSString*)text {
  text_.reset([text copy]);
}

- (NSString*)text {
  return text_;
}

- (void)setSelectionRange:(const gfx::Range&)range {
  selectionRange_ = range.ToNSRange();
}

- (gfx::Range)selectionRange {
  return gfx::Range(selectionRange_);
}

- (void)setSuggestions:(NSArray*)suggestions {
  suggestions_.reset([suggestions copy]);
}

- (NSArray*)suggestions {
  return suggestions_;
}

- (WebTextfieldTouchBarController*)controller {
  return controller_;
}

- (void)setShouldIgnoreReplacementSelection:(BOOL)shouldIgnore {
  shouldIgnoreReplacementSelection_ = shouldIgnore;
}

- (void)setEditingWordRange:(const gfx::Range&)range offset:(size_t)offset {
  editingWordRange_ = range.ToNSRange();
  offsetEditingWordRange_ = NSMakeRange(editingWordRange_.location + offset,
                                        editingWordRange_.length);
}

@end
