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

#include "ash/test/ash_test_base.h"
#include "ash/wm/window_state.h"
#include "ui/aura/window.h"
#include "ui/wm/core/window_util.h"

namespace ash {

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

  // Creates a test set of windows parented like a linked list. The result
  // vector will have window in order: ABCD.
  void CreateTestLinkedList(
      std::vector<std::unique_ptr<aura::Window>>* out_result) {
    ASSERT_TRUE(out_result->empty());
    for (char c : {'A', 'B', 'C', 'D'}) {
      auto window = CreateTestWindow();
      window->SetName(std::string(1, c));
      if (!out_result->empty())
        ::wm::AddTransientChild(out_result->back().get(), window.get());
      out_result->push_back(std::move(window));
    }
  }

  //          A
  //         /  \
  //        B    F
  //       /  \
  //      C    E
  //     /
  //    D
  // Creates a test set of windows parented like in the diagram above. The
  // result vector will have the windows in preorder: ABCDEF.
  void CreateTestInOrderTree(
      std::vector<std::unique_ptr<aura::Window>>* out_result) {
    ASSERT_TRUE(out_result->empty());
    auto window_a = CreateTestWindow();
    auto window_b = CreateTestWindow();
    auto window_c = CreateTestWindow();
    auto window_d = CreateTestWindow();
    auto window_e = CreateTestWindow();
    auto window_f = CreateTestWindow();

    window_a->SetName("A");
    window_b->SetName("B");
    window_c->SetName("C");
    window_d->SetName("D");
    window_e->SetName("E");
    window_f->SetName("F");

    // Create the tree structure.
    ::wm::AddTransientChild(window_a.get(), window_b.get());
    ::wm::AddTransientChild(window_a.get(), window_f.get());
    ::wm::AddTransientChild(window_b.get(), window_c.get());
    ::wm::AddTransientChild(window_b.get(), window_e.get());
    ::wm::AddTransientChild(window_c.get(), window_d.get());

    // Insert windows in preorder traversal: ABCDEF.
    out_result->push_back(std::move(window_a));
    out_result->push_back(std::move(window_b));
    out_result->push_back(std::move(window_c));
    out_result->push_back(std::move(window_d));
    out_result->push_back(std::move(window_e));
    out_result->push_back(std::move(window_f));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(WindowTransientDescendantIteratorTest);
};

// Tests that case that windows a parented transiently like a linked list.
TEST_F(WindowTransientDescendantIteratorTest, LinkedList) {
  std::vector<std::unique_ptr<aura::Window>> windows;
  CreateTestLinkedList(&windows);

  int index = 0;
  std::string str;
  for (auto* window : wm::GetTransientTreeIterator(windows[0].get())) {
    EXPECT_EQ(windows[index].get(), window);
    str += window->GetName();
    ++index;
  }
  EXPECT_EQ("ABCD", str);
}

// Tests that case that windows a parented transiently like a tree. The iterator
// should go through the windows with preorder traversal.
TEST_F(WindowTransientDescendantIteratorTest, Tree) {
  std::vector<std::unique_ptr<aura::Window>> windows;
  CreateTestInOrderTree(&windows);

  // The windows in |window| are added with preorder traversal, so they should
  // match exactly the window order from the transient iterator.
  int index = 0;
  std::string str;
  for (auto* window : wm::GetTransientTreeIterator(windows[0].get())) {
    EXPECT_EQ(windows[index].get(), window);
    str += window->GetName();
    ++index;
  }
  EXPECT_EQ("ABCDEF", str);
}

// Tests that windows that affected by a given predicate do not show up when
// iterating.
TEST_F(WindowTransientDescendantIteratorTest, LinkedListWithPredicate) {
  std::vector<std::unique_ptr<aura::Window>> windows;
  CreateTestLinkedList(&windows);

  auto predicate = [](aura::Window* w) { return w->GetName() == "C"; };

  std::string str;
  for (auto* window : wm::GetTransientTreeIterator(
           windows[0].get(), base::BindRepeating(predicate))) {
    str += window->GetName();
  }
  EXPECT_EQ("ABD", str);
}

TEST_F(WindowTransientDescendantIteratorTest, TreeWithPredicate) {
  std::vector<std::unique_ptr<aura::Window>> windows;
  CreateTestInOrderTree(&windows);

  auto predicate = [](aura::Window* w) {
    return w->GetName() == "B" || w->GetName() == "E";
  };

  std::string str;
  for (auto* window : wm::GetTransientTreeIterator(
           windows[0].get(), base::BindRepeating(predicate))) {
    str += window->GetName();
  }
  EXPECT_EQ("ACDF", str);
}

}  // namespace ash
