// Copyright (c) 2012 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 "content/browser/web_contents/touch_editable_impl_aura.h"

#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_timeouts.h"
#include "base/values.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view_aura.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ui_base_switches.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/events/event_utils.h"
#include "ui/events/test/event_generator.h"

using blink::WebInputEvent;

namespace content {

class TestTouchEditableImplAura : public TouchEditableImplAura {
 public:
  TestTouchEditableImplAura()
      : selection_changed_callback_arrived_(false),
        waiting_for_selection_changed_callback_(false),
        waiting_for_gesture_ack_type_(WebInputEvent::Undefined),
        last_gesture_ack_type_(WebInputEvent::Undefined) {}

  virtual void Reset() {
    selection_changed_callback_arrived_ = false;
    waiting_for_selection_changed_callback_ = false;
    waiting_for_gesture_ack_type_ = WebInputEvent::Undefined;
    last_gesture_ack_type_ = WebInputEvent::Undefined;
  }

  virtual void OnSelectionOrCursorChanged(const gfx::Rect& anchor,
                                          const gfx::Rect& focus) OVERRIDE {
    selection_changed_callback_arrived_ = true;
    TouchEditableImplAura::OnSelectionOrCursorChanged(anchor, focus);
    if (waiting_for_selection_changed_callback_)
      selection_changed_wait_run_loop_->Quit();
  }

  virtual void GestureEventAck(int gesture_event_type) OVERRIDE {
    last_gesture_ack_type_ =
        static_cast<WebInputEvent::Type>(gesture_event_type);
    TouchEditableImplAura::GestureEventAck(gesture_event_type);
    if (waiting_for_gesture_ack_type_ == gesture_event_type)
      gesture_ack_wait_run_loop_->Quit();
  }

  virtual void WaitForSelectionChangeCallback() {
    if (selection_changed_callback_arrived_)
      return;
    waiting_for_selection_changed_callback_ = true;
    selection_changed_wait_run_loop_.reset(new base::RunLoop());
    selection_changed_wait_run_loop_->Run();
  }

  virtual void WaitForGestureAck(WebInputEvent::Type gesture_event_type) {
    if (last_gesture_ack_type_ == gesture_event_type)
      return;
    waiting_for_gesture_ack_type_ = gesture_event_type;
    gesture_ack_wait_run_loop_.reset(new base::RunLoop());
    gesture_ack_wait_run_loop_->Run();
  }

 protected:
  virtual ~TestTouchEditableImplAura() {}

 private:
  bool selection_changed_callback_arrived_;
  bool waiting_for_selection_changed_callback_;
  WebInputEvent::Type waiting_for_gesture_ack_type_;
  WebInputEvent::Type last_gesture_ack_type_;
  scoped_ptr<base::RunLoop> selection_changed_wait_run_loop_;
  scoped_ptr<base::RunLoop> gesture_ack_wait_run_loop_;

  DISALLOW_COPY_AND_ASSIGN(TestTouchEditableImplAura);
};

class TouchEditableImplAuraTest : public ContentBrowserTest {
 public:
  TouchEditableImplAuraTest() {}

 protected:
  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    command_line->AppendSwitch(switches::kEnableTouchEditing);
  }

  // Executes the javascript synchronously and makes sure the returned value is
  // freed properly.
  void ExecuteSyncJSFunction(RenderFrameHost* rfh, const std::string& jscript) {
    scoped_ptr<base::Value> value =
        content::ExecuteScriptAndGetValue(rfh, jscript);
  }

  // Starts the test server and navigates to the given url. Sets a large enough
  // size to the root window.  Returns after the navigation to the url is
  // complete.
  void StartTestWithPage(const std::string& url) {
    ASSERT_TRUE(test_server()->Start());
    GURL test_url(test_server()->GetURL(url));
    NavigateToURL(shell(), test_url);
    aura::Window* content = shell()->web_contents()->GetContentNativeView();
    content->GetHost()->SetBounds(gfx::Rect(800, 600));
  }

  RenderWidgetHostViewAura* GetRenderWidgetHostViewAura(
      TouchEditableImplAura* touch_editable) {
    return touch_editable->rwhva_;
  }

  ui::TouchSelectionController* GetTouchSelectionController(
      TouchEditableImplAura* touch_editable) {
    return touch_editable->touch_selection_controller_.get();
  }

  ui::TextInputType GetTextInputType(TouchEditableImplAura* touch_editable) {
    return touch_editable->text_input_type_;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TouchEditableImplAuraTest);
};

IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
                       TouchSelectionOriginatingFromWebpageTest) {
  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
      web_contents->GetView());
  TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
  view_aura->SetTouchEditableForTest(touch_editable);
  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  aura::Window* content = web_contents->GetContentNativeView();
  ui::test::EventGenerator generator(content->GetRootWindow(), content);
  gfx::Rect bounds = content->GetBoundsInRootWindow();

  touch_editable->Reset();
  ExecuteSyncJSFunction(main_frame, "select_all_text()");
  touch_editable->WaitForSelectionChangeCallback();

  // Tap inside selection to bring up selection handles.
  generator.GestureTapAt(gfx::Point(bounds.x() + 10, bounds.y() + 10));
  EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);

  scoped_ptr<base::Value> value =
      content::ExecuteScriptAndGetValue(main_frame, "get_selection()");
  std::string selection;
  value->GetAsString(&selection);

  // Check if selection handles are showing.
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));
  EXPECT_STREQ("Some text we can select", selection.c_str());

  // Lets move the handles a bit to modify the selection
  touch_editable->Reset();
  generator.GestureScrollSequence(
      gfx::Point(10, 47),
      gfx::Point(30, 47),
      base::TimeDelta::FromMilliseconds(20),
      5);
  touch_editable->WaitForSelectionChangeCallback();

  EXPECT_TRUE(GetTouchSelectionController(touch_editable));
  value = content::ExecuteScriptAndGetValue(main_frame, "get_selection()");
  value->GetAsString(&selection);

  // It is hard to tell what exactly the selection would be now. But it would
  // definitely be less than whatever was selected before.
  EXPECT_GT(std::strlen("Some text we can select"), selection.size());
}

IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
                       TestTouchSelectionHiddenWhenScrolling) {
  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
      web_contents->GetView());
  TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
  view_aura->SetTouchEditableForTest(touch_editable);
  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);

  // Long press to select word.
  ui::GestureEvent long_press(
      10,
      10,
      0,
      ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS, 0, 0));
  touch_editable->Reset();
  rwhva->OnGestureEvent(&long_press);
  touch_editable->WaitForSelectionChangeCallback();

  // Check if selection handles are showing.
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));

  scoped_ptr<base::Value> value =
      content::ExecuteScriptAndGetValue(main_frame, "get_selection()");
  std::string selection;
  value->GetAsString(&selection);
  EXPECT_STREQ("Some", selection.c_str());

  // Start scrolling. Handles should get hidden.
  ui::GestureEvent scroll_begin(
      10,
      10,
      0,
      ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 0, 0));
  rwhva->OnGestureEvent(&scroll_begin);
  EXPECT_FALSE(GetTouchSelectionController(touch_editable));

  // Handles should come back after scroll ends.
  ui::GestureEvent scroll_end(
      10,
      10,
      0,
      ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_END, 0, 0));
  rwhva->OnGestureEvent(&scroll_end);
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));
}

IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
                       TouchSelectionOnLongPressTest) {
  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
      web_contents->GetView());
  TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
  view_aura->SetTouchEditableForTest(touch_editable);
  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);

  // Long press to select word.
  ui::GestureEvent long_press(
      10,
      10,
      0,
      ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_LONG_PRESS, 0, 0));
  touch_editable->Reset();
  rwhva->OnGestureEvent(&long_press);
  touch_editable->WaitForSelectionChangeCallback();

  // Check if selection handles are showing.
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));

  scoped_ptr<base::Value> value =
      content::ExecuteScriptAndGetValue(main_frame, "get_selection()");
  std::string selection;
  value->GetAsString(&selection);
  EXPECT_STREQ("Some", selection.c_str());
}

IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
                       NoTouchSelectionOnDoubleTapTest) {
  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  WebContentsViewAura* view_aura =
      static_cast<WebContentsViewAura*>(web_contents->GetView());
  TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
  view_aura->SetTouchEditableForTest(touch_editable);
  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);

  // Double-tap to select word.
  ui::GestureEvent double_tap(
      10,
      10,
      0,
      ui::EventTimeForNow(),
      ui::GestureEventDetails(ui::ET_GESTURE_TAP, 2, 0));
  touch_editable->Reset();
  rwhva->OnGestureEvent(&double_tap);
  touch_editable->WaitForSelectionChangeCallback();

  // Make sure touch selection handles are not showing.
  EXPECT_FALSE(GetTouchSelectionController(touch_editable));

  scoped_ptr<base::Value> value =
      content::ExecuteScriptAndGetValue(main_frame, "get_selection()");
  std::string selection;
  value->GetAsString(&selection);
  EXPECT_STREQ("Some", selection.c_str());
}

#if defined(OS_CHROMEOS)
// http://crbug.com/396509
#define MAYBE_TouchCursorInTextfieldTest DISABLED_TouchCursorInTextfieldTest
#else
#define MAYBE_TouchCursorInTextfieldTest TouchCursorInTextfieldTest
#endif
IN_PROC_BROWSER_TEST_F(TouchEditableImplAuraTest,
                       MAYBE_TouchCursorInTextfieldTest) {
  ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/touch_selection.html"));
  WebContentsImpl* web_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  RenderFrameHost* main_frame = web_contents->GetMainFrame();
  WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
      web_contents->GetView());
  TestTouchEditableImplAura* touch_editable = new TestTouchEditableImplAura;
  view_aura->SetTouchEditableForTest(touch_editable);
  RenderWidgetHostViewAura* rwhva = static_cast<RenderWidgetHostViewAura*>(
      web_contents->GetRenderWidgetHostView());
  aura::Window* content = web_contents->GetContentNativeView();
  ui::test::EventGenerator generator(content->GetRootWindow(), content);
  gfx::Rect bounds = content->GetBoundsInRootWindow();
  EXPECT_EQ(GetRenderWidgetHostViewAura(touch_editable), rwhva);

  ExecuteSyncJSFunction(main_frame, "focus_textfield()");
  touch_editable->WaitForSelectionChangeCallback();

  // Tap textfield
  touch_editable->Reset();
  generator.GestureTapAt(gfx::Point(bounds.x() + 50, bounds.y() + 40));
  // Tap Down acks are sent synchronously, while Tap acks are asynchronous.
  touch_editable->WaitForGestureAck(WebInputEvent::GestureTap);
  touch_editable->WaitForSelectionChangeCallback();
  touch_editable->Reset();

  // Check if cursor handle is showing.
  EXPECT_NE(ui::TEXT_INPUT_TYPE_NONE, GetTextInputType(touch_editable));
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));

  scoped_ptr<base::Value> value =
      content::ExecuteScriptAndGetValue(main_frame, "get_cursor_position()");
  int cursor_pos = -1;
  value->GetAsInteger(&cursor_pos);
  EXPECT_NE(-1, cursor_pos);

  // Move the cursor handle.
  generator.GestureScrollSequence(
      gfx::Point(50, 59),
      gfx::Point(10, 59),
      base::TimeDelta::FromMilliseconds(20),
      1);
  touch_editable->WaitForSelectionChangeCallback();
  EXPECT_TRUE(GetTouchSelectionController(touch_editable));
  value = content::ExecuteScriptAndGetValue(main_frame,
                                            "get_cursor_position()");
  int new_cursor_pos = -1;
  value->GetAsInteger(&new_cursor_pos);
  EXPECT_NE(-1, new_cursor_pos);
  // Cursor should have moved.
  EXPECT_NE(new_cursor_pos, cursor_pos);
}

}  // namespace content
