// Copyright 2014 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/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/screen_util.h"
#include "ash/shelf/shelf_layout_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "services/ws/public/mojom/window_tree_constants.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/screen.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_ui.h"
#include "ui/keyboard/keyboard_util.h"
#include "ui/keyboard/public/keyboard_switches.h"
#include "ui/keyboard/test/keyboard_test_util.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {

namespace {

// A login implementation of WidgetDelegate.
class LoginTestWidgetDelegate : public views::WidgetDelegate {
 public:
  explicit LoginTestWidgetDelegate(views::Widget* widget) : widget_(widget) {}
  ~LoginTestWidgetDelegate() override = default;

  // Overridden from WidgetDelegate:
  void DeleteDelegate() override { delete this; }
  views::Widget* GetWidget() override { return widget_; }
  const views::Widget* GetWidget() const override { return widget_; }
  bool CanActivate() const override { return true; }
  bool ShouldAdvanceFocusToTopLevelWidget() const override { return true; }

 private:
  views::Widget* widget_;

  DISALLOW_COPY_AND_ASSIGN(LoginTestWidgetDelegate);
};

}  // namespace

class LockLayoutManagerTest : public AshTestBase {
 public:
  void SetUp() override {
    // Allow a virtual keyboard (and initialize it per default).
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        keyboard::switches::kEnableVirtualKeyboard);
    AshTestBase::SetUp();
  }

  void TearDown() override {
    AshTestBase::TearDown();
  }

  aura::Window* CreateTestLoginWindow(views::Widget::InitParams params,
                                      bool use_delegate) {
    aura::Window* parent =
        Shell::GetPrimaryRootWindowController()->GetContainer(
            ash::kShellWindowId_LockScreenContainer);
    params.parent = parent;
    views::Widget* widget = new views::Widget;
    if (use_delegate)
      params.delegate = new LoginTestWidgetDelegate(widget);
    params.context = CurrentContext();
    widget->Init(params);
    widget->Show();
    aura::Window* window = widget->GetNativeView();
    return window;
  }

  // Show or hide the keyboard.
  void ShowKeyboard(bool show) {
    auto* keyboard = keyboard::KeyboardController::Get();
    ASSERT_TRUE(keyboard->IsEnabled());
    if (show == keyboard->IsKeyboardVisible())
      return;

    if (show) {
      keyboard->ShowKeyboard(false);
      ASSERT_TRUE(keyboard::WaitUntilShown());
    } else {
      keyboard->HideKeyboardByUser();
    }

    DCHECK_EQ(show, keyboard->IsKeyboardVisible());
  }

  void SetKeyboardOverscrollBehavior(
      keyboard::mojom::KeyboardOverscrollBehavior overscroll_behavior) {
    auto config = keyboard::KeyboardController::Get()->keyboard_config();
    config.overscroll_behavior = overscroll_behavior;
    keyboard::KeyboardController::Get()->UpdateKeyboardConfig(config);
  }
};

TEST_F(LockLayoutManagerTest, NorwmalWindowBoundsArePreserved) {
  gfx::Rect screen_bounds =
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW);
  const gfx::Rect bounds = gfx::Rect(10, 10, 300, 300);
  widget_params.bounds = bounds;
  std::unique_ptr<aura::Window> window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));
  EXPECT_EQ(bounds.ToString(), window->GetBoundsInScreen().ToString());

  gfx::Rect work_area =
      screen_util::GetDisplayWorkAreaBoundsInParent(window.get());
  window->SetBounds(work_area);

  EXPECT_EQ(work_area.ToString(), window->GetBoundsInScreen().ToString());
  EXPECT_NE(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());

  const gfx::Rect bounds2 = gfx::Rect(100, 100, 200, 200);
  window->SetBounds(bounds2);
  EXPECT_EQ(bounds2.ToString(), window->GetBoundsInScreen().ToString());
}

TEST_F(LockLayoutManagerTest, MaximizedFullscreenWindowBoundsAreEqualToScreen) {
  gfx::Rect screen_bounds =
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.show_state = ui::SHOW_STATE_MAXIMIZED;
  const gfx::Rect bounds = gfx::Rect(10, 10, 300, 300);
  widget_params.bounds = bounds;
  // Maximized TYPE_WINDOW_FRAMELESS windows needs a delegate defined otherwise
  // it won't get initial SetBounds event.
  std::unique_ptr<aura::Window> maximized_window(
      CreateTestLoginWindow(widget_params, true /* use_delegate */));

  widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  widget_params.delegate = NULL;
  std::unique_ptr<aura::Window> fullscreen_window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));

  EXPECT_EQ(screen_bounds.ToString(),
            maximized_window->GetBoundsInScreen().ToString());
  EXPECT_EQ(screen_bounds.ToString(),
            fullscreen_window->GetBoundsInScreen().ToString());

  gfx::Rect work_area =
      screen_util::GetDisplayWorkAreaBoundsInParent(maximized_window.get());
  maximized_window->SetBounds(work_area);

  EXPECT_NE(work_area.ToString(),
            maximized_window->GetBoundsInScreen().ToString());
  EXPECT_EQ(screen_bounds.ToString(),
            maximized_window->GetBoundsInScreen().ToString());

  work_area =
      screen_util::GetDisplayWorkAreaBoundsInParent(fullscreen_window.get());
  fullscreen_window->SetBounds(work_area);
  EXPECT_NE(work_area.ToString(),
            fullscreen_window->GetBoundsInScreen().ToString());
  EXPECT_EQ(screen_bounds.ToString(),
            fullscreen_window->GetBoundsInScreen().ToString());

  const gfx::Rect bounds2 = gfx::Rect(100, 100, 200, 200);
  maximized_window->SetBounds(bounds2);
  fullscreen_window->SetBounds(bounds2);
  EXPECT_EQ(screen_bounds.ToString(),
            maximized_window->GetBoundsInScreen().ToString());
  EXPECT_EQ(screen_bounds.ToString(),
            fullscreen_window->GetBoundsInScreen().ToString());
}

TEST_F(LockLayoutManagerTest, AccessibilityPanel) {
  ash::ShelfLayoutManager* shelf_layout_manager =
      GetPrimaryShelf()->shelf_layout_manager();
  ASSERT_TRUE(shelf_layout_manager);

  // Set the accessibility panel height.
  int accessibility_panel_height = 45;
  shelf_layout_manager->SetAccessibilityPanelHeight(accessibility_panel_height);

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  std::unique_ptr<aura::Window> window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));

  display::Display primary_display =
      display::Screen::GetScreen()->GetPrimaryDisplay();

  gfx::Rect target_bounds = primary_display.bounds();
  target_bounds.Inset(0 /* left */, accessibility_panel_height /* top */,
                      0 /* right */, 0 /* bottom */);

  EXPECT_EQ(target_bounds, window->GetBoundsInScreen());

  // Update the accessibility panel height, and verify the window bounds are
  // updated accordingly.
  accessibility_panel_height = 25;
  shelf_layout_manager->SetAccessibilityPanelHeight(accessibility_panel_height);

  target_bounds = primary_display.bounds();
  target_bounds.Inset(0 /* left */, accessibility_panel_height /* top */,
                      0 /* right */, 0 /* bottom */);

  EXPECT_EQ(target_bounds, window->GetBoundsInScreen());
}

TEST_F(LockLayoutManagerTest, KeyboardBounds) {
  display::Display primary_display =
      display::Screen::GetScreen()->GetPrimaryDisplay();
  gfx::Rect screen_bounds = primary_display.bounds();

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  std::unique_ptr<aura::Window> window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));

  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());

  // When virtual keyboard overscroll is enabled keyboard bounds should not
  // affect window bounds.
  keyboard::KeyboardController* keyboard = keyboard::KeyboardController::Get();
  SetKeyboardOverscrollBehavior(
      keyboard::mojom::KeyboardOverscrollBehavior::kEnabled);
  ShowKeyboard(true);
  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
  gfx::Rect keyboard_bounds = keyboard->visual_bounds_in_screen();
  EXPECT_NE(keyboard_bounds, gfx::Rect());
  ShowKeyboard(false);

  // When keyboard is hidden make sure that rotating the screen gives 100% of
  // screen size to window.
  // Repro steps for http://crbug.com/401667:
  // 1. Set up login screen defaults: VK overscroll disabled
  // 2. Show/hide keyboard, make sure that no stale keyboard bounds are cached.
  SetKeyboardOverscrollBehavior(
      keyboard::mojom::KeyboardOverscrollBehavior::kDisabled);
  ShowKeyboard(true);
  ShowKeyboard(false);
  display_manager()->SetDisplayRotation(
      primary_display.id(), display::Display::ROTATE_90,
      display::Display::RotationSource::ACTIVE);
  primary_display = display::Screen::GetScreen()->GetPrimaryDisplay();
  screen_bounds = primary_display.bounds();
  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
  display_manager()->SetDisplayRotation(
      primary_display.id(), display::Display::ROTATE_0,
      display::Display::RotationSource::ACTIVE);

  // When virtual keyboard overscroll is disabled keyboard bounds do
  // affect window bounds.
  SetKeyboardOverscrollBehavior(
      keyboard::mojom::KeyboardOverscrollBehavior::kDisabled);
  ShowKeyboard(true);

  primary_display = display::Screen::GetScreen()->GetPrimaryDisplay();
  screen_bounds = primary_display.bounds();
  gfx::Rect target_bounds(screen_bounds);
  target_bounds.set_height(target_bounds.height() -
                           keyboard->GetKeyboardWindow()->bounds().height());
  EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
  ShowKeyboard(false);

  SetKeyboardOverscrollBehavior(
      keyboard::mojom::KeyboardOverscrollBehavior::kDefault);

  keyboard->SetContainerType(keyboard::mojom::ContainerType::kFloating,
                             base::nullopt /* target_bounds */,
                             base::BindOnce([](bool success) {}));
  ShowKeyboard(true);
  primary_display = display::Screen::GetScreen()->GetPrimaryDisplay();
  screen_bounds = primary_display.bounds();
  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
  ShowKeyboard(false);
}

TEST_F(LockLayoutManagerTest, MultipleMonitors) {
  UpdateDisplay("300x400,400x500");
  gfx::Rect screen_bounds =
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  std::unique_ptr<aura::Window> window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));
  window->SetProperty(aura::client::kResizeBehaviorKey,
                      ws::mojom::kResizeBehaviorCanMaximize);

  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());

  EXPECT_EQ(root_windows[0], window->GetRootWindow());

  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));

  // Maximize the window with as the restore bounds is inside 2nd display but
  // lock container windows are always on primary display.
  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ("0,0 300x400", window->GetBoundsInScreen().ToString());

  window_state->Restore();
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ("0,0 300x400", window->GetBoundsInScreen().ToString());

  window_state->SetRestoreBoundsInScreen(gfx::Rect(280, 0, 30, 40));
  window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ("0,0 300x400", window->GetBoundsInScreen().ToString());

  window_state->Restore();
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ("0,0 300x400", window->GetBoundsInScreen().ToString());

  gfx::Rect work_area =
      screen_util::GetDisplayWorkAreaBoundsInParent(window.get());
  window->SetBounds(work_area);
  // Usually work_area takes Shelf into account but that doesn't affect
  // LockScreen container windows.
  EXPECT_NE(work_area.ToString(), window->GetBoundsInScreen().ToString());
  EXPECT_EQ(screen_bounds.ToString(), window->GetBoundsInScreen().ToString());
}

TEST_F(LockLayoutManagerTest, AccessibilityPanelWithMultipleMonitors) {
  UpdateDisplay("300x400,400x500");

  ash::ShelfLayoutManager* shelf_layout_manager =
      GetPrimaryShelf()->shelf_layout_manager();
  ASSERT_TRUE(shelf_layout_manager);

  int accessibility_panel_height = 45;
  shelf_layout_manager->SetAccessibilityPanelHeight(accessibility_panel_height);

  aura::Window::Windows root_windows = Shell::GetAllRootWindows();

  views::Widget::InitParams widget_params(
      views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
  widget_params.show_state = ui::SHOW_STATE_FULLSCREEN;
  std::unique_ptr<aura::Window> window(
      CreateTestLoginWindow(widget_params, false /* use_delegate */));
  window->SetProperty(aura::client::kResizeBehaviorKey,
                      ws::mojom::kResizeBehaviorCanMaximize);

  gfx::Rect target_bounds =
      display::Screen::GetScreen()->GetPrimaryDisplay().bounds();
  target_bounds.Inset(0, accessibility_panel_height, 0, 0);
  EXPECT_EQ(target_bounds, window->GetBoundsInScreen());

  // Restore window with bounds in the second display, the window should be
  // shown in the primary display.
  wm::WindowState* window_state = wm::GetWindowState(window.get());
  window_state->SetRestoreBoundsInScreen(gfx::Rect(400, 0, 30, 40));

  window_state->Restore();
  EXPECT_EQ(root_windows[0], window->GetRootWindow());
  EXPECT_EQ(target_bounds, window->GetBoundsInScreen());

  // Force the window to secondary display - accessibility panel is only set
  // for the primary shelf, so it should not influence the screen bounds.
  window->SetBoundsInScreen(gfx::Rect(0, 0, 30, 40), GetSecondaryDisplay());

  target_bounds = gfx::Rect(300, 0, 400, 500);
  EXPECT_EQ(root_windows[1], window->GetRootWindow());
  EXPECT_EQ(target_bounds, window->GetBoundsInScreen());
}

}  // namespace ash
