// Copyright 2019 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/autotest_private_api_utils.h"

#include "ash/app_list/app_list_controller_impl.h"
#include "ash/app_list/app_list_presenter_impl.h"
#include "ash/frame/non_client_frame_view_ash.h"
#include "ash/shell.h"
#include "ash/wm/mru_window_tracker.h"
#include "ash/wm/tablet_mode/scoped_skip_user_session_blocked_check.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/scoped_observation.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animator.h"

namespace ash {
namespace {

class HomeLauncherStateWaiter {
 public:
  HomeLauncherStateWaiter(bool target_shown, base::OnceClosure closure)
      : target_shown_(target_shown), closure_(std::move(closure)) {
    Shell::Get()
        ->app_list_controller()
        ->SetHomeLauncherAnimationCallbackForTesting(base::BindRepeating(
            &HomeLauncherStateWaiter::OnHomeLauncherAnimationCompleted,
            base::Unretained(this)));
  }

  HomeLauncherStateWaiter(const HomeLauncherStateWaiter&) = delete;
  HomeLauncherStateWaiter& operator=(const HomeLauncherStateWaiter&) = delete;

  ~HomeLauncherStateWaiter() {
    Shell::Get()
        ->app_list_controller()
        ->SetHomeLauncherAnimationCallbackForTesting(base::NullCallback());
  }

 private:
  // Passed to AppListControllerImpl as a callback to run when home launcher
  // transition animation is complete.
  void OnHomeLauncherAnimationCompleted(bool shown) {
    if (shown == target_shown_) {
      std::move(closure_).Run();
      delete this;
    }
  }

  bool target_shown_;
  base::OnceClosure closure_;
};

// A waiter that waits until the animation ended with the target state, and
// execute the callback.  This self destruction upon completion.
class LauncherStateWaiter {
 public:
  LauncherStateWaiter(ash::AppListViewState state, base::OnceClosure closure)
      : target_state_(state), closure_(std::move(closure)) {
    Shell::Get()
        ->app_list_controller()
        ->SetStateTransitionAnimationCallbackForTesting(base::BindRepeating(
            &LauncherStateWaiter::OnStateChanged, base::Unretained(this)));
  }

  LauncherStateWaiter(const LauncherStateWaiter&) = delete;
  LauncherStateWaiter& operator=(const LauncherStateWaiter&) = delete;

  ~LauncherStateWaiter() {
    Shell::Get()
        ->app_list_controller()
        ->SetStateTransitionAnimationCallbackForTesting(base::NullCallback());
  }

  void OnStateChanged(ash::AppListViewState state) {
    if (target_state_ == state) {
      std::move(closure_).Run();
      delete this;
    }
  }

 private:
  ash::AppListViewState target_state_;
  base::OnceClosure closure_;
};

class LauncherAnimationWaiter : public ui::LayerAnimationObserver {
 public:
  LauncherAnimationWaiter(AppListView* view, base::OnceClosure closure)
      : closure_(std::move(closure)) {
    observation_.Observe(view->GetWidget()->GetLayer()->GetAnimator());
  }
  ~LauncherAnimationWaiter() override = default;
  LauncherAnimationWaiter(const LauncherAnimationWaiter&) = delete;
  LauncherAnimationWaiter& operator=(const LauncherAnimationWaiter&) = delete;

 private:
  // ui::LayerAnimationObserver:
  void OnLayerAnimationEnded(ui::LayerAnimationSequence* sequence) override {
    std::move(closure_).Run();
    delete this;
  }
  void OnLayerAnimationAborted(ui::LayerAnimationSequence* sequence) override {
    OnLayerAnimationEnded(sequence);
  }
  void OnLayerAnimationScheduled(
      ui::LayerAnimationSequence* sequence) override {}

  base::OnceClosure closure_;
  base::ScopedObservation<ui::LayerAnimator, ui::LayerAnimationObserver>
      observation_{this};
};

bool WaitForHomeLauncherState(bool target_visible, base::OnceClosure closure) {
  if (Shell::Get()->app_list_controller()->IsVisible(
          /*display_id=*/absl::nullopt) == target_visible) {
    std::move(closure).Run();
    return true;
  }

  new HomeLauncherStateWaiter(target_visible, std::move(closure));
  return false;
}

bool WaitForLauncherAnimation(base::OnceClosure closure) {
  auto* app_list_view =
      Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
  if (!app_list_view) {
    std::move(closure).Run();
    return true;
  }
  bool animating =
      app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
  if (!animating) {
    std::move(closure).Run();
    return true;
  }
  new LauncherAnimationWaiter(app_list_view, std::move(closure));
  return false;
}

}  // namespace

std::vector<aura::Window*> GetAppWindowList() {
  ScopedSkipUserSessionBlockedCheck skip_session_blocked;
  return Shell::Get()->mru_window_tracker()->BuildAppWindowList(kAllDesks);
}

bool WaitForLauncherState(AppListViewState target_state,
                          base::OnceClosure closure) {
  const bool in_tablet_mode =
      Shell::Get()->tablet_mode_controller()->InTabletMode();
  if (in_tablet_mode) {
    // App-list can't enter kPeeking or kHalf state in tablet mode. Thus
    // |target_state| should be either kClosed, kFullscreenAllApps or
    // kFullscreenSearch.
    DCHECK(target_state == AppListViewState::kClosed ||
           target_state == AppListViewState::kFullscreenAllApps ||
           target_state == AppListViewState::kFullscreenSearch);
  }

  // In the tablet mode, home launcher visibility state needs special handling,
  // as app list view visibility does not match home launcher visibility. The
  // app list view is always visible, but the home launcher may be obscured by
  // app windows. The waiter interprets waits for kClosed state as waits
  // "home launcher not visible" state - note that the app list view
  // is actually expected to be in a visible state.
  AppListViewState effective_target_state =
      in_tablet_mode && target_state == AppListViewState::kClosed
          ? AppListViewState::kFullscreenAllApps
          : target_state;

  absl::optional<bool> target_home_launcher_visibility;
  if (in_tablet_mode)
    target_home_launcher_visibility = target_state != AppListViewState::kClosed;

  // Don't wait if the launcher is already in the target state and not
  // animating.
  auto* app_list_view =
      Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView();
  bool animating =
      app_list_view &&
      app_list_view->GetWidget()->GetLayer()->GetAnimator()->is_animating();
  bool at_target_state =
      (!app_list_view && effective_target_state == AppListViewState::kClosed) ||
      (app_list_view &&
       app_list_view->app_list_state() == effective_target_state);

  if (at_target_state && !animating) {
    // In tablet mode, ensure that the home launcher is in the expected state.
    if (target_home_launcher_visibility.has_value()) {
      return WaitForHomeLauncherState(*target_home_launcher_visibility,
                                      std::move(closure));
    }
    std::move(closure).Run();
    return true;
  }

  // In tablet mode, ensure that the home launcher is in the expected state.
  base::OnceClosure callback =
      target_home_launcher_visibility.has_value()
          ? base::BindOnce(base::IgnoreResult(&WaitForHomeLauncherState),
                           *target_home_launcher_visibility, std::move(closure))
          : std::move(closure);
  if (at_target_state)
    return WaitForLauncherAnimation(std::move(callback));
  new LauncherStateWaiter(
      target_state,
      base::BindOnce(base::IgnoreResult(&WaitForLauncherAnimation),
                     std::move(callback)));
  return false;
}

}  // namespace ash
