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

#include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h"

#include "build/build_config.h"
#include "third_party/blink/renderer/core/editing/ephemeral_range.h"
#include "third_party/blink/renderer/core/editing/frame_selection.h"
#include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
#include "third_party/blink/renderer/core/editing/markers/suggestion_marker_properties.h"
#include "third_party/blink/renderer/core/editing/selection_template.h"
#include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h"
#include "third_party/blink/renderer/core/editing/testing/editing_test_base.h"
#include "third_party/blink/renderer/core/editing/visible_selection.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"

using ui::mojom::ImeTextSpanThickness;
using ui::mojom::ImeTextSpanUnderlineStyle;

namespace blink {

class TextSuggestionControllerTest : public EditingTestBase {
 public:
  bool IsTextSuggestionHostAvailable() {
    return bool(GetDocument()
                    .GetFrame()
                    ->GetTextSuggestionController()
                    .text_suggestion_host_.is_bound());
  }

  void ShowSuggestionMenu(
      const HeapVector<std::pair<Member<const Text>, Member<DocumentMarker>>>&
          node_suggestion_marker_pairs,
      size_t max_number_of_suggestions) {
    GetDocument().GetFrame()->GetTextSuggestionController().ShowSuggestionMenu(
        node_suggestion_marker_pairs, max_number_of_suggestions);
  }

  EphemeralRangeInFlatTree ComputeRangeSurroundingCaret(
      const PositionInFlatTree& caret_position) {
    const Node* const position_node = caret_position.ComputeContainerNode();
    const unsigned position_offset_in_node =
        caret_position.ComputeOffsetInContainerNode();
    // See ComputeRangeSurroundingCaret() in TextSuggestionController.
    return EphemeralRangeInFlatTree(
        PositionInFlatTree(position_node, position_offset_in_node - 1),
        PositionInFlatTree(position_node, position_offset_in_node + 1));
  }
};

TEST_F(TextSuggestionControllerTest, ApplySpellCheckSuggestion) {
  SetBodyContent(
      "<div contenteditable>"
      "spllchck"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 8)), Color::kBlack,
      ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
      Color::kBlack, Color::kBlack);
  // Select immediately before misspelling
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .ApplySpellCheckSuggestion("spellcheck");

  EXPECT_EQ("spellcheck", text->textContent());

  // Cursor should be at end of replaced text
  const VisibleSelectionInFlatTree& selection =
      GetFrame().Selection().ComputeVisibleSelectionInFlatTree();
  EXPECT_EQ(text, selection.Start().ComputeContainerNode());
  EXPECT_EQ(10, selection.Start().ComputeOffsetInContainerNode());
  EXPECT_EQ(text, selection.End().ComputeContainerNode());
  EXPECT_EQ(10, selection.End().ComputeOffsetInContainerNode());
}

// Flaky on Android: http://crbug.com/1104700
#if defined(OS_ANDROID)
#define MAYBE_ApplyTextSuggestion DISABLED_ApplyTextSuggestion
#else
#define MAYBE_ApplyTextSuggestion ApplyTextSuggestion
#endif
TEST_F(TextSuggestionControllerTest, ApplyTextSuggestion) {
  SetBodyContent(
      "<div contenteditable>"
      "word1 word2 word3 word4"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  auto* text = To<Text>(div->firstChild());

  // Add marker on "word1". This marker should *not* be cleared by the
  // replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker1"}))
          .Build());

  // Add marker on "word1 word2 word3 word4". This marker should *not* be
  // cleared by the replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 23)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker2"}))
          .Build());

  // Add marker on "word2 word3". This marker should *not* be cleared by the
  // replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 6), Position(text, 17)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker3"}))
          .Build());

  // Add marker on "word4". This marker should *not* be cleared by the
  // replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 18), Position(text, 23)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker4"}))
          .Build());

  // Add marker on "word1 word2". This marker should be cleared by the
  // replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 11)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker5"}))
          .Build());

  // Add marker on "word3 word4". This marker should be cleared by the
  // replace operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 12), Position(text, 23)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker6"}))
          .Build());

  // Select immediately before word2.
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 6), Position(text, 6))
          .Build());

  // Replace "word2 word3" with "marker3" (marker should have tag 3; tags start
  // from 1, not 0).
  GetDocument().GetFrame()->GetTextSuggestionController().ApplyTextSuggestion(
      3, 0);

  // This returns the markers sorted by start offset; we need them sorted by
  // start *and* end offset, since we have multiple markers starting at 0.
  DocumentMarkerVector markers = GetDocument().Markers().MarkersFor(*text);
  std::sort(markers.begin(), markers.end(),
            [](const DocumentMarker* marker1, const DocumentMarker* marker2) {
              if (marker1->StartOffset() != marker2->StartOffset())
                return marker1->StartOffset() < marker2->StartOffset();
              return marker1->EndOffset() < marker2->EndOffset();
            });

  EXPECT_EQ(4u, markers.size());

  // marker1
  EXPECT_EQ(0u, markers[0]->StartOffset());
  EXPECT_EQ(5u, markers[0]->EndOffset());

  // marker2
  EXPECT_EQ(0u, markers[1]->StartOffset());
  EXPECT_EQ(19u, markers[1]->EndOffset());

  // marker3
  EXPECT_EQ(6u, markers[2]->StartOffset());
  EXPECT_EQ(13u, markers[2]->EndOffset());

  const auto* const suggestion_marker = To<SuggestionMarker>(markers[2].Get());
  EXPECT_EQ(1u, suggestion_marker->Suggestions().size());
  EXPECT_EQ(String("word2 word3"), suggestion_marker->Suggestions()[0]);

  // marker4
  EXPECT_EQ(14u, markers[3]->StartOffset());
  EXPECT_EQ(19u, markers[3]->EndOffset());

  // marker5 and marker6 should've been cleared

  // Cursor should be at end of replaced text
  const VisibleSelectionInFlatTree& selection =
      GetFrame().Selection().ComputeVisibleSelectionInFlatTree();
  EXPECT_EQ(text, selection.Start().ComputeContainerNode());
  EXPECT_EQ(13, selection.Start().ComputeOffsetInContainerNode());
  EXPECT_EQ(text, selection.End().ComputeContainerNode());
  EXPECT_EQ(13, selection.End().ComputeOffsetInContainerNode());
}

TEST_F(TextSuggestionControllerTest,
       ApplyingMisspellingTextSuggestionClearsMarker) {
  SetBodyContent(
      "<div contenteditable>"
      "mispelled"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  auto* text = To<Text>(div->firstChild());

  // Add marker on "mispelled". This marker should be cleared by the replace
  // operation.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 9)),
      SuggestionMarkerProperties::Builder()
          .SetType(SuggestionMarker::SuggestionType::kMisspelling)
          .SetSuggestions(Vector<String>({"misspelled"}))
          .Build());

  // Check the tag for the marker that was just added (the current tag value is
  // not reset between test cases).
  int32_t marker_tag =
      To<SuggestionMarker>(GetDocument().Markers().MarkersFor(*text)[0].Get())
          ->Tag();

  // Select immediately before "mispelled".
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
          .Build());

  // Replace "mispelled" with "misspelled".
  GetDocument().GetFrame()->GetTextSuggestionController().ApplyTextSuggestion(
      marker_tag, 0);

  EXPECT_EQ(0u, GetDocument().Markers().MarkersFor(*text).size());
  EXPECT_EQ("misspelled", text->textContent());
}

TEST_F(TextSuggestionControllerTest, DeleteActiveSuggestionRange_DeleteAtEnd) {
  SetBodyContent(
      "<div contenteditable>"
      "word1 word2"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word2" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 6), Position(text, 11)),
      Color::kTransparent, ImeTextSpanThickness::kThin,
      ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
  // Select immediately before word2
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 6), Position(text, 6))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  EXPECT_EQ("word1\xA0", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteInMiddle) {
  SetBodyContent(
      "<div contenteditable>"
      "word1 word2 word3"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word2" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 6), Position(text, 11)),
      Color::kTransparent, ImeTextSpanThickness::kThin,
      ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
  // Select immediately before word2
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 6), Position(text, 6))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  // One of the extra spaces around "word2" should have been removed
  EXPECT_EQ("word1\xA0word3", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteAtBeginningWithSpaceAfter) {
  SetBodyContent(
      "<div contenteditable>"
      "word1 word2"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word1" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
      ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
      Color::kBlack, Color::kBlack);
  // Select immediately before word1
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  // The space after "word1" should have been removed (to avoid leaving an
  // empty space at the beginning of the composition)
  EXPECT_EQ("word2", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteEntireRange) {
  SetBodyContent(
      "<div contenteditable>"
      "word1"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word1" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
      ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
      Color::kBlack, Color::kBlack);
  // Select immediately before word1
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  EXPECT_EQ("", text->textContent());
}

// The following two cases test situations that probably shouldn't occur in
// normal use (spell check/suggestoin markers not spanning a whole word), but
// are included anyway to verify that DeleteActiveSuggestionRange() is
// well-behaved in these cases

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteRangeWithTextBeforeAndSpaceAfter) {
  SetBodyContent(
      "<div contenteditable>"
      "word1word2 word3"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word2" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 5), Position(text, 10)),
      Color::kTransparent, ImeTextSpanThickness::kThin,
      ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
  // Select immediately before word2
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 5), Position(text, 5))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  EXPECT_EQ("word1\xA0word3", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteRangeWithSpaceBeforeAndTextAfter) {
  SetBodyContent(
      "<div contenteditable>"
      "word1 word2word3"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word2" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 6), Position(text, 11)),
      Color::kTransparent, ImeTextSpanThickness::kThin,
      ImeTextSpanUnderlineStyle::kSolid, Color::kBlack, Color::kBlack);
  // Select immediately before word2
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 6), Position(text, 6))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  EXPECT_EQ("word1\xA0word3", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_DeleteAtBeginningWithTextAfter) {
  SetBodyContent(
      "<div contenteditable>"
      "word1word2"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "word1" as the active suggestion range
  GetDocument().Markers().AddActiveSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)), Color::kTransparent,
      ImeTextSpanThickness::kThin, ImeTextSpanUnderlineStyle::kSolid,
      Color::kBlack, Color::kBlack);
  // Select immediately before word1
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 0), Position(text, 0))
          .Build());
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .DeleteActiveSuggestionRange();

  EXPECT_EQ("word2", text->textContent());
}

TEST_F(TextSuggestionControllerTest,
       DeleteActiveSuggestionRange_OnNewWordAddedToDictionary) {
  SetBodyContent(
      "<div contenteditable>"
      "embiggen"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  Node* text = div->firstChild();

  // Mark "embiggen" as misspelled
  GetDocument().Markers().AddSpellingMarker(
      EphemeralRange(Position(text, 0), Position(text, 8)));
  // Select inside before "embiggen"
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 1), Position(text, 1))
          .Build());

  // Add some other word to the dictionary
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .OnNewWordAddedToDictionary("cromulent");
  // Verify the spelling marker is still present
  EXPECT_NE(nullptr, GetDocument()
                         .GetFrame()
                         ->GetSpellChecker()
                         .GetSpellCheckMarkerUnderSelection()
                         .first);

  // Add "embiggen" to the dictionary
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .OnNewWordAddedToDictionary("embiggen");
  // Verify the spelling marker is gone
  EXPECT_EQ(nullptr, GetDocument()
                         .GetFrame()
                         ->GetSpellChecker()
                         .GetSpellCheckMarkerUnderSelection()
                         .first);
}

TEST_F(TextSuggestionControllerTest, CallbackHappensAfterDocumentDestroyed) {
  LocalFrame& frame = *GetDocument().GetFrame();
  frame.DomWindow()->FrameDestroyed();

  // Shouldn't crash
  frame.GetTextSuggestionController().SuggestionMenuTimeoutCallback(0);
}

TEST_F(TextSuggestionControllerTest, SuggestionMarkerWithEmptySuggestion) {
  SetBodyContent(
      "<div contenteditable>"
      "hello"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  auto* text = To<Text>(div->firstChild());

  // Set suggestion marker with empty suggestion list.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>())
          .Build());

  // Set the caret inside the word.
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 3), Position(text, 3))
          .Build());

  // Handle potential suggestion tap on the caret position.
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .HandlePotentialSuggestionTap(PositionInFlatTree(text, 3));

  // We don't trigger menu in this case so there shouldn't be any mojom
  // connection available.
  EXPECT_FALSE(IsTextSuggestionHostAvailable());

  const VisibleSelectionInFlatTree& selection =
      GetFrame().Selection().ComputeVisibleSelectionInFlatTree();
  EXPECT_FALSE(selection.IsNone());

  const EphemeralRangeInFlatTree& range_to_check =
      ComputeRangeSurroundingCaret(selection.Start());

  const HeapVector<std::pair<Member<const Text>, Member<DocumentMarker>>>&
      node_suggestion_marker_pairs =
          GetFrame().GetDocument()->Markers().MarkersIntersectingRange(
              range_to_check, DocumentMarker::MarkerTypes::Suggestion());
  EXPECT_FALSE(node_suggestion_marker_pairs.IsEmpty());

  // Calling ShowSuggestionMenu() shouldn't crash. See crbug.com/901135.
  // ShowSuggestionMenu() may still get called because of race condition.
  ShowSuggestionMenu(node_suggestion_marker_pairs, 3);
}

TEST_F(TextSuggestionControllerTest, SuggestionMarkerWithSuggestion) {
  SetBodyContent(
      "<div contenteditable>"
      "hello"
      "</div>");
  Element* div = GetDocument().QuerySelector("div");
  auto* text = To<Text>(div->firstChild());

  // Set suggestion marker with two suggestions.
  GetDocument().Markers().AddSuggestionMarker(
      EphemeralRange(Position(text, 0), Position(text, 5)),
      SuggestionMarkerProperties::Builder()
          .SetSuggestions(Vector<String>({"marker1", "marker2"}))
          .Build());

  // Set the caret inside the word.
  GetDocument().GetFrame()->Selection().SetSelectionAndEndTyping(
      SelectionInDOMTree::Builder()
          .SetBaseAndExtent(Position(text, 3), Position(text, 3))
          .Build());

  // Handle potential suggestion tap on the caret position.
  GetDocument()
      .GetFrame()
      ->GetTextSuggestionController()
      .HandlePotentialSuggestionTap(PositionInFlatTree(text, 3));

  EXPECT_TRUE(IsTextSuggestionHostAvailable());
}

}  // namespace blink
