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

#include <stddef.h>

#include "chrome/browser/ash/input_method/textinput_test_helper.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {
namespace input_method {

namespace {
struct InputTypeExpectation {
  std::string node_id;
  ui::TextInputType type;
};
}  // namespace

using TextInput_TextInputStateChangedTest = TextInputTestBase;

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       SwitchToPasswordFieldTest) {
  TextInputTestHelper helper(GetInputMethod());
  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("ime_enable_disable_test.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  EXPECT_EQ(true, content::EvalJs(tab, "text01_focus();"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());

  EXPECT_EQ(true, content::EvalJs(tab, "password01_focus();"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, FocusOnLoadTest) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("focus_input_on_load.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       FocusOnContentJSTest) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("focus_input_on_content_js.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest, MouseClickChange) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("focus_input_with_mouse_click.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(content::WaitForLoadStop(tab));

  ASSERT_TRUE(helper.ClickElement("text_id", tab));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());

  ASSERT_TRUE(helper.ClickElement("password_id", tab));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       FocusChangeOnFocus) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("focus_input_on_anothor_focus.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  std::string coordinate;
  ASSERT_TRUE(
      content::ExecJs(tab, "document.getElementById('text_id').focus();"));

  // Expects PASSWORD text input type because javascript will change the focus
  // to password field in #text_id's onfocus handler.
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());

  ASSERT_TRUE(helper.ClickElement("text_id", tab));
  // Expects PASSWORD text input type because javascript will chagne the focus
  // to password field in #text_id's onfocus handler.
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       NodeEliminationCase) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("simple_textinput.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  ASSERT_TRUE(
      content::ExecJs(tab, "document.getElementById('text_id').focus();"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());

  // Changing text input type to password.
  ASSERT_TRUE(content::ExecJs(
      tab, "document.body.removeChild(document.getElementById('text_id'));"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_NONE);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       TextInputTypeChangedByJavaScript) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("simple_textinput.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));

  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  ASSERT_TRUE(
      content::ExecJs(tab, "document.getElementById('text_id').focus();"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());

  // Changing text input type to password.
  ASSERT_TRUE(content::ExecJs(
      tab, "document.getElementById('text_id').type = 'password';"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       ChangingToContentEditableCase) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("content_editable.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  helper.ClickElement("anchor_id", tab);
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE, helper.GetTextInputType());

  // Disabling content editable, then expecting TEXT_INPUT_TYPE_NONE.
  ASSERT_TRUE(content::ExecJs(
      tab, "document.getElementById('anchor_id').contentEditable = false;"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_NONE);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  // Then re-enabling content editable, then expecting CONTENT_EDITABLE.
  ASSERT_TRUE(content::ExecJs(
      tab, "document.getElementById('anchor_id').contentEditable = true;"));
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE, helper.GetTextInputType());
}

IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       DISABLED_SwitchingAllTextInputTest) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("all_input_node.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
  content::WebContents* tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  InputTypeExpectation expectations[] = {
      {"text_id", ui::TEXT_INPUT_TYPE_TEXT},
      {"password_id", ui::TEXT_INPUT_TYPE_PASSWORD},
      {"search_id", ui::TEXT_INPUT_TYPE_SEARCH},
      {"email_id", ui::TEXT_INPUT_TYPE_EMAIL},
      {"number_id", ui::TEXT_INPUT_TYPE_NUMBER},
      {"tel_id", ui::TEXT_INPUT_TYPE_TELEPHONE},
      {"url_id", ui::TEXT_INPUT_TYPE_URL},
      {"textarea_id", ui::TEXT_INPUT_TYPE_TEXT_AREA},
      {"contenteditable_id", ui::TEXT_INPUT_TYPE_CONTENT_EDITABLE},
  };  // The order should be same as tab order in all_input_node.html.

  for (auto& expectation : expectations) {
    content::SimulateKeyPress(tab, ui::DomKey::TAB, ui::DomCode::TAB,
                              ui::VKEY_TAB, false, false, false, false);

    helper.WaitForTextInputStateChanged(expectation.type);
    EXPECT_EQ(expectation.type, helper.GetTextInputType());
  }

  for (auto& expectation : expectations) {
    helper.ClickElement(expectation.node_id, tab);

    helper.WaitForTextInputStateChanged(expectation.type);
    EXPECT_EQ(expectation.type, helper.GetTextInputType());
  }
}

// Flaky on chromeos.  http://crbug.com/391582
IN_PROC_BROWSER_TEST_F(TextInput_TextInputStateChangedTest,
                       DISABLED_OpenNewTabOnloadTest) {
  TextInputTestHelper helper(GetInputMethod());
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, helper.GetTextInputType());

  GURL base_url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("all_input_node.html")));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), base_url));
  content::WebContents* base_tab =
      browser()->tab_strip_model()->GetActiveWebContents();

  // Focus to password field.
  helper.ClickElement("password_id", base_tab);
  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_PASSWORD);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_PASSWORD, helper.GetTextInputType());

  // Then opening new foreground tab and wait new TextInputType.
  GURL new_url = ui_test_utils::GetTestUrl(
      base::FilePath(FILE_PATH_LITERAL("textinput")),
      base::FilePath(FILE_PATH_LITERAL("focus_input_on_load.html")));
  ui_test_utils::NavigateToURLWithDisposition(
      browser(), new_url, WindowOpenDisposition::NEW_FOREGROUND_TAB, 0);
  content::WebContents* new_tab =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_NE(base_tab, new_tab);

  helper.WaitForTextInputStateChanged(ui::TEXT_INPUT_TYPE_TEXT);
  EXPECT_EQ(ui::TEXT_INPUT_TYPE_TEXT, helper.GetTextInputType());
}

}  // namespace input_method
}  // namespace ash
