// Copyright 2013 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 "ui/base/ime/remote_input_method_win.h"

#include <InputScope.h>

#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/scoped_observer.h"
#include "base/strings/string16.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/composition_text.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/input_method_delegate.h"
#include "ui/base/ime/input_method_observer.h"
#include "ui/base/ime/remote_input_method_delegate_win.h"
#include "ui/events/event.h"

namespace ui {
namespace {

class MockTextInputClient : public DummyTextInputClient {
 public:
  MockTextInputClient()
      : text_input_type_(TEXT_INPUT_TYPE_NONE),
        text_input_mode_(TEXT_INPUT_MODE_DEFAULT),
        call_count_set_composition_text_(0),
        call_count_insert_char_(0),
        call_count_insert_text_(0),
        emulate_pepper_flash_(false),
        is_candidate_window_shown_called_(false),
        is_candidate_window_hidden_called_(false) {
  }

  size_t call_count_set_composition_text() const {
    return call_count_set_composition_text_;
  }
  const base::string16& inserted_text() const {
    return inserted_text_;
  }
  size_t call_count_insert_char() const {
    return call_count_insert_char_;
  }
  size_t call_count_insert_text() const {
    return call_count_insert_text_;
  }
  bool is_candidate_window_shown_called() const {
    return is_candidate_window_shown_called_;
  }
  bool is_candidate_window_hidden_called() const {
    return is_candidate_window_hidden_called_;
  }
  void Reset() {
    text_input_type_ = TEXT_INPUT_TYPE_NONE;
    text_input_mode_ = TEXT_INPUT_MODE_DEFAULT;
    call_count_set_composition_text_ = 0;
    inserted_text_.clear();
    call_count_insert_char_ = 0;
    call_count_insert_text_ = 0;
    caret_bounds_ = gfx::Rect();
    composition_character_bounds_.clear();
    emulate_pepper_flash_ = false;
    is_candidate_window_shown_called_ = false;
    is_candidate_window_hidden_called_ = false;
  }
  void set_text_input_type(ui::TextInputType type) {
    text_input_type_ = type;
  }
  void set_text_input_mode(ui::TextInputMode mode) {
    text_input_mode_ = mode;
  }
  void set_caret_bounds(const gfx::Rect& caret_bounds) {
    caret_bounds_ = caret_bounds;
  }
  void set_composition_character_bounds(
      const std::vector<gfx::Rect>& composition_character_bounds) {
    composition_character_bounds_ = composition_character_bounds;
  }
  void set_emulate_pepper_flash(bool enabled) {
    emulate_pepper_flash_ = enabled;
  }

 private:
  // Overriden from DummyTextInputClient.
  virtual void SetCompositionText(
      const ui::CompositionText& composition) override {
    ++call_count_set_composition_text_;
  }
  virtual void InsertChar(base::char16 ch, int flags) override {
    inserted_text_.append(1, ch);
    ++call_count_insert_char_;
  }
  virtual void InsertText(const base::string16& text) override {
    inserted_text_.append(text);
    ++call_count_insert_text_;
  }
  virtual ui::TextInputType GetTextInputType() const override {
    return text_input_type_;
  }
  virtual ui::TextInputMode GetTextInputMode() const override {
    return text_input_mode_;
  }
  virtual gfx::Rect GetCaretBounds() const {
    return caret_bounds_;
  }
  virtual bool GetCompositionCharacterBounds(uint32 index,
                                             gfx::Rect* rect) const override {
    // Emulate the situation of crbug.com/328237.
    if (emulate_pepper_flash_)
      return false;
    if (!rect || composition_character_bounds_.size() <= index)
      return false;
    *rect = composition_character_bounds_[index];
    return true;
  }
  virtual bool HasCompositionText() const override {
    return !composition_character_bounds_.empty();
  }
  virtual bool GetCompositionTextRange(gfx::Range* range) const override {
    if (composition_character_bounds_.empty())
      return false;
    *range = gfx::Range(0, composition_character_bounds_.size());
    return true;
  }
  virtual void OnCandidateWindowShown() override {
    is_candidate_window_shown_called_ = true;
  }
  virtual void OnCandidateWindowHidden() override {
    is_candidate_window_hidden_called_ = true;
  }

  ui::TextInputType text_input_type_;
  ui::TextInputMode text_input_mode_;
  gfx::Rect caret_bounds_;
  std::vector<gfx::Rect> composition_character_bounds_;
  base::string16 inserted_text_;
  size_t call_count_set_composition_text_;
  size_t call_count_insert_char_;
  size_t call_count_insert_text_;
  bool emulate_pepper_flash_;
  bool is_candidate_window_shown_called_;
  bool is_candidate_window_hidden_called_;
  DISALLOW_COPY_AND_ASSIGN(MockTextInputClient);
};

class MockInputMethodDelegate : public internal::InputMethodDelegate {
 public:
  MockInputMethodDelegate() {}

  const std::vector<ui::KeyboardCode>& fabricated_key_events() const {
    return fabricated_key_events_;
  }
  void Reset() {
    fabricated_key_events_.clear();
  }

 private:
  virtual bool DispatchKeyEventPostIME(const ui::KeyEvent& event) override {
    EXPECT_FALSE(event.HasNativeEvent());
    fabricated_key_events_.push_back(event.key_code());
    return true;
  }

  std::vector<ui::KeyboardCode> fabricated_key_events_;
  DISALLOW_COPY_AND_ASSIGN(MockInputMethodDelegate);
};

class MockRemoteInputMethodDelegateWin
    : public internal::RemoteInputMethodDelegateWin {
 public:
  MockRemoteInputMethodDelegateWin()
      : cancel_composition_called_(false),
        text_input_client_updated_called_(false) {
  }

  bool cancel_composition_called() const {
    return cancel_composition_called_;
  }
  bool text_input_client_updated_called() const {
    return text_input_client_updated_called_;
  }
  const std::vector<int32>& input_scopes() const {
    return input_scopes_;
  }
  const std::vector<gfx::Rect>& composition_character_bounds() const {
    return composition_character_bounds_;
  }
  void Reset() {
    cancel_composition_called_ = false;
    text_input_client_updated_called_ = false;
    input_scopes_.clear();
    composition_character_bounds_.clear();
  }

 private:
  virtual void CancelComposition() override {
    cancel_composition_called_ = true;
  }

  virtual void OnTextInputClientUpdated(
      const std::vector<int32>& input_scopes,
      const std::vector<gfx::Rect>& composition_character_bounds) override {
    text_input_client_updated_called_ = true;
    input_scopes_ = input_scopes;
    composition_character_bounds_ = composition_character_bounds;
  }

  bool cancel_composition_called_;
  bool text_input_client_updated_called_;
  std::vector<int32> input_scopes_;
  std::vector<gfx::Rect> composition_character_bounds_;
  DISALLOW_COPY_AND_ASSIGN(MockRemoteInputMethodDelegateWin);
};

class MockInputMethodObserver : public InputMethodObserver {
 public:
  MockInputMethodObserver()
      : on_text_input_state_changed_(0),
        on_input_method_destroyed_changed_(0) {
  }
  virtual ~MockInputMethodObserver() {
  }
  void Reset() {
    on_text_input_state_changed_ = 0;
    on_input_method_destroyed_changed_ = 0;
  }
  size_t on_text_input_state_changed() const {
    return on_text_input_state_changed_;
  }
  size_t on_input_method_destroyed_changed() const {
    return on_input_method_destroyed_changed_;
  }

 private:
  // Overriden from InputMethodObserver.
  virtual void OnTextInputTypeChanged(const TextInputClient* client) override {
  }
  virtual void OnFocus() override {
  }
  virtual void OnBlur() override {
  }
  virtual void OnCaretBoundsChanged(const TextInputClient* client) override {
  }
  virtual void OnTextInputStateChanged(const TextInputClient* client) override {
    ++on_text_input_state_changed_;
  }
  virtual void OnInputMethodDestroyed(const InputMethod* client) override {
    ++on_input_method_destroyed_changed_;
  }
  virtual void OnShowImeIfNeeded() {
  }

  size_t on_text_input_state_changed_;
  size_t on_input_method_destroyed_changed_;
  DISALLOW_COPY_AND_ASSIGN(MockInputMethodObserver);
};

typedef ScopedObserver<InputMethod, InputMethodObserver>
    InputMethodScopedObserver;

TEST(RemoteInputMethodWinTest, RemoteInputMethodPrivateWin) {
  InputMethod* other_ptr = static_cast<InputMethod*>(NULL) + 1;

  // Use typed NULL to make EXPECT_NE happy until nullptr becomes available.
  RemoteInputMethodPrivateWin* kNull =
      static_cast<RemoteInputMethodPrivateWin*>(NULL);
  EXPECT_EQ(kNull, RemoteInputMethodPrivateWin::Get(other_ptr));

  MockInputMethodDelegate delegate_;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  EXPECT_NE(kNull, RemoteInputMethodPrivateWin::Get(input_method.get()));

  InputMethod* dangling_ptr = input_method.get();
  input_method.reset(NULL);
  EXPECT_EQ(kNull, RemoteInputMethodPrivateWin::Get(dangling_ptr));
}

TEST(RemoteInputMethodWinTest, OnInputSourceChanged) {
  MockInputMethodDelegate delegate_;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);

  private_ptr->OnInputSourceChanged(
      MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), true);
  EXPECT_EQ("ja-JP", input_method->GetInputLocale());

  private_ptr->OnInputSourceChanged(
      MAKELANGID(LANG_ARABIC, SUBLANG_ARABIC_QATAR), true);
  EXPECT_EQ("ar-QA", input_method->GetInputLocale());
}

TEST(RemoteInputMethodWinTest, OnCandidatePopupChanged) {
  MockInputMethodDelegate delegate_;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);

  // Initial value
  EXPECT_FALSE(input_method->IsCandidatePopupOpen());

  // RemoteInputMethodWin::OnCandidatePopupChanged can be called even when the
  // focused text input client is NULL.
  ASSERT_TRUE(input_method->GetTextInputClient() == NULL);
  private_ptr->OnCandidatePopupChanged(false);
  private_ptr->OnCandidatePopupChanged(true);

  MockTextInputClient mock_text_input_client;
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  ASSERT_FALSE(mock_text_input_client.is_candidate_window_shown_called());
  ASSERT_FALSE(mock_text_input_client.is_candidate_window_hidden_called());
  mock_text_input_client.Reset();

  private_ptr->OnCandidatePopupChanged(true);
  EXPECT_TRUE(input_method->IsCandidatePopupOpen());
  EXPECT_TRUE(mock_text_input_client.is_candidate_window_shown_called());
  EXPECT_FALSE(mock_text_input_client.is_candidate_window_hidden_called());

  private_ptr->OnCandidatePopupChanged(false);
  EXPECT_FALSE(input_method->IsCandidatePopupOpen());
  EXPECT_TRUE(mock_text_input_client.is_candidate_window_shown_called());
  EXPECT_TRUE(mock_text_input_client.is_candidate_window_hidden_called());
}

TEST(RemoteInputMethodWinTest, CancelComposition) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  // This must not cause a crash.
  input_method->CancelComposition(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  input_method->CancelComposition(&mock_text_input_client);
  EXPECT_FALSE(mock_remote_delegate.cancel_composition_called());

  input_method->SetFocusedTextInputClient(&mock_text_input_client);
  input_method->CancelComposition(&mock_text_input_client);
  EXPECT_TRUE(mock_remote_delegate.cancel_composition_called());
}

TEST(RemoteInputMethodWinTest, SetFocusedTextInputClient) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
  mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // Initial state must be synced.
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  ASSERT_EQ(1, mock_remote_delegate.composition_character_bounds().size());
  EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
            mock_remote_delegate.composition_character_bounds()[0]);
  ASSERT_EQ(1, mock_remote_delegate.input_scopes().size());
  EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);

  // State must be cleared by SetFocusedTextInputClient(NULL).
  mock_remote_delegate.Reset();
  input_method->SetFocusedTextInputClient(NULL);
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  EXPECT_TRUE(mock_remote_delegate.composition_character_bounds().empty());
  EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());
}

TEST(RemoteInputMethodWinTest, DetachTextInputClient) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
  mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // Initial state must be synced.
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  ASSERT_EQ(1, mock_remote_delegate.composition_character_bounds().size());
  EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
    mock_remote_delegate.composition_character_bounds()[0]);
  ASSERT_EQ(1, mock_remote_delegate.input_scopes().size());
  EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);

  // State must be cleared by DetachTextInputClient
  mock_remote_delegate.Reset();
  input_method->DetachTextInputClient(&mock_text_input_client);
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  EXPECT_TRUE(mock_remote_delegate.composition_character_bounds().empty());
  EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());
}

TEST(RemoteInputMethodWinTest, OnCaretBoundsChanged) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  // This must not cause a crash.
  input_method->OnCaretBoundsChanged(&mock_text_input_client);

  mock_text_input_client.set_caret_bounds(gfx::Rect(10, 0, 10, 20));
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // Initial state must be synced.
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  ASSERT_EQ(1, mock_remote_delegate.composition_character_bounds().size());
  EXPECT_EQ(gfx::Rect(10, 0, 10, 20),
      mock_remote_delegate.composition_character_bounds()[0]);

  // Redundant OnCaretBoundsChanged must be ignored.
  mock_remote_delegate.Reset();
  input_method->OnCaretBoundsChanged(&mock_text_input_client);
  EXPECT_FALSE(mock_remote_delegate.text_input_client_updated_called());

  // Check OnCaretBoundsChanged is handled. (w/o composition)
  mock_remote_delegate.Reset();
  mock_text_input_client.Reset();
  mock_text_input_client.set_caret_bounds(gfx::Rect(10, 20, 30, 40));
  input_method->OnCaretBoundsChanged(&mock_text_input_client);
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  ASSERT_EQ(1, mock_remote_delegate.composition_character_bounds().size());
  EXPECT_EQ(gfx::Rect(10, 20, 30, 40),
      mock_remote_delegate.composition_character_bounds()[0]);

  // Check OnCaretBoundsChanged is handled. (w/ composition)
  {
    mock_remote_delegate.Reset();
    mock_text_input_client.Reset();

    std::vector<gfx::Rect> bounds;
    bounds.push_back(gfx::Rect(10, 20, 30, 40));
    bounds.push_back(gfx::Rect(40, 30, 20, 10));
    mock_text_input_client.set_composition_character_bounds(bounds);
    input_method->OnCaretBoundsChanged(&mock_text_input_client);
    EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
    EXPECT_EQ(bounds, mock_remote_delegate.composition_character_bounds());
  }
}

// Test case against crbug.com/328237.
TEST(RemoteInputMethodWinTest, OnCaretBoundsChangedForPepperFlash) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  mock_remote_delegate.Reset();
  mock_text_input_client.Reset();
  mock_text_input_client.set_emulate_pepper_flash(true);

  std::vector<gfx::Rect> caret_bounds;
  caret_bounds.push_back(gfx::Rect(5, 15, 25, 35));
  mock_text_input_client.set_caret_bounds(caret_bounds[0]);

  std::vector<gfx::Rect> composition_bounds;
  composition_bounds.push_back(gfx::Rect(10, 20, 30, 40));
  composition_bounds.push_back(gfx::Rect(40, 30, 20, 10));
  mock_text_input_client.set_composition_character_bounds(composition_bounds);
  input_method->OnCaretBoundsChanged(&mock_text_input_client);
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  // The caret bounds must be used when
  // TextInputClient::GetCompositionCharacterBounds failed.
  EXPECT_EQ(caret_bounds, mock_remote_delegate.composition_character_bounds());
}

TEST(RemoteInputMethodWinTest, OnTextInputTypeChanged) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  // This must not cause a crash.
  input_method->OnCaretBoundsChanged(&mock_text_input_client);

  mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_URL);
  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // Initial state must be synced.
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  ASSERT_EQ(1, mock_remote_delegate.input_scopes().size());
  EXPECT_EQ(IS_URL, mock_remote_delegate.input_scopes()[0]);

  // Check TEXT_INPUT_TYPE_NONE is handled.
  mock_remote_delegate.Reset();
  mock_text_input_client.Reset();
  mock_text_input_client.set_text_input_type(ui::TEXT_INPUT_TYPE_NONE);
  mock_text_input_client.set_text_input_mode(ui::TEXT_INPUT_MODE_KATAKANA);
  input_method->OnTextInputTypeChanged(&mock_text_input_client);
  EXPECT_TRUE(mock_remote_delegate.text_input_client_updated_called());
  EXPECT_TRUE(mock_remote_delegate.input_scopes().empty());

  // Redundant OnTextInputTypeChanged must be ignored.
  mock_remote_delegate.Reset();
  input_method->OnTextInputTypeChanged(&mock_text_input_client);
  EXPECT_FALSE(mock_remote_delegate.text_input_client_updated_called());

  mock_remote_delegate.Reset();
  mock_text_input_client.Reset();
  mock_text_input_client.set_caret_bounds(gfx::Rect(10, 20, 30, 40));
  input_method->OnCaretBoundsChanged(&mock_text_input_client);
}

TEST(RemoteInputMethodWinTest, DispatchKeyEvent_NativeKeyEvent) {
  // Basically RemoteInputMethodWin does not handle native keydown event.

  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  const MSG wm_keydown = { NULL, WM_KEYDOWN, ui::VKEY_A };
  ui::KeyEvent native_keydown(wm_keydown);

  // This must not cause a crash.
  EXPECT_FALSE(input_method->DispatchKeyEvent(native_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // TextInputClient is not focused yet here.

  EXPECT_FALSE(input_method->DispatchKeyEvent(native_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  // TextInputClient is now focused here.

  EXPECT_FALSE(input_method->DispatchKeyEvent(native_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();
}

TEST(RemoteInputMethodWinTest, DispatchKeyEvent_NativeCharEvent) {
  // RemoteInputMethodWin handles native char event if possible.

  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  const MSG wm_char = { NULL, WM_CHAR, 'A', 0 };
  ui::KeyEvent native_char(wm_char);

  // This must not cause a crash.
  EXPECT_FALSE(input_method->DispatchKeyEvent(native_char));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // TextInputClient is not focused yet here.

  EXPECT_FALSE(input_method->DispatchKeyEvent(native_char));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  // TextInputClient is now focused here.

  EXPECT_TRUE(input_method->DispatchKeyEvent(native_char));
  EXPECT_EQ(L"A", mock_text_input_client.inserted_text());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();
}

TEST(RemoteInputMethodWinTest, DispatchKeyEvent_FabricatedKeyDown) {
  // Fabricated non-char event will be delegated to
  // InputMethodDelegate::DispatchFabricatedKeyEventPostIME as long as the
  // delegate is installed.

  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  ui::KeyEvent fabricated_keydown(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE);
  fabricated_keydown.set_character(L'A');

  // This must not cause a crash.
  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  ASSERT_EQ(1, delegate_.fabricated_key_events().size());
  EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
  delegate_.Reset();
  mock_text_input_client.Reset();

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // TextInputClient is not focused yet here.

  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  ASSERT_EQ(1, delegate_.fabricated_key_events().size());
  EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);
  // TextInputClient is now focused here.

  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  ASSERT_EQ(1, delegate_.fabricated_key_events().size());
  EXPECT_EQ(L'A', delegate_.fabricated_key_events()[0]);
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetDelegate(NULL);
  // RemoteInputMethodDelegateWin is no longer set here.

  EXPECT_FALSE(input_method->DispatchKeyEvent(fabricated_keydown));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
}

TEST(RemoteInputMethodWinTest, DispatchKeyEvent_FabricatedChar) {
  // Note: RemoteInputMethodWin::DispatchKeyEvent should always return true
  // for fabricated character events.

  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  ui::KeyEvent fabricated_char(L'A', ui::VKEY_A, ui::EF_NONE);

  // This must not cause a crash.
  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_char));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  // TextInputClient is not focused yet here.

  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_char));
  EXPECT_TRUE(mock_text_input_client.inserted_text().empty());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  // TextInputClient is now focused here.

  EXPECT_TRUE(input_method->DispatchKeyEvent(fabricated_char));
  EXPECT_EQ(L"A", mock_text_input_client.inserted_text());
  EXPECT_TRUE(delegate_.fabricated_key_events().empty());
  delegate_.Reset();
  mock_text_input_client.Reset();
}

TEST(RemoteInputMethodWinTest, OnCompositionChanged) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  CompositionText composition_text;

  // TextInputClient is not focused yet here.

  private_ptr->OnCompositionChanged(composition_text);
  EXPECT_EQ(0, mock_text_input_client.call_count_set_composition_text());
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  // TextInputClient is now focused here.

  private_ptr->OnCompositionChanged(composition_text);
  EXPECT_EQ(1, mock_text_input_client.call_count_set_composition_text());
  delegate_.Reset();
  mock_text_input_client.Reset();
}

TEST(RemoteInputMethodWinTest, OnTextCommitted) {
  MockInputMethodDelegate delegate_;
  MockTextInputClient mock_text_input_client;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));

  RemoteInputMethodPrivateWin* private_ptr =
      RemoteInputMethodPrivateWin::Get(input_method.get());
  ASSERT_TRUE(private_ptr != NULL);
  MockRemoteInputMethodDelegateWin mock_remote_delegate;
  private_ptr->SetRemoteDelegate(&mock_remote_delegate);

  base::string16 committed_text = L"Hello";

  // TextInputClient is not focused yet here.

  mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_TEXT);
  private_ptr->OnTextCommitted(committed_text);
  EXPECT_EQ(0, mock_text_input_client.call_count_insert_char());
  EXPECT_EQ(0, mock_text_input_client.call_count_insert_text());
  EXPECT_EQ(L"", mock_text_input_client.inserted_text());
  delegate_.Reset();
  mock_text_input_client.Reset();

  input_method->SetFocusedTextInputClient(&mock_text_input_client);

  // TextInputClient is now focused here.

  mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_TEXT);
  private_ptr->OnTextCommitted(committed_text);
  EXPECT_EQ(0, mock_text_input_client.call_count_insert_char());
  EXPECT_EQ(1, mock_text_input_client.call_count_insert_text());
  EXPECT_EQ(committed_text, mock_text_input_client.inserted_text());
  delegate_.Reset();
  mock_text_input_client.Reset();

  // When TextInputType is TEXT_INPUT_TYPE_NONE, TextInputClient::InsertText
  // should not be used.
  mock_text_input_client.set_text_input_type(TEXT_INPUT_TYPE_NONE);
  private_ptr->OnTextCommitted(committed_text);
  EXPECT_EQ(committed_text.size(),
            mock_text_input_client.call_count_insert_char());
  EXPECT_EQ(0, mock_text_input_client.call_count_insert_text());
  EXPECT_EQ(committed_text, mock_text_input_client.inserted_text());
  delegate_.Reset();
  mock_text_input_client.Reset();
}

TEST(RemoteInputMethodWinTest, OnTextInputStateChanged_Observer) {
  DummyTextInputClient text_input_client;
  DummyTextInputClient text_input_client_the_other;

  MockInputMethodObserver input_method_observer;
  MockInputMethodDelegate delegate_;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  InputMethodScopedObserver scoped_observer(&input_method_observer);
  scoped_observer.Add(input_method.get());

  input_method->SetFocusedTextInputClient(&text_input_client);
  ASSERT_EQ(&text_input_client, input_method->GetTextInputClient());
  EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
  input_method_observer.Reset();

  input_method->SetFocusedTextInputClient(&text_input_client);
  ASSERT_EQ(&text_input_client, input_method->GetTextInputClient());
  EXPECT_EQ(0u, input_method_observer.on_text_input_state_changed());
  input_method_observer.Reset();

  input_method->SetFocusedTextInputClient(&text_input_client_the_other);
  ASSERT_EQ(&text_input_client_the_other, input_method->GetTextInputClient());
  EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
  input_method_observer.Reset();

  input_method->DetachTextInputClient(&text_input_client_the_other);
  ASSERT_TRUE(input_method->GetTextInputClient() == NULL);
  EXPECT_EQ(1u, input_method_observer.on_text_input_state_changed());
  input_method_observer.Reset();
}

TEST(RemoteInputMethodWinTest, OnInputMethodDestroyed_Observer) {
  DummyTextInputClient text_input_client;
  DummyTextInputClient text_input_client_the_other;

  MockInputMethodObserver input_method_observer;
  InputMethodScopedObserver scoped_observer(&input_method_observer);

  MockInputMethodDelegate delegate_;
  scoped_ptr<InputMethod> input_method(CreateRemoteInputMethodWin(&delegate_));
  input_method->AddObserver(&input_method_observer);

  EXPECT_EQ(0u, input_method_observer.on_input_method_destroyed_changed());
  input_method.reset();
  EXPECT_EQ(1u, input_method_observer.on_input_method_destroyed_changed());
}

}  // namespace
}  // namespace ui
