// 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 "ash/ime/input_method_menu_item.h"
#include "ash/ime/input_method_menu_manager.h"
#include "base/bind_helpers.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chromeos/ime/component_extension_ime_manager.h"
#include "chromeos/ime/composition_text.h"
#include "chromeos/ime/input_method_descriptor.h"
#include "chromeos/ime/input_method_manager.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "ui/base/ime/chromeos/ime_bridge.h"
#include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h"
#include "ui/events/event.h"

namespace chromeos {
namespace input_method {
namespace {

const char kIdentityIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
const char kToUpperIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
const char kAPIArgumentIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
const char kExtensionID[] = "iafoklpfplgfnoimmaejoeondnjnlcfp";

// InputMethod extension should work on 1)normal extension, 2)normal extension
// in incognito mode 3)component extension.
enum TestType {
  kTestTypeNormal = 0,
  kTestTypeIncognito = 1,
  kTestTypeComponent = 2,
};

class InputMethodEngineBrowserTest
    : public ExtensionBrowserTest,
      public ::testing::WithParamInterface<TestType> {
 public:
  InputMethodEngineBrowserTest()
      : ExtensionBrowserTest() {}
  virtual ~InputMethodEngineBrowserTest() {}

  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
  }

  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE {
    extension_ = NULL;
  }

 protected:
  void LoadTestInputMethod() {
    // This will load "chrome/test/data/extensions/input_ime"
    ExtensionTestMessageListener ime_ready_listener("ReadyToUseImeEvent",
                                                    false);
    extension_ = LoadExtensionWithType("input_ime", GetParam());
    ASSERT_TRUE(extension_);
    ASSERT_TRUE(ime_ready_listener.WaitUntilSatisfied());

    // Make sure ComponentExtensionIMEManager is initialized.
    // ComponentExtensionIMEManagerImpl::InitializeAsync posts
    // ReadComponentExtensionsInfo to the FILE thread for the
    // initialization.  If it is never initialized for some reasons,
    // the test is timed out and failed.
    ComponentExtensionIMEManager* ceimm =
        InputMethodManager::Get()->GetComponentExtensionIMEManager();
    while (!ceimm->IsInitialized()) {
      content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
    }

    // Extension IMEs are not enabled by default.
    std::vector<std::string> extension_ime_ids;
    extension_ime_ids.push_back(kIdentityIMEID);
    extension_ime_ids.push_back(kToUpperIMEID);
    extension_ime_ids.push_back(kAPIArgumentIMEID);
    InputMethodManager::Get()->SetEnabledExtensionImes(&extension_ime_ids);

    InputMethodDescriptors extension_imes;
    InputMethodManager::Get()->GetInputMethodExtensions(&extension_imes);

    // Test IME has two input methods, thus InputMethodManager should have two
    // extension IME.
    // Note: Even extension is loaded by LoadExtensionAsComponent as above, the
    // IME does not managed by ComponentExtensionIMEManager or it's id won't
    // start with __comp__. The component extension IME is whitelisted and
    // managed by ComponentExtensionIMEManager, but its framework is same as
    // normal extension IME.
    EXPECT_EQ(3U, extension_imes.size());
  }

  const extensions::Extension* LoadExtensionWithType(
      const std::string& extension_name, TestType type) {
    switch (type) {
      case kTestTypeNormal:
        return LoadExtension(test_data_dir_.AppendASCII(extension_name));
      case kTestTypeIncognito:
        return LoadExtensionIncognito(
            test_data_dir_.AppendASCII(extension_name));
      case kTestTypeComponent:
        return LoadExtensionAsComponent(
            test_data_dir_.AppendASCII(extension_name));
    }
    NOTREACHED();
    return NULL;
  }

  const extensions::Extension* extension_;
};

class KeyEventDoneCallback {
 public:
  explicit KeyEventDoneCallback(bool expected_argument)
      : expected_argument_(expected_argument),
        is_called_(false) {}
  ~KeyEventDoneCallback() {}

  void Run(bool consumed) {
    if (consumed == expected_argument_) {
      base::MessageLoop::current()->Quit();
      is_called_ = true;
    }
  }

  void WaitUntilCalled() {
    while (!is_called_)
      content::RunMessageLoop();
  }

 private:
  bool expected_argument_;
  bool is_called_;

  DISALLOW_COPY_AND_ASSIGN(KeyEventDoneCallback);
};

INSTANTIATE_TEST_CASE_P(InputMethodEngineBrowserTest,
                        InputMethodEngineBrowserTest,
                        ::testing::Values(kTestTypeNormal));
INSTANTIATE_TEST_CASE_P(InputMethodEngineIncognitoBrowserTest,
                        InputMethodEngineBrowserTest,
                        ::testing::Values(kTestTypeIncognito));
INSTANTIATE_TEST_CASE_P(InputMethodEngineComponentExtensionBrowserTest,
                        InputMethodEngineBrowserTest,
                        ::testing::Values(kTestTypeComponent));

IN_PROC_BROWSER_TEST_P(InputMethodEngineBrowserTest,
                       BasicScenarioTest) {
  LoadTestInputMethod();

  InputMethodManager::Get()->ChangeInputMethod(kIdentityIMEID);

  scoped_ptr<MockIMEInputContextHandler> mock_input_context(
      new MockIMEInputContextHandler());
  scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
      new MockIMECandidateWindowHandler());

  IMEBridge::Get()->SetInputContextHandler(mock_input_context.get());
  IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());

  IMEEngineHandlerInterface* engine_handler =
      IMEBridge::Get()->GetCurrentEngineHandler();
  ASSERT_TRUE(engine_handler);

  // onActivate event should be fired if Enable function is called.
  ExtensionTestMessageListener activated_listener("onActivate", false);
  engine_handler->Enable();
  ASSERT_TRUE(activated_listener.WaitUntilSatisfied());
  ASSERT_TRUE(activated_listener.was_satisfied());

  // onFocus event should be fired if FocusIn function is called.
  ExtensionTestMessageListener focus_listener("onFocus:text", false);
  IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
                                                  ui::TEXT_INPUT_MODE_DEFAULT);
  engine_handler->FocusIn(context);
  ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
  ASSERT_TRUE(focus_listener.was_satisfied());

  // onKeyEvent should be fired if ProcessKeyEvent is called.
  KeyEventDoneCallback callback(false);  // EchoBackIME doesn't consume keys.
  ExtensionTestMessageListener keyevent_listener("onKeyEvent", false);
  ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE, false);
  engine_handler->ProcessKeyEvent(key_event,
                                  base::Bind(&KeyEventDoneCallback::Run,
                                             base::Unretained(&callback)));
  ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
  ASSERT_TRUE(keyevent_listener.was_satisfied());
  callback.WaitUntilCalled();

  // onSurroundingTextChange should be fired if SetSurroundingText is called.
  ExtensionTestMessageListener surrounding_text_listener(
      "onSurroundingTextChanged", false);
  engine_handler->SetSurroundingText("text",  // Surrounding text.
                                     0,  // focused position.
                                     1);  // anchor position.
  ASSERT_TRUE(surrounding_text_listener.WaitUntilSatisfied());
  ASSERT_TRUE(surrounding_text_listener.was_satisfied());

  // onMenuItemActivated should be fired if PropertyActivate is called.
  ExtensionTestMessageListener property_listener("onMenuItemActivated", false);
  engine_handler->PropertyActivate("property_name");
  ASSERT_TRUE(property_listener.WaitUntilSatisfied());
  ASSERT_TRUE(property_listener.was_satisfied());

  // onReset should be fired if Reset is called.
  ExtensionTestMessageListener reset_listener("onReset", false);
  engine_handler->Reset();
  ASSERT_TRUE(reset_listener.WaitUntilSatisfied());
  ASSERT_TRUE(reset_listener.was_satisfied());

  // onBlur should be fired if FocusOut is called.
  ExtensionTestMessageListener blur_listener("onBlur", false);
  engine_handler->FocusOut();
  ASSERT_TRUE(blur_listener.WaitUntilSatisfied());
  ASSERT_TRUE(blur_listener.was_satisfied());

  // onDeactivated should be fired if Disable is called.
  ExtensionTestMessageListener disabled_listener("onDeactivated", false);
  engine_handler->Disable();
  ASSERT_TRUE(disabled_listener.WaitUntilSatisfied());
  ASSERT_TRUE(disabled_listener.was_satisfied());

  IMEBridge::Get()->SetInputContextHandler(NULL);
  IMEBridge::Get()->SetCandidateWindowHandler(NULL);
}

IN_PROC_BROWSER_TEST_P(InputMethodEngineBrowserTest,
                       APIArgumentTest) {
  LoadTestInputMethod();

  InputMethodManager::Get()->ChangeInputMethod(kAPIArgumentIMEID);

  scoped_ptr<MockIMEInputContextHandler> mock_input_context(
      new MockIMEInputContextHandler());
  scoped_ptr<MockIMECandidateWindowHandler> mock_candidate_window(
      new MockIMECandidateWindowHandler());

  IMEBridge::Get()->SetInputContextHandler(mock_input_context.get());
  IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());

  IMEEngineHandlerInterface* engine_handler =
      IMEBridge::Get()->GetCurrentEngineHandler();
  ASSERT_TRUE(engine_handler);

  extensions::ExtensionHost* host = FindHostWithPath(
      extensions::ExtensionSystem::Get(profile())->process_manager(),
      extensions::BackgroundInfo::GetBackgroundURL(extension_).path(),
      1);

  engine_handler->Enable();
  IMEEngineHandlerInterface::InputContext context(ui::TEXT_INPUT_TYPE_TEXT,
                                                  ui::TEXT_INPUT_MODE_DEFAULT);
  engine_handler->FocusIn(context);

  {
    SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:No");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:a:KeyA:false:false:false:false";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(
        ui::ET_KEY_PRESSED, ui::VKEY_A, "KeyA", ui::EF_NONE, false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:No, Shift:No, Caps:No");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:a:KeyA:true:false:false:false";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_CONTROL_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:No, alt:Yes, Shift:No, Caps:No");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:a:KeyA:false:true:false:false";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_ALT_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:No");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:A:KeyA:false:false:true:false";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_SHIFT_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:No, Caps:Yes");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:A:KeyA:false:false:false:true";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_CAPS_LOCK_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:Yes, alt:Yes, Shift:No, Caps:No");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:a:KeyA:true:true:false:false";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_ALT_DOWN | ui::EF_CONTROL_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  {
    SCOPED_TRACE("KeyDown, Ctrl:No, alt:No, Shift:Yes, Caps:Yes");
    KeyEventDoneCallback callback(false);
    const std::string expected_value =
        "onKeyEvent::keydown:a:KeyA:false:false:true:true";
    ExtensionTestMessageListener keyevent_listener(expected_value, false);

    ui::KeyEvent key_event(ui::ET_KEY_PRESSED,
                           ui::VKEY_A,
                           "KeyA",
                           ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN,
                           false);
    engine_handler->ProcessKeyEvent(key_event,
                                    base::Bind(&KeyEventDoneCallback::Run,
                                               base::Unretained(&callback)));
    ASSERT_TRUE(keyevent_listener.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener.was_satisfied());
    callback.WaitUntilCalled();
  }
  // TODO(nona): Add browser tests for other API as well.
  {
    SCOPED_TRACE("commitText test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char commit_text_test_script[] =
        "chrome.input.ime.commitText({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  text:'COMMIT_TEXT'"
        "});";

    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       commit_text_test_script));
    EXPECT_EQ(1, mock_input_context->commit_text_call_count());
    EXPECT_EQ("COMMIT_TEXT", mock_input_context->last_commit_text());
  }
  {
    SCOPED_TRACE("sendKeyEvents test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char send_key_events_test_script[] =
        "chrome.input.ime.sendKeyEvents({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  keyData : [{"
        "    type : 'keydown',"
        "    requestId : '0',"
        "    key : 'z',"
        "    code : 'KeyZ',"
        "  },{"
        "    type : 'keyup',"
        "    requestId : '1',"
        "    key : 'z',"
        "    code : 'KeyZ',"
        "  }]"
        "});";

    ExtensionTestMessageListener keyevent_listener_down(
        std::string("onKeyEvent:") + kExtensionID +
        ":keydown:z:KeyZ:false:false:false:false",
        false);
    ExtensionTestMessageListener keyevent_listener_up(
        std::string("onKeyEvent:") + kExtensionID +
        ":keyup:z:KeyZ:false:false:false:false",
        false);

    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       send_key_events_test_script));

    ASSERT_TRUE(keyevent_listener_down.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener_down.was_satisfied());
    ASSERT_TRUE(keyevent_listener_up.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener_up.was_satisfied());
  }
  {
    SCOPED_TRACE("sendKeyEvents test with keyCode");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char send_key_events_test_script[] =
        "chrome.input.ime.sendKeyEvents({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  keyData : [{"
        "    type : 'keydown',"
        "    requestId : '2',"
        "    key : 'a',"
        "    code : 'KeyQ',"
        "    keyCode : 0x41,"
        "  },{"
        "    type : 'keyup',"
        "    requestId : '3',"
        "    key : 'a',"
        "    code : 'KeyQ',"
        "    keyCode : 0x41,"
        "  }]"
        "});";

    ExtensionTestMessageListener keyevent_listener_down(
        std::string("onKeyEvent:") + kExtensionID +
        ":keydown:a:KeyQ:false:false:false:false",
        false);
    ExtensionTestMessageListener keyevent_listener_up(
        std::string("onKeyEvent:") + kExtensionID +
        ":keyup:a:KeyQ:false:false:false:false",
        false);

    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       send_key_events_test_script));

    ASSERT_TRUE(keyevent_listener_down.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener_down.was_satisfied());
    ASSERT_TRUE(keyevent_listener_up.WaitUntilSatisfied());
    EXPECT_TRUE(keyevent_listener_up.was_satisfied());
  }
  {
    SCOPED_TRACE("setComposition test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_composition_test_script[] =
        "chrome.input.ime.setComposition({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  text:'COMPOSITION_TEXT',"
        "  cursor:4,"
        "  segments : [{"
        "    start: 0,"
        "    end: 5,"
        "    style: 'underline'"
        "  },{"
        "    start: 6,"
        "    end: 10,"
        "    style: 'doubleUnderline'"
        "  }]"
        "});";

    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       set_composition_test_script));
    EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());

    EXPECT_EQ(4U,
              mock_input_context->last_update_composition_arg().cursor_pos);
    EXPECT_TRUE(mock_input_context->last_update_composition_arg().is_visible);

    const CompositionText& composition_text =
        mock_input_context->last_update_composition_arg().composition_text;
    EXPECT_EQ(base::UTF8ToUTF16("COMPOSITION_TEXT"), composition_text.text());
    const std::vector<CompositionText::UnderlineAttribute>& underlines =
        composition_text.underline_attributes();

    ASSERT_EQ(2U, underlines.size());
    EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_SINGLE,
              underlines[0].type);
    EXPECT_EQ(0U, underlines[0].start_index);
    EXPECT_EQ(5U, underlines[0].end_index);

    EXPECT_EQ(CompositionText::COMPOSITION_TEXT_UNDERLINE_DOUBLE,
              underlines[1].type);
    EXPECT_EQ(6U, underlines[1].start_index);
    EXPECT_EQ(10U, underlines[1].end_index);
  }
  {
    SCOPED_TRACE("clearComposition test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char commite_text_test_script[] =
        "chrome.input.ime.clearComposition({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "});";

    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       commite_text_test_script));
    EXPECT_EQ(1, mock_input_context->update_preedit_text_call_count());
    EXPECT_FALSE(
        mock_input_context->last_update_composition_arg().is_visible);
    const CompositionText& composition_text =
        mock_input_context->last_update_composition_arg().composition_text;
    EXPECT_TRUE(composition_text.text().empty());
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:visibility test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    visible: true,"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:cursor_visibility test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    cursorVisible: true,"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    // window visibility is kept as before.
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;
    EXPECT_TRUE(table.is_cursor_visible());
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:vertical test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    vertical: true,"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    // window visibility is kept as before.
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;

    // cursor visibility is kept as before.
    EXPECT_TRUE(table.is_cursor_visible());

    EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:pageSize test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    pageSize: 7,"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    // window visibility is kept as before.
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;

    // cursor visibility is kept as before.
    EXPECT_TRUE(table.is_cursor_visible());

    // oritantation is kept as before.
    EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());

    EXPECT_EQ(7U, table.page_size());
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:auxTextVisibility test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    auxiliaryTextVisible: true"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;
    EXPECT_TRUE(table.is_auxiliary_text_visible());
  }
  {
    SCOPED_TRACE("setCandidateWindowProperties:auxText test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidate_window_properties_test_script[] =
        "chrome.input.ime.setCandidateWindowProperties({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  properties: {"
        "    auxiliaryText: 'AUXILIARY_TEXT'"
        "  }"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(),
        set_candidate_window_properties_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    // aux text visibility is kept as before.
    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;
    EXPECT_TRUE(table.is_auxiliary_text_visible());
    EXPECT_EQ("AUXILIARY_TEXT", table.auxiliary_text());
  }
  {
    SCOPED_TRACE("setCandidates test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_candidates_test_script[] =
        "chrome.input.ime.setCandidates({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  candidates: [{"
        "    candidate: 'CANDIDATE_1',"
        "    id: 1,"
        "    },{"
        "    candidate: 'CANDIDATE_2',"
        "    id: 2,"
        "    label: 'LABEL_2',"
        "    },{"
        "    candidate: 'CANDIDATE_3',"
        "    id: 3,"
        "    label: 'LABEL_3',"
        "    annotation: 'ANNOTACTION_3'"
        "    },{"
        "    candidate: 'CANDIDATE_4',"
        "    id: 4,"
        "    label: 'LABEL_4',"
        "    annotation: 'ANNOTACTION_4',"
        "    usage: {"
        "      title: 'TITLE_4',"
        "      body: 'BODY_4'"
        "    }"
        "  }]"
        "});";
    ASSERT_TRUE(content::ExecuteScript(host->host_contents(),
                                       set_candidates_test_script));

    // window visibility is kept as before.
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;

    // cursor visibility is kept as before.
    EXPECT_TRUE(table.is_cursor_visible());

    // oritantation is kept as before.
    EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());

    // page size is kept as before.
    EXPECT_EQ(7U, table.page_size());

    ASSERT_EQ(4U, table.candidates().size());

    EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_1"),
              table.candidates().at(0).value);

    EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_2"),
              table.candidates().at(1).value);
    EXPECT_EQ(base::UTF8ToUTF16("LABEL_2"), table.candidates().at(1).label);

    EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_3"),
              table.candidates().at(2).value);
    EXPECT_EQ(base::UTF8ToUTF16("LABEL_3"), table.candidates().at(2).label);
    EXPECT_EQ(base::UTF8ToUTF16("ANNOTACTION_3"),
              table.candidates().at(2).annotation);

    EXPECT_EQ(base::UTF8ToUTF16("CANDIDATE_4"),
              table.candidates().at(3).value);
    EXPECT_EQ(base::UTF8ToUTF16("LABEL_4"), table.candidates().at(3).label);
    EXPECT_EQ(base::UTF8ToUTF16("ANNOTACTION_4"),
              table.candidates().at(3).annotation);
    EXPECT_EQ(base::UTF8ToUTF16("TITLE_4"),
              table.candidates().at(3).description_title);
    EXPECT_EQ(base::UTF8ToUTF16("BODY_4"),
              table.candidates().at(3).description_body);
  }
  {
    SCOPED_TRACE("setCursorPosition test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_cursor_position_test_script[] =
        "chrome.input.ime.setCursorPosition({"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  candidateID: 2"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(), set_cursor_position_test_script));
    EXPECT_EQ(1, mock_candidate_window->update_lookup_table_call_count());

    // window visibility is kept as before.
    EXPECT_TRUE(
        mock_candidate_window->last_update_lookup_table_arg().is_visible);

    const ui::CandidateWindow& table =
        mock_candidate_window->last_update_lookup_table_arg().lookup_table;

    // cursor visibility is kept as before.
    EXPECT_TRUE(table.is_cursor_visible());

    // oritantation is kept as before.
    EXPECT_EQ(ui::CandidateWindow::VERTICAL, table.orientation());

    // page size is kept as before.
    EXPECT_EQ(7U, table.page_size());

    // candidates are same as before.
    ASSERT_EQ(4U, table.candidates().size());

    // Candidate ID == 2 is 1 in index.
    EXPECT_EQ(1U, table.cursor_position());
  }
  {
    SCOPED_TRACE("setMenuItem test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char set_menu_item_test_script[] =
        "chrome.input.ime.setMenuItems({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  items: [{"
        "    id: 'ID0',"
        "  },{"
        "    id: 'ID1',"
        "    label: 'LABEL1',"
        "  },{"
        "    id: 'ID2',"
        "    label: 'LABEL2',"
        "    style: 'radio',"
        "  },{"
        "    id: 'ID3',"
        "    label: 'LABEL3',"
        "    style: 'check',"
        "    visible: true,"
        "  },{"
        "    id: 'ID4',"
        "    label: 'LABEL4',"
        "    style: 'separator',"
        "    visible: true,"
        "    checked: true"
        "  }]"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(), set_menu_item_test_script));

    const ash::ime::InputMethodMenuItemList& props =
        ash::ime::InputMethodMenuManager::GetInstance()->
        GetCurrentInputMethodMenuItemList();
    ASSERT_EQ(5U, props.size());

    EXPECT_EQ("ID0", props[0].key);
    EXPECT_EQ("ID1", props[1].key);
    EXPECT_EQ("ID2", props[2].key);
    EXPECT_EQ("ID3", props[3].key);
    EXPECT_EQ("ID4", props[4].key);

    EXPECT_EQ("LABEL1", props[1].label);
    EXPECT_EQ("LABEL2", props[2].label);
    EXPECT_EQ("LABEL3", props[3].label);
    EXPECT_EQ("LABEL4", props[4].label);

    EXPECT_TRUE(props[2].is_selection_item);
    // TODO(nona): Add tests for style: ["toggle" and "separator"]
    // and visible:, when implement them.

    EXPECT_TRUE(props[4].is_selection_item_checked);
  }
  {
    SCOPED_TRACE("deleteSurroundingText test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    const char delete_surrounding_text_test_script[] =
        "chrome.input.ime.deleteSurroundingText({"
        "  engineID: engineBridge.getActiveEngineID(),"
        "  contextID: engineBridge.getFocusedContextID().contextID,"
        "  offset: 5,"
        "  length: 3"
        "});";
    ASSERT_TRUE(content::ExecuteScript(
        host->host_contents(), delete_surrounding_text_test_script));

    EXPECT_EQ(1, mock_input_context->delete_surrounding_text_call_count());
    EXPECT_EQ(5, mock_input_context->last_delete_surrounding_text_arg().offset);
    EXPECT_EQ(3U,
              mock_input_context->last_delete_surrounding_text_arg().length);
  }
  {
    SCOPED_TRACE("onFocus test");
    mock_input_context->Reset();
    mock_candidate_window->Reset();

    {
      ExtensionTestMessageListener focus_listener("onFocus:text", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_TEXT, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
    {
      ExtensionTestMessageListener focus_listener("onFocus:search", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_SEARCH, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
    {
      ExtensionTestMessageListener focus_listener("onFocus:tel", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_TELEPHONE, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
    {
      ExtensionTestMessageListener focus_listener("onFocus:url", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_URL, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
    {
      ExtensionTestMessageListener focus_listener("onFocus:email", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_EMAIL, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
    {
      ExtensionTestMessageListener focus_listener("onFocus:number", false);
      IMEEngineHandlerInterface::InputContext context(
          ui::TEXT_INPUT_TYPE_NUMBER, ui::TEXT_INPUT_MODE_DEFAULT);
      engine_handler->FocusIn(context);
      ASSERT_TRUE(focus_listener.WaitUntilSatisfied());
      ASSERT_TRUE(focus_listener.was_satisfied());
    }
  }

  IMEBridge::Get()->SetInputContextHandler(NULL);
  IMEBridge::Get()->SetCandidateWindowHandler(NULL);
}

}  // namespace
}  // namespace input_method
}  // namespace chromeos
