// Copyright (c) 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 "ash/display/mirror_window_controller.h"

#include "ash/ash_switches.h"
#include "ash/display/display_manager.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/cursor_manager_test_api.h"
#include "ash/test/display_manager_test_api.h"
#include "ash/test/mirror_window_test_api.h"
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "ui/aura/env.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/hit_test.h"
#include "ui/events/test/event_generator.h"

namespace ash {

namespace {
DisplayInfo CreateDisplayInfo(int64_t id, const gfx::Rect& bounds) {
  DisplayInfo info(id, base::StringPrintf("x-%d", static_cast<int>(id)), false);
  info.SetBounds(bounds);
  return info;
}

class MirrorOnBootTest : public test::AshTestBase {
 public:
  MirrorOnBootTest() {}
  ~MirrorOnBootTest() override {}

  void SetUp() override {
    base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
        switches::kAshHostWindowBounds, "1+1-300x300,1+301-300x300");
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kAshEnableSoftwareMirroring);
    test::AshTestBase::SetUp();
  }
  void TearDown() override { test::AshTestBase::TearDown(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(MirrorOnBootTest);
};

}

typedef test::AshTestBase MirrorWindowControllerTest;

#if defined(OS_WIN)
// Software mirroring does not work on win.
#define MAYBE_MirrorCursorBasic DISABLED_MirrorCursorBasic
#define MAYBE_MirrorCursorLocations DISABLED_MirrorCursorLocations
#define MAYBE_MirrorCursorMoveOnEnter DISABLED_MirrorCursorMoveOnEnter
#define MAYBE_MirrorCursorRotate DISABLED_MirrorCursorRotate
#define MAYBE_DockMode DISABLED_DockMode
#define MAYBE_MirrorOnBoot DISABLED_MirrorOnBoot
#else
#define MAYBE_MirrorCursorBasic MirrorCursorBasic
#define MAYBE_MirrorCursorLocations MirrorCursorLocations
#define MAYBE_MirrorCursorMoveOnEnter MirrorCursorMoveOnEnter
#define MAYBE_MirrorCursorRotate MirrorCursorRotate
#define MAYBE_DockMode DockMode
#define MAYBE_MirrorOnBoot MirrorOnBoot
#endif

TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorBasic) {
  test::MirrorWindowTestApi test_api;
  aura::test::TestWindowDelegate test_window_delegate;
  test_window_delegate.set_window_component(HTTOP);

  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
  UpdateDisplay("400x400,400x400");
  aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow();
  scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
      &test_window_delegate,
      0,
      gfx::Rect(50, 50, 100, 100),
      root));
  window->Show();
  window->SetName("foo");

  EXPECT_TRUE(test_api.GetCursorWindow());
  EXPECT_EQ("50,50 100x100", window->bounds().ToString());

  ui::test::EventGenerator generator(root);
  generator.MoveMouseTo(10, 10);

  // Test if cursor movement is propertly reflected in mirror window.
  EXPECT_EQ("4,4", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("10,10",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
  EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType());
  EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible());

  // Test if cursor type change is propertly reflected in mirror window.
  generator.MoveMouseTo(100, 100);
  EXPECT_EQ("100,100",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
  EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType());

  // Test if visibility change is propertly reflected in mirror window.
  // A key event hides cursor.
  generator.PressKey(ui::VKEY_A, 0);
  generator.ReleaseKey(ui::VKEY_A, 0);
  EXPECT_FALSE(test_api.GetCursorWindow()->IsVisible());

  // Mouse event makes it visible again.
  generator.MoveMouseTo(300, 300);
  EXPECT_EQ("300,300",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
  EXPECT_EQ(ui::kCursorNull, test_api.GetCurrentCursorType());
  EXPECT_TRUE(test_api.GetCursorWindow()->IsVisible());
}

TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorRotate) {
  test::MirrorWindowTestApi test_api;
  aura::test::TestWindowDelegate test_window_delegate;
  test_window_delegate.set_window_component(HTTOP);

  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
  UpdateDisplay("400x400,400x400");
  aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow();
  scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
      &test_window_delegate,
      0,
      gfx::Rect(50, 50, 100, 100),
      root));
  window->Show();
  window->SetName("foo");

  EXPECT_TRUE(test_api.GetCursorWindow());
  EXPECT_EQ("50,50 100x100", window->bounds().ToString());

  ui::test::EventGenerator generator(root);
  generator.MoveMouseToInHost(100, 100);

  // Test if cursor movement is propertly reflected in mirror window.
  EXPECT_EQ("11,12", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("100,100",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
  EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType());

  UpdateDisplay("400x400/r,400x400");  // 90 degrees.
  generator.MoveMouseToInHost(300, 100);
  EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType());
  // The size of cursor image is 25x25, so the rotated hot point must
  // be (25-12, 11).
  EXPECT_EQ("13,11", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("300,100",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());

  UpdateDisplay("400x400/u,400x400");  // 180 degrees.
  generator.MoveMouseToInHost(300, 300);
  EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType());
  // Rotated hot point must be (25-11, 25-12).
  EXPECT_EQ("14,13", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("300,300",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());

  UpdateDisplay("400x400/l,400x400");  // 270 degrees.
  generator.MoveMouseToInHost(100, 300);
  EXPECT_EQ(ui::kCursorNorthResize, test_api.GetCurrentCursorType());
  // Rotated hot point must be (12, 25-11).
  EXPECT_EQ("12,14", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("100,300",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
}

// Make sure that the mirror cursor's location is same as
// the source display's host location in the mirror root window's
// coordinates.
TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorLocations) {
  test::MirrorWindowTestApi test_api;
  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);

  // Test with device scale factor.
  UpdateDisplay("400x600*2,400x600");

  aura::Window* root = Shell::GetInstance()->GetPrimaryRootWindow();
  ui::test::EventGenerator generator(root);
  generator.MoveMouseToInHost(10, 20);

  EXPECT_EQ("7,7", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("10,20",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());

  // Test with ui scale
  UpdateDisplay("400x600*0.5,400x600");
  generator.MoveMouseToInHost(20, 30);

  EXPECT_EQ("4,4", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("20,30",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());

  // Test with rotation
  UpdateDisplay("400x600/r,400x600");
  generator.MoveMouseToInHost(30, 40);

  EXPECT_EQ("21,4", test_api.GetCursorHotPoint().ToString());
  EXPECT_EQ("30,40",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
}

// Test the behavior of the cursor when entering software mirror mode swaps the
// cursor's display.
TEST_F(MirrorWindowControllerTest, MAYBE_MirrorCursorMoveOnEnter) {
  aura::Env* env = aura::Env::GetInstance();
  Shell* shell = Shell::GetInstance();
  WindowTreeHostManager* window_tree_host_manager =
      shell->window_tree_host_manager();

  UpdateDisplay("400x400*2/r,400x400");
  int64_t primary_display_id = window_tree_host_manager->GetPrimaryDisplayId();
  int64_t secondary_display_id = ScreenUtil::GetSecondaryDisplay().id();
  test::ScopedSetInternalDisplayId set_internal(primary_display_id);

  // Chrome uses the internal display as the source display for software mirror
  // mode. Move the cursor to the external display.
  aura::Window* secondary_root_window =
      window_tree_host_manager->GetRootWindowForDisplayId(secondary_display_id);
  secondary_root_window->MoveCursorTo(gfx::Point(100, 200));
  EXPECT_EQ("300,200", env->last_mouse_location().ToString());
  test::CursorManagerTestApi cursor_test_api(shell->cursor_manager());
  EXPECT_EQ(1.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
  EXPECT_EQ(gfx::Display::ROTATE_0, cursor_test_api.GetCurrentCursorRotation());

  shell->display_manager()->SetMultiDisplayMode(DisplayManager::MIRRORING);
  UpdateDisplay("400x400*2/r,400x400");

  // Entering mirror mode should have centered the cursor on the primary display
  // because the cursor's previous position is out of bounds.
  // Check real cursor's position and properties.
  EXPECT_EQ("100,100", env->last_mouse_location().ToString());
  EXPECT_EQ(2.0f, cursor_test_api.GetCurrentCursor().device_scale_factor());
  EXPECT_EQ(gfx::Display::ROTATE_90,
            cursor_test_api.GetCurrentCursorRotation());

  // Check mirrored cursor's location.
  test::MirrorWindowTestApi test_api;
  gfx::Point hot_point = test_api.GetCursorHotPoint();
  // Rotated hot point must be (25-7, 7).
  EXPECT_EQ("18,7", test_api.GetCursorHotPoint().ToString());
  // New coordinates are not (200,200) because (200,200) is not the center of
  // the display.
  EXPECT_EQ("199,200",
            test_api.GetCursorHotPointLocationInRootWindow().ToString());
}

// Make sure that the compositor based mirroring can switch
// from/to dock mode.
TEST_F(MirrorWindowControllerTest, MAYBE_DockMode) {
  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
  const int64_t internal_id = 1;
  const int64_t external_id = 2;

  const DisplayInfo internal_display_info =
      CreateDisplayInfo(internal_id, gfx::Rect(0, 0, 500, 500));
  const DisplayInfo external_display_info =
      CreateDisplayInfo(external_id, gfx::Rect(1, 1, 100, 100));
  std::vector<DisplayInfo> display_info_list;

  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);

  // software mirroring.
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(external_display_info);
  display_manager->OnNativeDisplaysChanged(display_info_list);
  const int64_t internal_display_id =
      test::DisplayManagerTestApi().SetFirstDisplayAsInternalDisplay();
  EXPECT_EQ(internal_id, internal_display_id);

  EXPECT_EQ(1U, display_manager->GetNumDisplays());
  EXPECT_TRUE(display_manager->IsInMirrorMode());
  EXPECT_EQ(external_id, display_manager->mirroring_display_id());

  // dock mode.
  display_info_list.clear();
  display_info_list.push_back(external_display_info);
  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
  display_manager->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager->GetNumDisplays());
  EXPECT_FALSE(display_manager->IsInMirrorMode());

  // back to software mirroring.
  display_info_list.clear();
  display_info_list.push_back(internal_display_info);
  display_info_list.push_back(external_display_info);
  display_manager->SetMultiDisplayMode(DisplayManager::MIRRORING);
  display_manager->OnNativeDisplaysChanged(display_info_list);
  EXPECT_EQ(1U, display_manager->GetNumDisplays());
  EXPECT_TRUE(display_manager->IsInMirrorMode());
  EXPECT_EQ(external_id, display_manager->mirroring_display_id());
}

TEST_F(MirrorOnBootTest, MAYBE_MirrorOnBoot) {
  DisplayManager* display_manager = Shell::GetInstance()->display_manager();
  EXPECT_TRUE(display_manager->IsInMirrorMode());
  RunAllPendingInMessageLoop();
  test::MirrorWindowTestApi test_api;
  EXPECT_TRUE(test_api.GetHost());
}

}  // namespace ash
