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

#include "components/exo/text_input.h"

#include <memory>
#include <string>

#include "base/strings/utf_string_conversions.h"
#include "components/exo/buffer.h"
#include "components/exo/shell_surface.h"
#include "components/exo/surface.h"
#include "components/exo/test/exo_test_base.h"
#include "components/exo/test/exo_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/input_method_observer.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/views/widget/widget.h"

using testing::_;

namespace exo {

namespace {

class MockTextInputDelegate : public TextInput::Delegate {
 public:
  MockTextInputDelegate() = default;

  // TextInput::Delegate:
  MOCK_METHOD0(Activated, void());
  MOCK_METHOD0(Deactivated, void());
  MOCK_METHOD1(OnVirtualKeyboardVisibilityChanged, void(bool));
  MOCK_METHOD1(SetCompositionText, void(const ui::CompositionText&));
  MOCK_METHOD1(Commit, void(const base::string16&));
  MOCK_METHOD1(SetCursor, void(const gfx::Range&));
  MOCK_METHOD1(DeleteSurroundingText, void(const gfx::Range&));
  MOCK_METHOD1(SendKey, void(const ui::KeyEvent&));
  MOCK_METHOD1(OnLanguageChanged, void(const std::string&));
  MOCK_METHOD1(OnTextDirectionChanged,
               void(base::i18n::TextDirection direction));

 private:
  DISALLOW_COPY_AND_ASSIGN(MockTextInputDelegate);
};

class TestingInputMethodObserver : public ui::InputMethodObserver {
 public:
  explicit TestingInputMethodObserver(ui::InputMethod* input_method)
      : input_method_(input_method) {
    input_method_->AddObserver(this);
  }

  ~TestingInputMethodObserver() override {
    input_method_->RemoveObserver(this);
  }

  // ui::InputMethodObserver
  MOCK_METHOD0(OnFocus, void());
  MOCK_METHOD0(OnBlur, void());
  MOCK_METHOD1(OnCaretBoundsChanged, void(const ui::TextInputClient*));
  MOCK_METHOD1(OnTextInputStateChanged, void(const ui::TextInputClient*));
  MOCK_METHOD1(OnInputMethodDestroyed, void(const ui::InputMethod*));
  MOCK_METHOD0(OnShowVirtualKeyboardIfEnabled, void());

 private:
  ui::InputMethod* input_method_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(TestingInputMethodObserver);
};

class TextInputTest : public test::ExoTestBase {
 public:
  TextInputTest() = default;

  void SetUp() override {
    test::ExoTestBase::SetUp();
    text_input_ =
        std::make_unique<TextInput>(std::make_unique<MockTextInputDelegate>());
    SetupSurface();
  }

  void TearDown() override {
    TearDownSurface();
    text_input_.reset();
    test::ExoTestBase::TearDown();
  }

  void SetupSurface() {
    gfx::Size buffer_size(32, 32);
    buffer_ = std::make_unique<Buffer>(
        exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
    surface_ = std::make_unique<Surface>();
    shell_surface_ = std::make_unique<ShellSurface>(surface_.get());

    surface_->Attach(buffer_.get());
    surface_->Commit();

    gfx::Point origin(100, 100);
    shell_surface_->SetGeometry(gfx::Rect(origin, buffer_size));
  }

  void TearDownSurface() {
    shell_surface_.reset();
    surface_.reset();
    buffer_.reset();
  }

 protected:
  TextInput* text_input() { return text_input_.get(); }
  MockTextInputDelegate* delegate() {
    return static_cast<MockTextInputDelegate*>(text_input_->delegate());
  }
  Surface* surface() { return surface_.get(); }

  ui::InputMethod* GetInputMethod() {
    return surface_->window()->GetHost()->GetInputMethod();
  }

  void SetCompositionText(const std::string& utf8) {
    ui::CompositionText t;
    t.text = base::UTF8ToUTF16(utf8);
    t.selection = gfx::Range(1u);
    t.ime_text_spans.push_back(
        ui::ImeTextSpan(ui::ImeTextSpan::Type::kComposition, 0, t.text.size(),
                        ui::ImeTextSpan::Thickness::kThick));
    EXPECT_CALL(*delegate(), SetCompositionText(t)).Times(1);
    text_input()->SetCompositionText(t);
  }

 private:
  std::unique_ptr<TextInput> text_input_;

  std::unique_ptr<Buffer> buffer_;
  std::unique_ptr<Surface> surface_;
  std::unique_ptr<ShellSurface> shell_surface_;

  DISALLOW_COPY_AND_ASSIGN(TextInputTest);
};

TEST_F(TextInputTest, Activate) {
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, text_input()->GetTextInputType());
  EXPECT_EQ(ui::TEXT_INPUT_MODE_DEFAULT, text_input()->GetTextInputMode());

  EXPECT_CALL(*delegate(), Activated).Times(1);
  text_input()->Activate(surface());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, text_input()->GetTextInputType());
  EXPECT_EQ(ui::TEXT_INPUT_MODE_TEXT, text_input()->GetTextInputMode());
  EXPECT_EQ(0, text_input()->GetTextInputFlags());

  EXPECT_CALL(*delegate(), Deactivated).Times(1);
  text_input()->Deactivate();
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, text_input()->GetTextInputType());
  EXPECT_EQ(ui::TEXT_INPUT_MODE_DEFAULT, text_input()->GetTextInputMode());
}

TEST_F(TextInputTest, ShowVirtualKeyboardIfEnabled) {
  TestingInputMethodObserver observer(GetInputMethod());

  EXPECT_CALL(observer, OnTextInputStateChanged(text_input())).Times(1);
  EXPECT_CALL(*delegate(), Activated).Times(1);
  text_input()->Activate(surface());

  EXPECT_CALL(observer, OnShowVirtualKeyboardIfEnabled)
      .WillOnce(testing::Invoke(
          [this]() { text_input()->OnKeyboardVisibilityChanged(true); }));
  EXPECT_CALL(*delegate(), OnVirtualKeyboardVisibilityChanged(true)).Times(1);
  text_input()->ShowVirtualKeyboardIfEnabled();

  EXPECT_CALL(observer, OnTextInputStateChanged(nullptr)).Times(1);
  EXPECT_CALL(*delegate(), Deactivated).Times(1);
  text_input()->Deactivate();
}

TEST_F(TextInputTest, ShowVirtualKeyboardIfEnabledBeforeActivated) {
  TestingInputMethodObserver observer(GetInputMethod());

  // ShowVirtualKeyboardIfEnabled before activation.
  text_input()->ShowVirtualKeyboardIfEnabled();

  EXPECT_CALL(observer, OnTextInputStateChanged(text_input())).Times(1);
  EXPECT_CALL(observer, OnShowVirtualKeyboardIfEnabled)
      .WillOnce(testing::Invoke(
          [this]() { text_input()->OnKeyboardVisibilityChanged(true); }));
  EXPECT_CALL(*delegate(), Activated).Times(1);
  EXPECT_CALL(*delegate(), OnVirtualKeyboardVisibilityChanged(true)).Times(1);
  text_input()->Activate(surface());

  EXPECT_CALL(*delegate(), Deactivated).Times(1);
}

TEST_F(TextInputTest, SetTypeModeFlag) {
  TestingInputMethodObserver observer(GetInputMethod());

  EXPECT_CALL(observer, OnTextInputStateChanged(text_input())).Times(1);
  EXPECT_CALL(*delegate(), Activated).Times(1);
  text_input()->Activate(surface());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, text_input()->GetTextInputType());
  EXPECT_EQ(ui::TEXT_INPUT_MODE_TEXT, text_input()->GetTextInputMode());
  EXPECT_EQ(0, text_input()->GetTextInputFlags());
  EXPECT_TRUE(text_input()->ShouldDoLearning());

  int flags = ui::TEXT_INPUT_FLAG_AUTOCOMPLETE_OFF |
              ui::TEXT_INPUT_FLAG_AUTOCAPITALIZE_NONE;
  EXPECT_CALL(observer, OnTextInputStateChanged(text_input())).Times(1);
  text_input()->SetTypeModeFlags(ui::TEXT_INPUT_TYPE_URL,
                                 ui::TEXT_INPUT_MODE_URL, flags, false);

  EXPECT_EQ(ui::TEXT_INPUT_TYPE_URL, text_input()->GetTextInputType());
  EXPECT_EQ(ui::TEXT_INPUT_MODE_URL, text_input()->GetTextInputMode());
  EXPECT_EQ(flags, text_input()->GetTextInputFlags());
  EXPECT_FALSE(text_input()->ShouldDoLearning());

  EXPECT_CALL(*delegate(), Deactivated).Times(1);
}

TEST_F(TextInputTest, CaretBounds) {
  TestingInputMethodObserver observer(GetInputMethod());

  EXPECT_CALL(observer, OnTextInputStateChanged(text_input())).Times(1);
  EXPECT_CALL(*delegate(), Activated).Times(1);
  text_input()->Activate(surface());

  gfx::Rect bounds(10, 10, 0, 16);
  EXPECT_CALL(observer, OnCaretBoundsChanged(text_input())).Times(1);
  text_input()->SetCaretBounds(bounds);

  EXPECT_EQ(bounds.size().ToString(),
            text_input()->GetCaretBounds().size().ToString());
  gfx::Point origin = surface()->window()->GetBoundsInScreen().origin();
  origin += bounds.OffsetFromOrigin();
  EXPECT_EQ(origin.ToString(),
            text_input()->GetCaretBounds().origin().ToString());

  EXPECT_CALL(*delegate(), Deactivated).Times(1);
}

TEST_F(TextInputTest, CompositionText) {
  SetCompositionText("composition");

  ui::CompositionText empty;
  EXPECT_CALL(*delegate(), SetCompositionText(empty)).Times(1);
  text_input()->ClearCompositionText();
}

TEST_F(TextInputTest, CommitCompositionText) {
  SetCompositionText("composition");

  EXPECT_CALL(*delegate(), Commit(base::UTF8ToUTF16("composition"))).Times(1);
  const uint32_t composition_text_length =
      text_input()->ConfirmCompositionText(/** keep_selection */ false);
  EXPECT_EQ(composition_text_length, static_cast<uint32_t>(11));
}

TEST_F(TextInputTest, Commit) {
  base::string16 s = base::ASCIIToUTF16("commit text");

  EXPECT_CALL(*delegate(), Commit(s)).Times(1);
  text_input()->InsertText(s);
}

TEST_F(TextInputTest, InsertChar) {
  ui::KeyEvent ev(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, 0);

  EXPECT_CALL(*delegate(), SendKey(testing::Ref(ev))).Times(1);
  text_input()->InsertChar(ev);
}

TEST_F(TextInputTest, InsertCharNormalKey) {
  base::char16 ch = 'x';
  ui::KeyEvent ev(ch, ui::VKEY_X, ui::DomCode::NONE, 0);

  EXPECT_CALL(*delegate(), Commit(base::string16(1, ch))).Times(1);
  EXPECT_CALL(*delegate(), SendKey(_)).Times(0);
  text_input()->InsertChar(ev);
}

TEST_F(TextInputTest, SurroundingText) {
  gfx::Range range;
  EXPECT_FALSE(text_input()->GetTextRange(&range));
  EXPECT_FALSE(text_input()->GetCompositionTextRange(&range));
  EXPECT_FALSE(text_input()->GetEditableSelectionRange(&range));
  base::string16 got_text;
  EXPECT_FALSE(text_input()->GetTextFromRange(gfx::Range(0, 1), &got_text));

  base::string16 text = base::UTF8ToUTF16("surrounding\xE3\x80\x80text");
  text_input()->SetSurroundingText(text, 11, 12);

  EXPECT_TRUE(text_input()->GetTextRange(&range));
  EXPECT_EQ(gfx::Range(0, text.size()).ToString(), range.ToString());

  EXPECT_FALSE(text_input()->GetCompositionTextRange(&range));
  EXPECT_TRUE(text_input()->GetEditableSelectionRange(&range));
  EXPECT_EQ(gfx::Range(11, 12).ToString(), range.ToString());
  EXPECT_TRUE(text_input()->GetTextFromRange(gfx::Range(11, 12), &got_text));
  EXPECT_EQ(text.substr(11, 1), got_text);

  // DeleteSurroundingText receives the range in UTF8 -- so (11, 14) range is
  // expected.
  EXPECT_CALL(*delegate(), DeleteSurroundingText(gfx::Range(11, 14))).Times(1);
  text_input()->ExtendSelectionAndDelete(0, 0);

  size_t composition_size = std::string("composition").size();
  SetCompositionText("composition");
  EXPECT_TRUE(text_input()->GetCompositionTextRange(&range));
  EXPECT_EQ(gfx::Range(11, 11 + composition_size).ToString(), range.ToString());
  EXPECT_TRUE(text_input()->GetTextRange(&range));
  EXPECT_EQ(gfx::Range(0, text.size() - 1 + composition_size).ToString(),
            range.ToString());
  EXPECT_TRUE(text_input()->GetEditableSelectionRange(&range));
  EXPECT_EQ(gfx::Range(11, 12).ToString(), range.ToString());
}

TEST_F(TextInputTest, GetTextRange) {
  base::string16 text = base::UTF8ToUTF16("surrounding text");
  text_input()->SetSurroundingText(text, 11, 12);

  SetCompositionText("composition");

  const struct {
    gfx::Range range;
    std::string expected;
  } kTestCases[] = {
      {gfx::Range(0, 3), "sur"},
      {gfx::Range(10, 13), "gco"},
      {gfx::Range(10, 23), "gcompositiont"},
      {gfx::Range(12, 15), "omp"},
      {gfx::Range(12, 23), "ompositiont"},
      {gfx::Range(22, 25), "tex"},
  };
  for (auto& c : kTestCases) {
    base::string16 result;
    EXPECT_TRUE(text_input()->GetTextFromRange(c.range, &result))
        << c.range.ToString();
    EXPECT_EQ(base::UTF8ToUTF16(c.expected), result) << c.range.ToString();
  }
}

}  // anonymous namespace
}  // namespace exo
