// 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 "base/memory/weak_ptr.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/search/search.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/views/constrained_window_views.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/web_modal/web_contents_modal_dialog_host.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "components/web_modal/web_contents_modal_dialog_manager_delegate.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "ipc/ipc_message.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/focus/focus_manager.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/window/dialog_delegate.h"
#include "ui/web_dialogs/test/test_web_dialog_delegate.h"

#if defined(USE_AURA) && defined(USE_X11)
#include <X11/Xlib.h>
#include "ui/events/test/events_test_utils_x11.h"
#endif

using web_modal::WebContentsModalDialogManager;
using web_modal::WebContentsModalDialogManagerDelegate;

namespace {

class TestConstrainedDialogContentsView
    : public views::View,
      public base::SupportsWeakPtr<TestConstrainedDialogContentsView> {
 public:
  TestConstrainedDialogContentsView()
      : text_field_(new views::Textfield) {
    SetLayoutManager(new views::FillLayout);
    AddChildView(text_field_);
  }

  views::View* GetInitiallyFocusedView() {
    return text_field_;
  }

 private:
  views::Textfield* text_field_;
  DISALLOW_COPY_AND_ASSIGN(TestConstrainedDialogContentsView);
};

class TestConstrainedDialog : public views::DialogDelegate {
 public:
  TestConstrainedDialog()
      : contents_((new TestConstrainedDialogContentsView())->AsWeakPtr()),
        done_(false) {
  }

  virtual ~TestConstrainedDialog() {}

  virtual views::View* GetInitiallyFocusedView() OVERRIDE {
    return contents_ ? contents_->GetInitiallyFocusedView() : NULL;
  }

  virtual views::View* GetContentsView() OVERRIDE {
    return contents_.get();
  }

  virtual views::Widget* GetWidget() OVERRIDE {
    return contents_ ? contents_->GetWidget() : NULL;
  }

  virtual const views::Widget* GetWidget() const OVERRIDE {
    return contents_ ? contents_->GetWidget() : NULL;
  }

  virtual void DeleteDelegate() OVERRIDE {
    // Don't delete the delegate yet.  We need to keep it around for inspection
    // later.
    EXPECT_TRUE(done_);
  }

  virtual bool Accept() OVERRIDE {
    done_ = true;
    return true;
  }

  virtual bool Cancel() OVERRIDE {
    done_ = true;
    return true;
  }

  virtual ui::ModalType GetModalType() const OVERRIDE {
#if defined(USE_ASH)
    return ui::MODAL_TYPE_CHILD;
#else
    return views::WidgetDelegate::GetModalType();
#endif
  }

  bool done() {
    return done_;
  }

 private:
  // contents_ will be freed when the View goes away.
  base::WeakPtr<TestConstrainedDialogContentsView> contents_;
  bool done_;

  DISALLOW_COPY_AND_ASSIGN(TestConstrainedDialog);
};

} // namespace

class ConstrainedWindowViewTest : public InProcessBrowserTest {
 public:
  ConstrainedWindowViewTest() {
  }
};

#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
// TODO(erg): linux_aura bringup: http://crbug.com/163931
#define MAYBE_FocusTest DISABLED_FocusTest
#else
#define MAYBE_FocusTest FocusTest
#endif

// Tests the following:
//
// *) Initially focused view in a constrained dialog receives focus reliably.
//
// *) Constrained windows that are queued don't register themselves as
//    accelerator targets until they are displayed.
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, MAYBE_FocusTest) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents != NULL);
  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  ASSERT_TRUE(web_contents_modal_dialog_manager != NULL);
  WebContentsModalDialogManagerDelegate* modal_delegate =
      web_contents_modal_dialog_manager->delegate();
  ASSERT_TRUE(modal_delegate != NULL);

  // Create a constrained dialog.  It will attach itself to web_contents.
  scoped_ptr<TestConstrainedDialog> test_dialog1(new TestConstrainedDialog);
  views::Widget* window1 = views::Widget::CreateWindowAsFramelessChild(
      test_dialog1.get(),
      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
  web_contents_modal_dialog_manager->ShowDialog(window1->GetNativeView());

  views::FocusManager* focus_manager = window1->GetFocusManager();
  ASSERT_TRUE(focus_manager);

  // test_dialog1's text field should be focused.
  EXPECT_EQ(test_dialog1->GetInitiallyFocusedView(),
            focus_manager->GetFocusedView());

  // Now create a second constrained dialog.  This will also be attached to
  // web_contents, but will remain hidden since the test_dialog1 is still
  // showing.
  scoped_ptr<TestConstrainedDialog> test_dialog2(new TestConstrainedDialog);
  views::Widget* window2 = views::Widget::CreateWindowAsFramelessChild(
      test_dialog2.get(),
      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
  web_contents_modal_dialog_manager->ShowDialog(window2->GetNativeView());
  // Should be the same focus_manager.
  ASSERT_EQ(focus_manager, window2->GetFocusManager());

  // test_dialog1's text field should still be the view that has focus.
  EXPECT_EQ(test_dialog1->GetInitiallyFocusedView(),
            focus_manager->GetFocusedView());
  ASSERT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());

  // Now send a VKEY_RETURN to the browser.  This should result in closing
  // test_dialog1.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(
      ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)));
  content::RunAllPendingInMessageLoop();

  EXPECT_TRUE(test_dialog1->done());
  EXPECT_FALSE(test_dialog2->done());
  EXPECT_TRUE(web_contents_modal_dialog_manager->IsDialogActive());

  // test_dialog2 will be shown.  Focus should be on test_dialog2's text field.
  EXPECT_EQ(test_dialog2->GetInitiallyFocusedView(),
            focus_manager->GetFocusedView());

  int tab_with_constrained_window =
      browser()->tab_strip_model()->active_index();

  // Create a new tab.
  chrome::NewTab(browser());

  // The constrained dialog should no longer be selected.
  EXPECT_NE(test_dialog2->GetInitiallyFocusedView(),
            focus_manager->GetFocusedView());

  browser()->tab_strip_model()->ActivateTabAt(tab_with_constrained_window,
                                              false);

  // Activating the previous tab should bring focus to the constrained window.
  EXPECT_EQ(test_dialog2->GetInitiallyFocusedView(),
            focus_manager->GetFocusedView());

  // Send another VKEY_RETURN, closing test_dialog2
  EXPECT_TRUE(focus_manager->ProcessAccelerator(
      ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE)));
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(test_dialog2->done());
  EXPECT_FALSE(web_contents_modal_dialog_manager->IsDialogActive());
}

#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
// TODO(erg): linux_aura bringup: http://crbug.com/163931
#define MAYBE_TabCloseTest DISABLED_TabCloseTest
#else
#define MAYBE_TabCloseTest TabCloseTest
#endif

// Tests that the constrained window is closed properly when its tab is
// closed.
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, MAYBE_TabCloseTest) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents != NULL);
  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  ASSERT_TRUE(web_contents_modal_dialog_manager != NULL);
  WebContentsModalDialogManagerDelegate* modal_delegate =
      web_contents_modal_dialog_manager->delegate();
  ASSERT_TRUE(modal_delegate != NULL);

  // Create a constrained dialog.  It will attach itself to web_contents.
  scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
  views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
      test_dialog.get(),
      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());

  bool closed =
      browser()->tab_strip_model()->CloseWebContentsAt(
          browser()->tab_strip_model()->active_index(),
          TabStripModel::CLOSE_NONE);
  EXPECT_TRUE(closed);
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(test_dialog->done());
}

#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
// TODO(erg): linux_aura bringup: http://crbug.com/163931
#define MAYBE_TabSwitchTest DISABLED_TabSwitchTest
#else
#define MAYBE_TabSwitchTest TabSwitchTest
#endif

// Tests that the constrained window is hidden when an other tab is selected and
// shown when its tab is selected again.
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, MAYBE_TabSwitchTest) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents != NULL);

  // Create a constrained dialog.  It will attach itself to web_contents.
  scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  WebContentsModalDialogManagerDelegate* modal_delegate =
      web_contents_modal_dialog_manager->delegate();
  ASSERT_TRUE(modal_delegate != NULL);
  views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
      test_dialog.get(),
      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
  EXPECT_TRUE(window->IsVisible());

  // Open a new tab. The constrained window should hide itself.
  browser()->tab_strip_model()->AppendWebContents(
      content::WebContents::Create(
          content::WebContents::CreateParams(browser()->profile())),
      true);
  EXPECT_FALSE(window->IsVisible());

  // Close the new tab. The constrained window should show itself again.
  bool closed =
      browser()->tab_strip_model()->CloseWebContentsAt(
          browser()->tab_strip_model()->active_index(),
          TabStripModel::CLOSE_NONE);
  EXPECT_TRUE(closed);
  EXPECT_TRUE(window->IsVisible());

  // Close the original tab.
  browser()->tab_strip_model()->CloseWebContentsAt(
      browser()->tab_strip_model()->active_index(),
      TabStripModel::CLOSE_NONE);
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(test_dialog->done());
}

// Tests that the constrained window behaves properly when moving its tab
// between browser windows.
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest, TabMoveTest) {
  // Open a second browser.
  Browser* browser2 = CreateBrowser(browser()->profile());

  // Create a second WebContents in the second browser, so that moving the
  // WebContents does not trigger the browser to close immediately. This mimics
  // the behavior when a user drags tabs between browsers.
  content::WebContents* web_contents = content::WebContents::Create(
      content::WebContents::CreateParams(browser()->profile()));
  browser2->tab_strip_model()->AppendWebContents(web_contents, true);
  ASSERT_EQ(web_contents, browser2->tab_strip_model()->GetActiveWebContents());

  // Create a constrained dialog.  It will attach itself to web_contents.
  scoped_ptr<TestConstrainedDialog> test_dialog(new TestConstrainedDialog);
  WebContentsModalDialogManager* web_contents_modal_dialog_manager =
      WebContentsModalDialogManager::FromWebContents(web_contents);
  WebContentsModalDialogManagerDelegate* modal_delegate =
      web_contents_modal_dialog_manager->delegate();
  ASSERT_TRUE(modal_delegate != NULL);
  views::Widget* window = views::Widget::CreateWindowAsFramelessChild(
      test_dialog.get(),
      modal_delegate->GetWebContentsModalDialogHost()->GetHostView());
  web_contents_modal_dialog_manager->ShowDialog(window->GetNativeView());
  EXPECT_TRUE(window->IsVisible());

  // Detach the web contents from the second browser's tab strip.
  browser2->tab_strip_model()->DetachWebContentsAt(
      browser2->tab_strip_model()->GetIndexOfWebContents(web_contents));

  // Append the web contents to the first browser.
  browser()->tab_strip_model()->AppendWebContents(web_contents, true);
  EXPECT_TRUE(window->IsVisible());

  // Close the second browser.
  browser2->tab_strip_model()->CloseAllTabs();
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(window->IsVisible());

  // Close the dialog's tab.
  bool closed =
      browser()->tab_strip_model()->CloseWebContentsAt(
          browser()->tab_strip_model()->GetIndexOfWebContents(web_contents),
          TabStripModel::CLOSE_NONE);
  EXPECT_TRUE(closed);
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(test_dialog->done());
}

#if defined(OS_WIN) || (defined(USE_AURA) && defined(USE_X11))

// Forwards the key event which has |key_code| to the renderer.
void ForwardKeyEvent(content::RenderViewHost* host, ui::KeyboardCode key_code) {
#if defined(OS_WIN)
  MSG native_key_event = { NULL, WM_KEYDOWN, key_code, 0 };
#elif defined(USE_X11)
  ui::ScopedXI2Event x_event;
  x_event.InitKeyEvent(ui::ET_KEY_PRESSED, key_code, ui::EF_NONE);
  XEvent* native_key_event = x_event;
#endif

#if defined(USE_AURA)
  ui::KeyEvent key(native_key_event, false);
  ui::KeyEvent* native_ui_key_event = &key;
#elif defined(OS_WIN)
  MSG native_ui_key_event = native_key_event;
#endif

  host->ForwardKeyboardEvent(
      content::NativeWebKeyboardEvent(native_ui_key_event));
}

// Tests that backspace is not processed before it's sent to the web contents.
// Flaky on Win Aura and Linux ChromiumOS. See http://crbug.com/170331
#if defined(USE_AURA)
#define MAYBE_BackspaceSentToWebContent DISABLED_BackspaceSentToWebContent
#else
#define MAYBE_BackspaceSentToWebContent BackspaceSentToWebContent
#endif
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest,
                       MAYBE_BackspaceSentToWebContent) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents != NULL);

  GURL new_tab_url(chrome::kChromeUINewTabURL);
  ui_test_utils::NavigateToURL(browser(), new_tab_url);
  GURL about_url(chrome::kChromeUIAboutURL);
  ui_test_utils::NavigateToURL(browser(), about_url);

  ConstrainedWebDialogDelegate* cwdd = CreateConstrainedWebDialog(
      browser()->profile(),
      new ui::test::TestWebDialogDelegate(about_url),
      NULL,
      web_contents);

  content::WindowedNotificationObserver back_observer(
      content::NOTIFICATION_LOAD_STOP,
      content::Source<content::NavigationController>(
          &web_contents->GetController()));
  content::RenderViewHost* render_view_host =
      cwdd->GetWebContents()->GetRenderViewHost();
  ForwardKeyEvent(render_view_host, ui::VKEY_BACK);

  // Backspace is not processed as accelerator before it's sent to web contents.
  EXPECT_FALSE(web_contents->GetController().GetPendingEntry());
  EXPECT_EQ(about_url.spec(), web_contents->GetURL().spec());

  // Backspace is processed as accelerator after it's sent to web contents.
  content::RunAllPendingInMessageLoop();
  EXPECT_TRUE(web_contents->GetController().GetPendingEntry());

  // Wait for the navigation to commit, since the URL will not be visible
  // until then.
  back_observer.Wait();
  EXPECT_TRUE(chrome::IsNTPURL(web_contents->GetURL(), browser()->profile()));
}

// Fails flakily (once per 10-20 runs) on Win Aura only. http://crbug.com/177482
// Also fails on CrOS.
// Also fails on linux_aura (http://crbug.com/163931)
#if defined(TOOLKIT_VIEWS)
#define MAYBE_EscapeCloseConstrainedWindow DISABLED_EscapeCloseConstrainedWindow
#else
#define MAYBE_EscapeCloseConstrainedWindow EscapeCloseConstrainedWindow
#endif

// Tests that escape closes the constrained window.
IN_PROC_BROWSER_TEST_F(ConstrainedWindowViewTest,
                       MAYBE_EscapeCloseConstrainedWindow) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ASSERT_TRUE(web_contents != NULL);

  GURL new_tab_url(chrome::kChromeUINewTabURL);
  ui_test_utils::NavigateToURL(browser(), new_tab_url);
  ConstrainedWebDialogDelegate* cwdd = CreateConstrainedWebDialog(
      browser()->profile(),
      new ui::test::TestWebDialogDelegate(new_tab_url),
      NULL,
      web_contents);

  views::Widget* widget =
      views::Widget::GetWidgetForNativeView(cwdd->GetNativeDialog());
  views::test::TestWidgetObserver observer(widget);

  content::RenderViewHost* render_view_host =
      cwdd->GetWebContents()->GetRenderViewHost();
  ForwardKeyEvent(render_view_host, ui::VKEY_ESCAPE);

  // Escape is not processed as accelerator before it's sent to web contents.
  EXPECT_FALSE(observer.widget_closed());

  content::RunAllPendingInMessageLoop();

  // Escape is processed as accelerator after it's sent to web contents.
  EXPECT_TRUE(observer.widget_closed());
}

#endif  // defined(OS_WIN) || (defined(USE_AURA) && defined(USE_X11))
