// 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 "chrome/browser/ui/views/location_bar/zoom_bubble_view.h"

#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller.h"
#include "chrome/browser/ui/exclusive_access/fullscreen_controller_test.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/zoom/zoom_controller.h"
#include "extensions/browser/extension_zoom_request_client.h"
#include "extensions/common/extension_builder.h"
#include "ui/views/test/test_widget_observer.h"

#if defined(OS_CHROMEOS)
#include "ash/public/cpp/immersive/immersive_fullscreen_controller_test_api.h"
#include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
#include "ui/aura/test/env_test_helper.h"
#endif

#if defined(OS_MACOSX)
#include "ui/base/test/scoped_fake_nswindow_fullscreen.h"
#endif

using ZoomBubbleBrowserTest = InProcessBrowserTest;

namespace {

void ShowInActiveTab(Browser* browser) {
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::USER_GESTURE);
  EXPECT_TRUE(ZoomBubbleView::GetZoomBubble());
}

}  // namespace

// Test whether the zoom bubble is anchored and whether it is visible when in
// non-immersive fullscreen.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, NonImmersiveFullscreen) {
#if defined(OS_MACOSX)
  ui::test::ScopedFakeNSWindowFullscreen fake_fullscreen;
#endif

  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
  content::WebContents* web_contents = browser_view->GetActiveWebContents();

  // The zoom bubble should be anchored when not in fullscreen.
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble();
  EXPECT_TRUE(zoom_bubble->GetAnchorView());

  // Entering fullscreen should close the bubble. (We enter into tab fullscreen
  // here because tab fullscreen is non-immersive even on Chrome OS.)
  {
    // NOTIFICATION_FULLSCREEN_CHANGED is sent asynchronously. Wait for the
    // notification before testing the zoom bubble visibility.
    std::unique_ptr<FullscreenNotificationObserver> waiter(
        new FullscreenNotificationObserver());
    browser()
        ->exclusive_access_manager()
        ->fullscreen_controller()
        ->EnterFullscreenModeForTab(web_contents, GURL());
    waiter->Wait();
  }
  ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled());
  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());

  // The bubble should not be anchored when it is shown in non-immersive
  // fullscreen.
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
  zoom_bubble = ZoomBubbleView::GetZoomBubble();
  EXPECT_FALSE(zoom_bubble->GetAnchorView());

  // Exit fullscreen before ending the test for the sake of sanity.
  {
    std::unique_ptr<FullscreenNotificationObserver> waiter(
        new FullscreenNotificationObserver());
    chrome::ToggleFullscreenMode(browser());
    waiter->Wait();
  }
}

#if defined(OS_CHROMEOS)
// Test whether the zoom bubble is anchored and whether it is visible when in
// immersive fullscreen.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, ImmersiveFullscreen) {
  aura::test::EnvTestHelper().SetAlwaysUseLastMouseLocation(true);
  BrowserView* browser_view = static_cast<BrowserView*>(browser()->window());
  content::WebContents* web_contents = browser_view->GetActiveWebContents();

  ImmersiveModeController* immersive_controller =
      browser_view->immersive_mode_controller();
  ASSERT_EQ(ImmersiveModeController::Type::ASH, immersive_controller->type());
  ash::ImmersiveFullscreenControllerTestApi(
      static_cast<ImmersiveModeControllerAsh*>(immersive_controller)
          ->controller())
      .SetupForTest();

  // Enter immersive fullscreen.
  {
    std::unique_ptr<FullscreenNotificationObserver> waiter(
        new FullscreenNotificationObserver());
    chrome::ToggleFullscreenMode(browser());
    waiter->Wait();
  }
  ASSERT_TRUE(immersive_controller->IsEnabled());
  ASSERT_FALSE(immersive_controller->IsRevealed());

  // The zoom bubble should not be anchored when it is shown in immersive
  // fullscreen and the top-of-window views are not revealed.
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  ASSERT_TRUE(ZoomBubbleView::GetZoomBubble());
  const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble();
  EXPECT_FALSE(zoom_bubble->GetAnchorView());

  // An immersive reveal should hide the zoom bubble.
  std::unique_ptr<ImmersiveRevealedLock> immersive_reveal_lock(
      immersive_controller->GetRevealedLock(
          ImmersiveModeController::ANIMATE_REVEAL_NO));
  ASSERT_TRUE(immersive_controller->IsRevealed());
  EXPECT_EQ(NULL, ZoomBubbleView::zoom_bubble_);

  // The zoom bubble should be anchored when it is shown in immersive fullscreen
  // and the top-of-window views are revealed.
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  zoom_bubble = ZoomBubbleView::GetZoomBubble();
  ASSERT_TRUE(zoom_bubble);
  EXPECT_TRUE(zoom_bubble->GetAnchorView());

  // The top-of-window views should not hide till the zoom bubble hides. (It
  // would be weird if the view to which the zoom bubble is anchored hid while
  // the zoom bubble was still visible.)
  immersive_reveal_lock.reset();
  EXPECT_TRUE(immersive_controller->IsRevealed());
  ZoomBubbleView::CloseCurrentBubble();
  // The zoom bubble is deleted on a task.
  content::RunAllPendingInMessageLoop();
  EXPECT_FALSE(immersive_controller->IsRevealed());

  // Exit fullscreen before ending the test for the sake of sanity.
  {
    std::unique_ptr<FullscreenNotificationObserver> waiter(
        new FullscreenNotificationObserver());
    chrome::ToggleFullscreenMode(browser());
    waiter->Wait();
  }
}
#endif  // OS_CHROMEOS

// Tests that trying to open zoom bubble with stale WebContents is safe.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, NoWebContentsIsSafe) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();

  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  // Close the current tab and try opening the zoom bubble with stale
  // |web_contents|.
  chrome::CloseTab(browser());
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
}

// Ensure a tab switch closes the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, TabSwitchCloses) {
  AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
  ShowInActiveTab(browser());
  chrome::SelectNextTab(browser());
  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());
}

// Ensure the bubble is dismissed on tab closure and doesn't reference a
// destroyed WebContents.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, DestroyedWebContents) {
  AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK);
  ShowInActiveTab(browser());

  ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble();
  EXPECT_TRUE(bubble);

  views::test::TestWidgetObserver observer(bubble->GetWidget());
  EXPECT_FALSE(bubble->GetWidget()->IsClosed());

  chrome::CloseTab(browser());
  EXPECT_FALSE(ZoomBubbleView::GetZoomBubble());

  // Widget::Close() completes asynchronously, so it's still safe to access
  // |bubble| here, even though GetZoomBubble() returned null.
  EXPECT_FALSE(observer.widget_closed());
  EXPECT_TRUE(bubble->GetWidget()->IsClosed());

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer.widget_closed());
}

namespace {

class TestZoomRequestClient : public extensions::ExtensionZoomRequestClient {
 public:
  TestZoomRequestClient(scoped_refptr<const extensions::Extension> extension,
                        bool should_suppress_bubble)
      : extensions::ExtensionZoomRequestClient(extension),
        should_suppress_bubble_(should_suppress_bubble) {}

  bool ShouldSuppressBubble() const override { return should_suppress_bubble_; }

 protected:
  ~TestZoomRequestClient() override = default;

 private:
  const bool should_suppress_bubble_;
};

}  // namespace

// Extensions may be whitelisted to not show a bubble when they perform a zoom
// change. However, if a zoom bubble is already showing, zoom changes performed
// by the extension should update the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest,
                       BubbleSuppressingExtensionRefreshesExistingBubble) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  zoom::ZoomController* zoom_controller =
      zoom::ZoomController::FromWebContents(web_contents);
  ASSERT_TRUE(zoom_controller);

  // Extension zoom bubble suppression only happens in manual mode.
  zoom_controller->SetZoomMode(zoom::ZoomController::ZOOM_MODE_MANUAL);

  ShowInActiveTab(browser());
  const ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble();
  ASSERT_TRUE(bubble);

  const double old_zoom_level = zoom_controller->GetZoomLevel();
  const base::string16 old_label = bubble->label_->text();

  scoped_refptr<const extensions::Extension> extension =
      extensions::ExtensionBuilder("Test").Build();
  scoped_refptr<const TestZoomRequestClient> client =
      base::MakeRefCounted<const TestZoomRequestClient>(extension, true);
  const double new_zoom_level = old_zoom_level + 0.5;
  zoom_controller->SetZoomLevelByClient(new_zoom_level, client);

  ASSERT_EQ(ZoomBubbleView::GetZoomBubble(), bubble);
  const base::string16 new_label = bubble->label_->text();

  EXPECT_NE(new_label, old_label);
}

class ZoomBubbleReuseTest : public ZoomBubbleBrowserTest {
 protected:
  // Performs two zoom changes by these respective clients (where nullptr
  // represents a user initiated zoom). Returns true if the zoom change by
  // |client2| reused the bubble from the zoom change by |client1|.
  bool IsBubbleReused(scoped_refptr<const TestZoomRequestClient> client1,
                      scoped_refptr<const TestZoomRequestClient> client2) {
    // This test would be inconclusive for clients that do not create bubbles.
    // See BubbleSuppressingExtensionRefreshesExistingBubble instead.
    DCHECK(!client1 || !client1->ShouldSuppressBubble());
    DCHECK(!client2 || !client2->ShouldSuppressBubble());
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    zoom::ZoomController* zoom_controller =
        zoom::ZoomController::FromWebContents(web_contents);
    EXPECT_TRUE(zoom_controller);

    const double starting_zoom_level = zoom_controller->GetZoomLevel();
    const double zoom_level1 = starting_zoom_level + 0.5;
    const double zoom_level2 = zoom_level1 + 0.5;

    zoom_controller->SetZoomLevelByClient(zoom_level1, client1);
    const ZoomBubbleView* bubble1 = ZoomBubbleView::GetZoomBubble();
    EXPECT_TRUE(bubble1);
    zoom_controller->SetZoomLevelByClient(zoom_level2, client2);
    const ZoomBubbleView* bubble2 = ZoomBubbleView::GetZoomBubble();
    EXPECT_TRUE(bubble2);

    return bubble1 == bubble2;
  }

  void SetUpOnMainThread() override {
    extension1_ = extensions::ExtensionBuilder("Test1").Build();
    client1_ =
        base::MakeRefCounted<const TestZoomRequestClient>(extension1_, false);
    extension2_ = extensions::ExtensionBuilder("Test2").Build();
    client2_ =
        base::MakeRefCounted<const TestZoomRequestClient>(extension2_, false);
  }

  scoped_refptr<const extensions::Extension> extension1_;
  scoped_refptr<const TestZoomRequestClient> client1_;
  scoped_refptr<const extensions::Extension> extension2_;
  scoped_refptr<const TestZoomRequestClient> client2_;
};

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, BothUserInitiated) {
  EXPECT_TRUE(IsBubbleReused(nullptr, nullptr));
}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, SameExtension) {
  EXPECT_TRUE(IsBubbleReused(client1_, client1_));
}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, DifferentExtension) {
  EXPECT_FALSE(IsBubbleReused(client1_, client2_));
}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, ExtensionThenUser) {
  EXPECT_FALSE(IsBubbleReused(client1_, nullptr));
}

IN_PROC_BROWSER_TEST_F(ZoomBubbleReuseTest, UserThenExtension) {
  EXPECT_FALSE(IsBubbleReused(nullptr, client1_));
}

class ZoomBubbleDialogTest : public DialogBrowserTest {
 public:
  ZoomBubbleDialogTest() {}

  // DialogBrowserTest:
  void ShowUi(const std::string& name) override { ShowInActiveTab(browser()); }

 private:
  DISALLOW_COPY_AND_ASSIGN(ZoomBubbleDialogTest);
};

// Test that calls ShowUi("default").
IN_PROC_BROWSER_TEST_F(ZoomBubbleDialogTest, InvokeUi_default) {
  ShowAndVerifyUi();
}

// If a key event causes the zoom bubble to gain focus, it shouldn't close
// automatically. This allows keyboard-only users to interact with the bubble.
IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, FocusPreventsClose) {
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  ZoomBubbleView::ShowBubble(web_contents, gfx::Point(),
                             ZoomBubbleView::AUTOMATIC);
  ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble();
  ASSERT_TRUE(bubble);
  // |auto_close_timer_| is running so that the bubble is closed at the end.
  EXPECT_TRUE(bubble->auto_close_timer_.IsRunning());

  views::FocusManager* focus_manager = bubble->GetFocusManager();
  // The bubble must have an associated Widget from which to get a FocusManager.
  ASSERT_TRUE(focus_manager);

  // Focus is usually gained via a key combination like alt+shift+a. The test
  // simulates this by focusing the bubble and then sending an empty KeyEvent.
  focus_manager->SetFocusedView(bubble->reset_button_);
  bubble->OnKeyEvent(nullptr);
  // |auto_close_timer_| should not be running since focus should prevent the
  // bubble from closing.
  EXPECT_FALSE(bubble->auto_close_timer_.IsRunning());
}
