// Copyright 2017 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/shelf/back_button.h"

#include <memory>

#include "ash/accelerators/accelerator_controller_impl.h"
#include "ash/app_list/test/app_list_test_helper.h"
#include "ash/app_list/views/app_list_view.h"
#include "ash/kiosk_next/kiosk_next_shell_test_util.h"
#include "ash/kiosk_next/mock_kiosk_next_shell_client.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_view.h"
#include "ash/shelf/shelf_view_test_api.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/test_accelerator_target.h"
#include "ui/events/test/event_generator.h"

namespace ash {

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

  BackButton* back_button() { return test_api_->shelf_view()->GetBackButton(); }
  ShelfViewTestAPI* test_api() { return test_api_.get(); }

  void SetUp() override {
    AshTestBase::SetUp();
    test_api_ = std::make_unique<ShelfViewTestAPI>(
        GetPrimaryShelf()->GetShelfViewForTesting());

    // Finish all setup tasks. In particular we want to finish the
    // GetSwitchStates post task in (Fake)PowerManagerClient which is triggered
    // by TabletModeController otherwise this will cause tablet mode to exit
    // while we wait for animations in the test.
    base::RunLoop().RunUntilIdle();
  }

 protected:
  std::unique_ptr<ShelfViewTestAPI> test_api_;

  DISALLOW_COPY_AND_ASSIGN(BackButtonTest);
};

// Verify that the back button is visible in tablet mode.
TEST_F(BackButtonTest, Visibility) {
  ASSERT_TRUE(back_button()->layer());
  EXPECT_EQ(0.f, back_button()->layer()->opacity());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  test_api()->RunMessageLoopUntilAnimationsDone();
  EXPECT_EQ(1.f, back_button()->layer()->opacity());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  test_api()->RunMessageLoopUntilAnimationsDone();
  EXPECT_EQ(0.f, back_button()->layer()->opacity());
}

// Verify that the back button is visible in tablet mode, if the initial shelf
// alignment is on the left or right.
TEST_F(BackButtonTest, VisibilityWithVerticalShelf) {
  test_api()->shelf_view()->shelf()->SetAlignment(SHELF_ALIGNMENT_LEFT);
  ASSERT_TRUE(back_button()->layer());
  EXPECT_EQ(0.f, back_button()->layer()->opacity());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  test_api()->RunMessageLoopUntilAnimationsDone();
  EXPECT_EQ(1.f, back_button()->layer()->opacity());

  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(false);
  test_api()->RunMessageLoopUntilAnimationsDone();
  EXPECT_EQ(0.f, back_button()->layer()->opacity());
}

TEST_F(BackButtonTest, BackKeySequenceGenerated) {
  // Enter tablet mode; the back button is not visible in non tablet mode.
  Shell::Get()->tablet_mode_controller()->EnableTabletModeWindowManager(true);
  test_api()->RunMessageLoopUntilAnimationsDone();

  AcceleratorControllerImpl* controller =
      Shell::Get()->accelerator_controller();

  // Register an accelerator that looks for back presses. Note there is already
  // an accelerator on AppListView, which will handle the accelerator since it
  // is targeted before AcceleratorController (switching to tablet mode with no
  // other windows activates the app list). First remove that accelerator. In
  // release, there's only the AppList's accelerator, so it's always hit when
  // the app list is active. (ash/accelerators.cc has VKEY_BROWSER_BACK, but it
  // also needs Ctrl pressed).
  GetAppListTestHelper()->GetAppListView()->ResetAccelerators();

  ui::Accelerator accelerator_back_press(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
  accelerator_back_press.set_key_state(ui::Accelerator::KeyState::PRESSED);
  ui::TestAcceleratorTarget target_back_press;
  controller->Register({accelerator_back_press}, &target_back_press);

  // Register an accelerator that looks for back releases.
  ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
  accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED);
  ui::TestAcceleratorTarget target_back_release;
  controller->Register({accelerator_back_release}, &target_back_release);

  // Verify that by pressing the back button no event is generated on the press,
  // but there is one generated on the release.
  ui::test::EventGenerator* generator = GetEventGenerator();
  generator->MoveMouseTo(back_button()->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  EXPECT_EQ(0, target_back_press.accelerator_count());
  EXPECT_EQ(0, target_back_release.accelerator_count());

  generator->ReleaseLeftButton();
  EXPECT_EQ(1, target_back_press.accelerator_count());
  EXPECT_EQ(1, target_back_release.accelerator_count());
}

class KioskNextBackButtonTest : public BackButtonTest {
 public:
  KioskNextBackButtonTest() {
    scoped_feature_list_.InitAndEnableFeature(features::kKioskNextShell);
  }

  void SetUp() override {
    set_start_session(false);
    BackButtonTest::SetUp();
    client_ = BindMockKioskNextShellClient();
  }

  void SimulateKioskNextSession() {
    LogInKioskNextUser(GetSessionControllerClient());

    // Update test_api_ because its reference to ShelfView is outdated.
    test_api_ = std::make_unique<ShelfViewTestAPI>(
        GetPrimaryShelf()->GetShelfViewForTesting());
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
  std::unique_ptr<MockKioskNextShellClient> client_;

  DISALLOW_COPY_AND_ASSIGN(KioskNextBackButtonTest);
};

TEST_F(KioskNextBackButtonTest, BackKeySequenceGenerated) {
  SimulateKioskNextSession();

  // Tablet mode should be enabled in Kiosk Next.
  ASSERT_TRUE(Shell::Get()
                  ->tablet_mode_controller()
                  ->IsTabletModeWindowManagerEnabled());
  test_api()->RunMessageLoopUntilAnimationsDone();

  // Enter Overview mode, since the shelf view is hidden from the Kiosk Next
  // home screen.
  OverviewController* overview_controller = Shell::Get()->overview_controller();
  ASSERT_TRUE(overview_controller->ToggleOverview());
  ASSERT_TRUE(overview_controller->InOverviewSession());
  test_api()->RunMessageLoopUntilAnimationsDone();

  // Register an accelerator that looks for back releases.
  ui::Accelerator accelerator_back_release(ui::VKEY_BROWSER_BACK, ui::EF_NONE);
  accelerator_back_release.set_key_state(ui::Accelerator::KeyState::RELEASED);
  ui::TestAcceleratorTarget target_back_release;
  Shell::Get()->accelerator_controller()->Register({accelerator_back_release},
                                                   &target_back_release);

  // Verify that when pressing down the back button, the accelerator is not
  // triggered yet.
  ui::test::EventGenerator* generator = GetEventGenerator();
  generator->MoveMouseTo(back_button()->GetBoundsInScreen().CenterPoint());
  generator->PressLeftButton();
  EXPECT_EQ(0, target_back_release.accelerator_count());
  EXPECT_TRUE(overview_controller->InOverviewSession());

  // Verify that by releasing the back button, the accelerator is triggered,
  // exiting Overview mode and sending a release event.
  generator->ReleaseLeftButton();
  EXPECT_EQ(1, target_back_release.accelerator_count());
  EXPECT_FALSE(overview_controller->InOverviewSession());
}

}  // namespace ash
