// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/display/display_alignment_controller.h"

#include <algorithm>

#include "ash/constants/ash_features.h"
#include "ash/display/display_alignment_indicator.h"
#include "ash/display/window_tree_host_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "base/timer/mock_timer.h"
#include "ui/display/display_layout_builder.h"
#include "ui/display/manager/display_layout_store.h"
#include "ui/display/manager/display_manager.h"
#include "ui/display/test/display_manager_test_api.h"
#include "ui/views/widget/widget.h"

namespace ash {

namespace {

enum class EdgeType { kTop, kRight, kBottom, kLeft };

DisplayAlignmentController* display_alignment_controller() {
  return Shell::Get()->display_alignment_controller();
}

void TriggerIndicator(const display::Display& display, EdgeType edge) {
  WindowTreeHostManager* window_tree_host_manager =
      Shell::Get()->window_tree_host_manager();
  aura::Window* primary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(display.id());

  ui::test::EventGenerator primary_generator(primary_root);

  const gfx::Rect display_bounds = primary_root->GetBoundsInRootWindow();

  gfx::Point point_on_edge;
  if (edge == EdgeType::kTop)
    point_on_edge = display_bounds.top_center();
  else if (edge == EdgeType::kRight)
    point_on_edge = display_bounds.right_center();
  else if (edge == EdgeType::kBottom)
    point_on_edge = display_bounds.bottom_center();
  else
    point_on_edge = display_bounds.left_center();

  primary_generator.MoveMouseToInHost(point_on_edge);
  primary_generator.MoveMouseToInHost(display_bounds.CenterPoint());
  primary_generator.MoveMouseToInHost(point_on_edge);
}

}  // namespace

class DisplayAlignmentControllerTest : public AshTestBase {
 public:
  DisplayAlignmentControllerTest() = default;
  ~DisplayAlignmentControllerTest() override = default;

 protected:
  void LockScreen() { GetSessionControllerClient()->LockScreen(); }
  void UnlockScreen() { GetSessionControllerClient()->UnlockScreen(); }

  // AshTestBase:
  void SetUp() override {
    scoped_feature_list_.InitAndEnableFeature(features::kDisplayAlignAssist);

    AshTestBase::SetUp();

    std::unique_ptr<base::MockOneShotTimer> mock_timer =
        std::make_unique<base::MockOneShotTimer>();

    mock_timer_ptr_ = mock_timer.get();

    display_alignment_controller()->SetTimerForTesting(std::move(mock_timer));
  }

  void DragDisplay(int64_t id, int32_t delta_x, int32_t delta_y) {
    display_alignment_controller()->DisplayDragged(id, delta_x, delta_y);
  }

  bool NoIndicatorsExist() {
    return display_alignment_controller()
        ->GetActiveIndicatorsForTesting()
        .empty();
  }

  void CheckIndicatorShown(size_t num_indicators,
                           const display::Display& src_display) {
    const auto& active_indicators =
        display_alignment_controller()->GetActiveIndicatorsForTesting();

    WindowTreeHostManager* window_tree_host_manager =
        Shell::Get()->window_tree_host_manager();
    aura::Window* primary_root =
        window_tree_host_manager->GetRootWindowForDisplayId(src_display.id());

    EXPECT_EQ(num_indicators, active_indicators.size());

    for (const auto& indicator : active_indicators) {
      ASSERT_TRUE(indicator);

      EXPECT_TRUE(indicator->indicator_widget_.IsVisible());

      aura::Window* current_root =
          indicator->indicator_widget_.GetNativeWindow()->GetRootWindow();
      if (current_root == primary_root) {
        ASSERT_TRUE(indicator->pill_widget_);
        EXPECT_TRUE(indicator->pill_widget_->IsVisible());
      } else {
        EXPECT_FALSE(indicator->pill_widget_);
      }
    }
  }

  void CheckPreviewIndicatorShown(int64_t dragged_display_id,
                                  int64_t target_display_id,
                                  bool is_visible) {
    ASSERT_EQ(dragged_display_id,
              display_alignment_controller()->GetDraggedDisplayIdForTesting());

    const auto& active_indicators_ =
        display_alignment_controller()->GetActiveIndicatorsForTesting();

    const auto& iter =
        std::ranges::find(active_indicators_, target_display_id,
                          &DisplayAlignmentIndicator::display_id);

    if (iter == active_indicators_.end()) {
      EXPECT_FALSE(is_visible);
      return;
    }

    DisplayAlignmentIndicator* indicator = iter->get();
    ASSERT_TRUE(indicator);

    const views::Widget& indicator_widget = indicator->indicator_widget_;

    if (!is_visible) {
      EXPECT_FALSE(indicator_widget.IsVisible());
      return;
    }

    EXPECT_EQ(Shell::GetRootWindowForDisplayId(target_display_id),
              indicator_widget.GetNativeWindow()->GetRootWindow());
    EXPECT_TRUE(indicator_widget.IsVisible());
  }

  raw_ptr<base::MockOneShotTimer, DanglingUntriaged> mock_timer_ptr_ = nullptr;

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_F(DisplayAlignmentControllerTest, SingleDisplayNoIndicators) {
  UpdateDisplay("1920x1080");

  EXPECT_TRUE(NoIndicatorsExist());
}

TEST_F(DisplayAlignmentControllerTest, TriggerIndicatorPrimary) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& display = display_manager()->GetDisplayAt(0);

  aura::Window* root_window =
      Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
          display.id());

  ui::test::EventGenerator generator(root_window);

  // Move mouse on to an edge.
  generator.MoveMouseToInHost(gfx::Point(0, 0));
  EXPECT_TRUE(NoIndicatorsExist());

  // Move mouse off the edge.
  generator.MoveMouseToInHost(gfx::Point(20, 50));
  EXPECT_TRUE(NoIndicatorsExist());

  // Move mouse on to an edge for the second time.
  generator.MoveMouseToInHost(gfx::Point(0, 0));

  CheckIndicatorShown(2, display);

  // Finish displaying indicators.
  mock_timer_ptr_->Fire();
  EXPECT_TRUE(NoIndicatorsExist());
}

TEST_F(DisplayAlignmentControllerTest, RetriggerIndicatorPrimary) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& display = display_manager()->GetDisplayAt(0);

  EXPECT_TRUE(NoIndicatorsExist());

  TriggerIndicator(display, EdgeType::kTop);

  CheckIndicatorShown(2, display);

  // Finish displaying indicators.
  mock_timer_ptr_->Fire();

  EXPECT_TRUE(NoIndicatorsExist());

  // Re-trigger indicators.
  TriggerIndicator(display, EdgeType::kTop);

  CheckIndicatorShown(2, display);
}

TEST_F(DisplayAlignmentControllerTest, OnlyTriggerNeighboringIndicators) {
  UpdateDisplay("1920x1080,1366x768,800x600");

  const auto& display = display_manager()->GetDisplayAt(0);

  TriggerIndicator(display, EdgeType::kTop);

  CheckIndicatorShown(2, display);
}

TEST_F(DisplayAlignmentControllerTest, TriggerSecondaryDisplay) {
  UpdateDisplay("1920x1080,1366x768,800x600");

  const auto& display = display_manager()->GetDisplayAt(1);

  TriggerIndicator(display, EdgeType::kTop);

  CheckIndicatorShown(4, display);
}

TEST_F(DisplayAlignmentControllerTest, TriggerTwoDisplayOnSameEdge) {
  //
  //    +---------+---------+
  //    |    1    |    2    |
  //    |         |         |
  //    |         |         |
  //    |         |         |
  //    +-+-------+---------+-+
  //      |         P         |
  //      |                   |
  //      |                   |
  //      |                   |
  //      +-------------------+
  //

  int64_t primary_id = display::Screen::Get()->GetPrimaryDisplay().id();
  display::DisplayIdList list =
      display::test::CreateDisplayIdListN(primary_id, 3);
  display::DisplayLayoutBuilder builder(primary_id);
  builder.AddDisplayPlacement(list[1], primary_id,
                              display::DisplayPlacement::TOP, -110);
  builder.AddDisplayPlacement(list[2], primary_id,
                              display::DisplayPlacement::TOP, 490);
  display_manager()->layout_store()->RegisterLayoutForDisplayIdList(
      list, builder.Build());

  UpdateDisplay("1200x500,600x500,600x500");

  const auto& display = display_manager()->GetDisplayAt(1);

  TriggerIndicator(display, EdgeType::kTop);

  CheckIndicatorShown(4, display);
}

TEST_F(DisplayAlignmentControllerTest, DontTriggerIndicator) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& display = display_manager()->GetDisplayAt(0);

  aura::Window* root_window =
      Shell::Get()->window_tree_host_manager()->GetRootWindowForDisplayId(
          display.id());

  ui::test::EventGenerator generator(root_window);

  // Move the mouse on to the edge once.
  generator.MoveMouseToInHost(gfx::Point(0, 0));
  generator.MoveMouseToInHost(gfx::Point(20, 50));

  EXPECT_TRUE(NoIndicatorsExist());
  mock_timer_ptr_->Fire();
  EXPECT_TRUE(NoIndicatorsExist());
}

TEST_F(DisplayAlignmentControllerTest, DontTriggerIndicatorDifferentDisplays) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);
  const auto& secondary_display = display_manager()->GetDisplayAt(1);

  WindowTreeHostManager* window_tree_host_manager =
      Shell::Get()->window_tree_host_manager();

  aura::Window* primary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(primary_display.id());
  aura::Window* secondary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(
          secondary_display.id());

  ui::test::EventGenerator primary_generator(primary_root);
  ui::test::EventGenerator secondary_generator(secondary_root);

  // Simulate hitting the edge of the first display.
  primary_generator.MoveMouseToInHost(gfx::Point(0, 0));
  primary_generator.MoveMouseToInHost(gfx::Point(20, 20));

  // Hitting the edge of the second display should not trigger alignment
  // indicators.
  secondary_generator.MoveMouseToInHost(gfx::Point(1365, 0));

  EXPECT_TRUE(NoIndicatorsExist());
}

TEST_F(DisplayAlignmentControllerTest, RemoveDisplay) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);

  TriggerIndicator(primary_display, EdgeType::kLeft);

  CheckIndicatorShown(2, primary_display);

  UpdateDisplay("1920x1080");

  EXPECT_TRUE(NoIndicatorsExist());

  TriggerIndicator(primary_display, EdgeType::kTop);

  EXPECT_TRUE(NoIndicatorsExist());
}

TEST_F(DisplayAlignmentControllerTest, LockScreen) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);

  TriggerIndicator(primary_display, EdgeType::kBottom);

  CheckIndicatorShown(2, primary_display);

  LockScreen();

  EXPECT_TRUE(NoIndicatorsExist());

  TriggerIndicator(primary_display, EdgeType::kTop);

  EXPECT_TRUE(NoIndicatorsExist());

  UnlockScreen();

  TriggerIndicator(primary_display, EdgeType::kTop);

  CheckIndicatorShown(2, primary_display);
}

TEST_F(DisplayAlignmentControllerTest, ChangeResolution) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);

  TriggerIndicator(primary_display, EdgeType::kTop);

  CheckIndicatorShown(2, primary_display);

  UpdateDisplay("2560x1440,1366x768");

  // Resolution change immediately hides the indicator.
  EXPECT_TRUE(NoIndicatorsExist());

  TriggerIndicator(primary_display, EdgeType::kRight);

  CheckIndicatorShown(2, primary_display);
}

TEST_F(DisplayAlignmentControllerTest, AllowOffByOnes) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);

  WindowTreeHostManager* window_tree_host_manager =
      Shell::Get()->window_tree_host_manager();

  aura::Window* primary_root =
      window_tree_host_manager->GetRootWindowForDisplayId(primary_display.id());

  ui::test::EventGenerator primary_generator(primary_root);

  // (1, 1) is one off of both top and left edge.
  primary_generator.MoveMouseToInHost(gfx::Point(1, 1));
  primary_generator.MoveMouseToInHost(gfx::Point(20, 20));
  primary_generator.MoveMouseToInHost(gfx::Point(1, 1));

  CheckIndicatorShown(2, primary_display);
}

TEST_F(DisplayAlignmentControllerTest, DragDisplayBasic) {
  UpdateDisplay("1920x1080,1366x768");
  const auto& primary_display = display_manager()->GetDisplayAt(0);
  const auto& secondary_display = display_manager()->GetDisplayAt(1);

  DragDisplay(primary_display.id(), 0, 0);

  CheckPreviewIndicatorShown(primary_display.id(), secondary_display.id(),
                             /*is_visible=*/true);

  UpdateDisplay("1920x1080,1366x768");
  EXPECT_TRUE(NoIndicatorsExist());
}

// When drag display starts, all existing indicators should be replaced.
TEST_F(DisplayAlignmentControllerTest, DragDisplayReplaceExistingIndicators) {
  UpdateDisplay("1920x1080,1366x768");

  const auto& primary_display = display_manager()->GetDisplayAt(0);
  const auto& secondary_display = display_manager()->GetDisplayAt(1);

  TriggerIndicator(primary_display, EdgeType::kLeft);

  CheckIndicatorShown(2, primary_display);

  DragDisplay(primary_display.id(), 0, 10);

  CheckPreviewIndicatorShown(primary_display.id(), secondary_display.id(),
                             /*is_visible=*/true);
}

TEST_F(DisplayAlignmentControllerTest, DragDisplayHideOldNeighbors) {
  UpdateDisplay("1920x1080,1366x768");
  const auto& primary_display = display_manager()->GetDisplayAt(0);
  const auto& secondary_display = display_manager()->GetDisplayAt(1);

  DragDisplay(primary_display.id(), 0, 0);

  // Move the primary display so that the two are no longer neighbors
  DragDisplay(primary_display.id(), -2000, -2000);

  CheckPreviewIndicatorShown(primary_display.id(), secondary_display.id(),
                             /*is_visible=*/false);
}

TEST_F(DisplayAlignmentControllerTest, DragDisplayNewNeighbor) {
  UpdateDisplay("1000x900,1000x900,1000x100");
  const auto& display_1 = display_manager()->GetDisplayAt(0);
  const auto& display_2 = display_manager()->GetDisplayAt(1);
  const auto& display_3 = display_manager()->GetDisplayAt(2);

  DragDisplay(display_1.id(), 0, 0);

  // Move the primary display so that the other two are no longer neighbors
  DragDisplay(display_1.id(), 3000, 0);

  CheckPreviewIndicatorShown(display_1.id(), display_2.id(),
                             /*is_visible=*/false);

  CheckPreviewIndicatorShown(display_1.id(), display_3.id(),
                             /*is_visible=*/true);
}
}  // namespace ash
