// Copyright 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/wm/mru_window_tracker.h"

#include <algorithm>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/session/session_controller_impl.h"
#include "ash/shell.h"
#include "ash/wm/ash_focus_rules.h"
#include "ash/wm/switchable_windows.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/containers/adapters.h"
#include "base/stl_util.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"
#include "ui/wm/public/activation_delegate.h"

namespace ash {

namespace {

// A class that observes a window that should not be destroyed inside a certain
// scope. This class is added to investigate crbug.com/937381 to see if it's
// possible that a window is destroyed while building up the mru window list.
// TODO(crbug.com/937381): Remove this class once we figure out the reason.
class ScopedWindowClosingObserver : public aura::WindowObserver {
 public:
  explicit ScopedWindowClosingObserver(aura::Window* window) : window_(window) {
    window_->AddObserver(this);
  }
  ~ScopedWindowClosingObserver() override {
    window_->RemoveObserver(this);
    window_ = nullptr;
  }

  // aura::WindowObserver:
  void OnWindowDestroyed(aura::Window* window) override { CHECK(false); }

 private:
  aura::Window* window_;

  DISALLOW_COPY_AND_ASSIGN(ScopedWindowClosingObserver);
};

bool IsWindowConsideredActivatable(aura::Window* window) {
  DCHECK(window);
  ScopedWindowClosingObserver observer(window);
  AshFocusRules* focus_rules = Shell::Get()->focus_rules();

  // Only toplevel windows can be activated.
  if (!focus_rules->IsToplevelWindow(window))
    return false;

  if (!focus_rules->IsWindowConsideredVisibleForActivation(window))
    return false;

  if (::wm::GetActivationDelegate(window) &&
      !::wm::GetActivationDelegate(window)->ShouldActivate()) {
    return false;
  }

  return window->CanFocus();
}

// A predicate that determines whether |window| can be included in the MRU
// window list.
bool CanIncludeWindowInMruList(aura::Window* window) {
  return ::wm::CanActivateWindow(window) &&
         !wm::GetWindowState(window)->IsPip();
}

// A predicate that determines whether |window| can be included in the list
// built for cycling through windows (alt + tab).
bool CanIncludeWindowInCycleList(aura::Window* window) {
  return CanIncludeWindowInMruList(window) &&
         !wm::ShouldExcludeForCycleList(window);
}

// Returns a list of windows ordered by their stacking order such that the most
// recently used window is at the front of the list.
// If |mru_windows| is passed, these windows are moved to the front of the list.
// It uses the given |can_include_window_predicate| to determine whether to
// include a window in the returned list or not.
template <class CanIncludeWindowPredicate>
MruWindowTracker::WindowList BuildWindowListInternal(
    const std::vector<aura::Window*>* mru_windows,
    CanIncludeWindowPredicate can_include_window_predicate) {
  MruWindowTracker::WindowList windows;

  // Put the windows in the mru_windows list at the head, if it's available.
  if (mru_windows) {
    // The |mru_windows| are sorted such that the most recent window comes last,
    // hence iterate in reverse order.
    for (auto* window : base::Reversed(*mru_windows)) {
      // Exclude windows in non-switchable containers and those which should not
      // be included.
      if ((window->parent() && !wm::IsSwitchableContainer(window->parent())) ||
          !can_include_window_predicate(window)) {
        continue;
      }

      windows.emplace_back(window);
    }
  }

  auto roots = Shell::GetAllRootWindows();

  // Put the active root window last in |roots| so that when we iterate over the
  // root windows in reverse order below, the active root comes first. We do
  // this so that the top-most windows in the active root window will be added
  // first to |windows|.
  aura::Window* active_root = Shell::GetRootWindowForNewWindows();
  auto iter = std::find(roots.begin(), roots.end(), active_root);
  // When switching to/from Unified Mode, the active root window controller
  // might be in the process of shutting down, and its windows are being moved
  // to another root window before the root window for new windows is updated.
  // See WindowTreeHostManager::DeleteHost().
  if (iter != roots.end()) {
    roots.erase(iter);
    roots.emplace_back(active_root);
  }

  for (auto* root : base::Reversed(roots)) {
    // |wm::kSwitchableWindowContainerIds[]| contains a list of the container
    // IDs sorted such that the ID of the top-most container comes last. Hence,
    // we iterate in reverse order so the top-most windows are added first.
    const auto switachable_containers =
        wm::GetSwitchableContainersForRoot(root);
    for (auto* container : base::Reversed(switachable_containers)) {
      for (auto* child : base::Reversed(container->children())) {
        // Only add windows that the predicate allows.
        if (!can_include_window_predicate(child))
          continue;

        // Only add windows that have not been added previously from
        // |mru_windows| (if available).
        if (mru_windows && base::ContainsValue(*mru_windows, child))
          continue;

        windows.emplace_back(child);
      }
    }
  }

  return windows;
}

}  // namespace

//////////////////////////////////////////////////////////////////////////////
// MruWindowTracker, public:

MruWindowTracker::MruWindowTracker() {
  Shell::Get()->activation_client()->AddObserver(this);
}

MruWindowTracker::~MruWindowTracker() {
  Shell::Get()->activation_client()->RemoveObserver(this);
  for (auto* window : mru_windows_)
    window->RemoveObserver(this);
}

MruWindowTracker::WindowList MruWindowTracker::BuildMruWindowList() const {
  return BuildWindowListInternal(&mru_windows_, CanIncludeWindowInMruList);
}

MruWindowTracker::WindowList MruWindowTracker::BuildWindowListIgnoreModal()
    const {
  return BuildWindowListInternal(nullptr, IsWindowConsideredActivatable);
}

MruWindowTracker::WindowList MruWindowTracker::BuildWindowForCycleList() const {
  return BuildWindowListInternal(&mru_windows_, CanIncludeWindowInCycleList);
}

void MruWindowTracker::SetIgnoreActivations(bool ignore) {
  ignore_window_activations_ = ignore;

  // If no longer ignoring window activations, move currently active window
  // to front.
  if (!ignore)
    SetActiveWindow(wm::GetActiveWindow());
}

void MruWindowTracker::AddObserver(Observer* observer) {
  observers_.AddObserver(observer);
}

void MruWindowTracker::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

//////////////////////////////////////////////////////////////////////////////
// MruWindowTracker, private:

void MruWindowTracker::SetActiveWindow(aura::Window* active_window) {
  if (!active_window)
    return;

  auto iter =
      std::find(mru_windows_.begin(), mru_windows_.end(), active_window);
  // Observe all newly tracked windows.
  if (iter == mru_windows_.end())
    active_window->AddObserver(this);
  else
    mru_windows_.erase(iter);
  mru_windows_.emplace_back(active_window);
}

void MruWindowTracker::OnWindowActivated(ActivationReason reason,
                                         aura::Window* gained_active,
                                         aura::Window* lost_active) {
  if (!ignore_window_activations_)
    SetActiveWindow(gained_active);
}

void MruWindowTracker::OnWindowDestroyed(aura::Window* window) {
  // It's possible for OnWindowActivated() to be called after
  // OnWindowDestroying(). This means we need to override OnWindowDestroyed()
  // else we may end up with a deleted window in |mru_windows_|.
  base::Erase(mru_windows_, window);
  window->RemoveObserver(this);

  for (auto& observer : observers_)
    observer.OnWindowUntracked(window);
}

}  // namespace ash
