// Copyright (c) 2012 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 "base/string16.h"
#include "base/utf_string_conversions.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/common/accessibility_messages.h"
#include "content/common/accessibility_node_data.h"
#include "testing/gtest/include/gtest/gtest.h"

using content::AccessibilityNodeData;

namespace {

// Subclass of BrowserAccessibility that counts the number of instances.
class CountedBrowserAccessibility : public BrowserAccessibility {
 public:
  CountedBrowserAccessibility() {
    global_obj_count_++;
    native_ref_count_ = 1;
  }
  virtual ~CountedBrowserAccessibility() {
    global_obj_count_--;
  }

  virtual void NativeAddReference() OVERRIDE {
    native_ref_count_++;
  }

  virtual void NativeReleaseReference() OVERRIDE {
    native_ref_count_--;
    if (native_ref_count_ == 0)
      delete this;
  }

  int native_ref_count_;
  static int global_obj_count_;
};

int CountedBrowserAccessibility::global_obj_count_ = 0;

// Factory that creates a CountedBrowserAccessibility.
class CountedBrowserAccessibilityFactory
    : public BrowserAccessibilityFactory {
 public:
  virtual ~CountedBrowserAccessibilityFactory() {}
  virtual BrowserAccessibility* Create() {
    return new CountedBrowserAccessibility();
  }
};

}  // anonymous namespace

TEST(BrowserAccessibilityManagerTest, TestNoLeaks) {
  // Create AccessibilityNodeData objects for a simple document tree,
  // representing the accessibility information used to initialize
  // BrowserAccessibilityManager.
  AccessibilityNodeData button;
  button.id = 2;
  button.name = UTF8ToUTF16("Button");
  button.role = AccessibilityNodeData::ROLE_BUTTON;
  button.state = 0;

  AccessibilityNodeData checkbox;
  checkbox.id = 3;
  checkbox.name = UTF8ToUTF16("Checkbox");
  checkbox.role = AccessibilityNodeData::ROLE_CHECKBOX;
  checkbox.state = 0;

  AccessibilityNodeData root;
  root.id = 1;
  root.name = UTF8ToUTF16("Document");
  root.role = AccessibilityNodeData::ROLE_DOCUMENT;
  root.state = 0;
  root.children.push_back(button);
  root.children.push_back(checkbox);

  // Construct a BrowserAccessibilityManager with this
  // AccessibilityNodeData tree and a factory for an instance-counting
  // BrowserAccessibility, and ensure that exactly 3 instances were
  // created. Note that the manager takes ownership of the factory.
  CountedBrowserAccessibility::global_obj_count_ = 0;
  BrowserAccessibilityManager* manager =
      BrowserAccessibilityManager::Create(
          NULL,
          root,
          NULL,
          new CountedBrowserAccessibilityFactory());

  ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);

  // Delete the manager and test that all 3 instances are deleted.
  delete manager;
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);

  // Construct a manager again, and this time save references to two of
  // the three nodes in the tree.
  manager =
      BrowserAccessibilityManager::Create(
          NULL,
          root,
          NULL,
          new CountedBrowserAccessibilityFactory());
  ASSERT_EQ(3, CountedBrowserAccessibility::global_obj_count_);

  CountedBrowserAccessibility* root_accessible =
      static_cast<CountedBrowserAccessibility*>(manager->GetRoot());
  root_accessible->NativeAddReference();
  CountedBrowserAccessibility* child1_accessible =
      static_cast<CountedBrowserAccessibility*>(root_accessible->GetChild(1));
  child1_accessible->NativeAddReference();

  // Now delete the manager, and only one of the three nodes in the tree
  // should be released.
  delete manager;
  ASSERT_EQ(2, CountedBrowserAccessibility::global_obj_count_);

  // Release each of our references and make sure that each one results in
  // the instance being deleted as its reference count hits zero.
  root_accessible->NativeReleaseReference();
  ASSERT_EQ(1, CountedBrowserAccessibility::global_obj_count_);
  child1_accessible->NativeReleaseReference();
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}

TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects) {
  // Make sure that changes to a subtree reuse as many objects as possible.

  // Tree 1:
  //
  // root
  //   child1
  //   child2
  //   child3

  AccessibilityNodeData tree1_child1;
  tree1_child1.id = 2;
  tree1_child1.name = UTF8ToUTF16("Child1");
  tree1_child1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child1.state = 0;

  AccessibilityNodeData tree1_child2;
  tree1_child2.id = 3;
  tree1_child2.name = UTF8ToUTF16("Child2");
  tree1_child2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child2.state = 0;

  AccessibilityNodeData tree1_child3;
  tree1_child3.id = 4;
  tree1_child3.name = UTF8ToUTF16("Child3");
  tree1_child3.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child3.state = 0;

  AccessibilityNodeData tree1_root;
  tree1_root.id = 1;
  tree1_root.name = UTF8ToUTF16("Document");
  tree1_root.role = AccessibilityNodeData::ROLE_DOCUMENT;
  tree1_root.state = 0;
  tree1_root.children.push_back(tree1_child1);
  tree1_root.children.push_back(tree1_child2);
  tree1_root.children.push_back(tree1_child3);

  // Tree 2:
  //
  // root
  //   child0  <-- inserted
  //   child1
  //   child2
  //           <-- child3 deleted

  AccessibilityNodeData tree2_child0;
  tree2_child0.id = 5;
  tree2_child0.name = UTF8ToUTF16("Child0");
  tree2_child0.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child0.state = 0;

  AccessibilityNodeData tree2_child1;
  tree2_child1.id = 2;
  tree2_child1.name = UTF8ToUTF16("Child1");
  tree2_child1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child1.state = 0;

  AccessibilityNodeData tree2_child2;
  tree2_child2.id = 3;
  tree2_child2.name = UTF8ToUTF16("Child2");
  tree2_child2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child2.state = 0;

  AccessibilityNodeData tree2_root;
  tree2_root.id = 1;
  tree2_root.name = UTF8ToUTF16("DocumentChanged");
  tree2_root.role = AccessibilityNodeData::ROLE_DOCUMENT;
  tree2_root.state = 0;
  tree2_root.children.push_back(tree2_child0);
  tree2_root.children.push_back(tree2_child1);
  tree2_root.children.push_back(tree2_child2);

  // Construct a BrowserAccessibilityManager with tree1.
  CountedBrowserAccessibility::global_obj_count_ = 0;
  BrowserAccessibilityManager* manager =
      BrowserAccessibilityManager::Create(
          NULL,
          tree1_root,
          NULL,
          new CountedBrowserAccessibilityFactory());
  ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);

  // Save references to all of the objects.
  CountedBrowserAccessibility* root_accessible =
      static_cast<CountedBrowserAccessibility*>(manager->GetRoot());
  root_accessible->NativeAddReference();
  CountedBrowserAccessibility* child1_accessible =
      static_cast<CountedBrowserAccessibility*>(root_accessible->GetChild(0));
  child1_accessible->NativeAddReference();
  CountedBrowserAccessibility* child2_accessible =
      static_cast<CountedBrowserAccessibility*>(root_accessible->GetChild(1));
  child2_accessible->NativeAddReference();
  CountedBrowserAccessibility* child3_accessible =
      static_cast<CountedBrowserAccessibility*>(root_accessible->GetChild(2));
  child3_accessible->NativeAddReference();

  // Check the index in parent.
  EXPECT_EQ(0, child1_accessible->index_in_parent());
  EXPECT_EQ(1, child2_accessible->index_in_parent());
  EXPECT_EQ(2, child3_accessible->index_in_parent());

  // Process a notification containing the changed subtree.
  std::vector<AccessibilityHostMsg_NotificationParams> params;
  params.push_back(AccessibilityHostMsg_NotificationParams());
  AccessibilityHostMsg_NotificationParams* msg = &params[0];
  msg->notification_type = AccessibilityNotificationChildrenChanged;
  msg->acc_tree = tree2_root;
  msg->includes_children = true;
  msg->id = tree2_root.id;
  manager->OnAccessibilityNotifications(params);

  // There should be 5 objects now: the 4 from the new tree, plus the
  // reference to child3 we kept.
  EXPECT_EQ(5, CountedBrowserAccessibility::global_obj_count_);

  // Check that our references to the root, child1, and child2 are still valid,
  // but that the reference to child3 is now invalid.
  EXPECT_TRUE(root_accessible->instance_active());
  EXPECT_TRUE(child1_accessible->instance_active());
  EXPECT_TRUE(child2_accessible->instance_active());
  EXPECT_FALSE(child3_accessible->instance_active());

  // Check that the index in parent has been updated.
  EXPECT_EQ(1, child1_accessible->index_in_parent());
  EXPECT_EQ(2, child2_accessible->index_in_parent());

  // Release our references. The object count should only decrease by 1
  // for child3.
  root_accessible->NativeReleaseReference();
  child1_accessible->NativeReleaseReference();
  child2_accessible->NativeReleaseReference();
  child3_accessible->NativeReleaseReference();

  EXPECT_EQ(4, CountedBrowserAccessibility::global_obj_count_);

  // Delete the manager and make sure all memory is cleaned up.
  delete manager;
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}

TEST(BrowserAccessibilityManagerTest, TestReuseBrowserAccessibilityObjects2) {
  // Similar to the test above, but with a more complicated tree.

  // Tree 1:
  //
  // root
  //   container
  //     child1
  //       grandchild1
  //     child2
  //       grandchild2
  //     child3
  //       grandchild3

  AccessibilityNodeData tree1_grandchild1;
  tree1_grandchild1.id = 4;
  tree1_grandchild1.name = UTF8ToUTF16("GrandChild1");
  tree1_grandchild1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_grandchild1.state = 0;

  AccessibilityNodeData tree1_child1;
  tree1_child1.id = 3;
  tree1_child1.name = UTF8ToUTF16("Child1");
  tree1_child1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child1.state = 0;
  tree1_child1.children.push_back(tree1_grandchild1);

  AccessibilityNodeData tree1_grandchild2;
  tree1_grandchild2.id = 6;
  tree1_grandchild2.name = UTF8ToUTF16("GrandChild1");
  tree1_grandchild2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_grandchild2.state = 0;

  AccessibilityNodeData tree1_child2;
  tree1_child2.id = 5;
  tree1_child2.name = UTF8ToUTF16("Child2");
  tree1_child2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child2.state = 0;
  tree1_child2.children.push_back(tree1_grandchild2);

  AccessibilityNodeData tree1_grandchild3;
  tree1_grandchild3.id = 8;
  tree1_grandchild3.name = UTF8ToUTF16("GrandChild3");
  tree1_grandchild3.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_grandchild3.state = 0;

  AccessibilityNodeData tree1_child3;
  tree1_child3.id = 7;
  tree1_child3.name = UTF8ToUTF16("Child3");
  tree1_child3.role = AccessibilityNodeData::ROLE_BUTTON;
  tree1_child3.state = 0;
  tree1_child3.children.push_back(tree1_grandchild3);

  AccessibilityNodeData tree1_container;
  tree1_container.id = 2;
  tree1_container.name = UTF8ToUTF16("Container");
  tree1_container.role = AccessibilityNodeData::ROLE_GROUP;
  tree1_container.state = 0;
  tree1_container.children.push_back(tree1_child1);
  tree1_container.children.push_back(tree1_child2);
  tree1_container.children.push_back(tree1_child3);

  AccessibilityNodeData tree1_root;
  tree1_root.id = 1;
  tree1_root.name = UTF8ToUTF16("Document");
  tree1_root.role = AccessibilityNodeData::ROLE_DOCUMENT;
  tree1_root.state = 0;
  tree1_root.children.push_back(tree1_container);

  // Tree 2:
  //
  // root
  //   container
  //     child0         <-- inserted
  //       grandchild0  <--
  //     child1
  //       grandchild1
  //     child2
  //       grandchild2
  //                    <-- child3 (and grandchild3) deleted

  AccessibilityNodeData tree2_grandchild0;
  tree2_grandchild0.id = 9;
  tree2_grandchild0.name = UTF8ToUTF16("GrandChild0");
  tree2_grandchild0.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_grandchild0.state = 0;

  AccessibilityNodeData tree2_child0;
  tree2_child0.id = 10;
  tree2_child0.name = UTF8ToUTF16("Child0");
  tree2_child0.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child0.state = 0;
  tree2_child0.children.push_back(tree2_grandchild0);

  AccessibilityNodeData tree2_grandchild1;
  tree2_grandchild1.id = 4;
  tree2_grandchild1.name = UTF8ToUTF16("GrandChild1");
  tree2_grandchild1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_grandchild1.state = 0;

  AccessibilityNodeData tree2_child1;
  tree2_child1.id = 3;
  tree2_child1.name = UTF8ToUTF16("Child1");
  tree2_child1.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child1.state = 0;
  tree2_child1.children.push_back(tree2_grandchild1);

  AccessibilityNodeData tree2_grandchild2;
  tree2_grandchild2.id = 6;
  tree2_grandchild2.name = UTF8ToUTF16("GrandChild1");
  tree2_grandchild2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_grandchild2.state = 0;

  AccessibilityNodeData tree2_child2;
  tree2_child2.id = 5;
  tree2_child2.name = UTF8ToUTF16("Child2");
  tree2_child2.role = AccessibilityNodeData::ROLE_BUTTON;
  tree2_child2.state = 0;
  tree2_child2.children.push_back(tree2_grandchild2);

  AccessibilityNodeData tree2_container;
  tree2_container.id = 2;
  tree2_container.name = UTF8ToUTF16("Container");
  tree2_container.role = AccessibilityNodeData::ROLE_GROUP;
  tree2_container.state = 0;
  tree2_container.children.push_back(tree2_child0);
  tree2_container.children.push_back(tree2_child1);
  tree2_container.children.push_back(tree2_child2);

  AccessibilityNodeData tree2_root;
  tree2_root.id = 1;
  tree2_root.name = UTF8ToUTF16("Document");
  tree2_root.role = AccessibilityNodeData::ROLE_DOCUMENT;
  tree2_root.state = 0;
  tree2_root.children.push_back(tree2_container);

  // Construct a BrowserAccessibilityManager with tree1.
  CountedBrowserAccessibility::global_obj_count_ = 0;
  BrowserAccessibilityManager* manager =
      BrowserAccessibilityManager::Create(
          NULL,
          tree1_root,
          NULL,
          new CountedBrowserAccessibilityFactory());
  ASSERT_EQ(8, CountedBrowserAccessibility::global_obj_count_);

  // Save references to some objects.
  CountedBrowserAccessibility* root_accessible =
      static_cast<CountedBrowserAccessibility*>(manager->GetRoot());
  root_accessible->NativeAddReference();
  CountedBrowserAccessibility* container_accessible =
      static_cast<CountedBrowserAccessibility*>(root_accessible->GetChild(0));
  container_accessible->NativeAddReference();
  CountedBrowserAccessibility* child2_accessible =
      static_cast<CountedBrowserAccessibility*>(
          container_accessible->GetChild(1));
  child2_accessible->NativeAddReference();
  CountedBrowserAccessibility* child3_accessible =
      static_cast<CountedBrowserAccessibility*>(
          container_accessible->GetChild(2));
  child3_accessible->NativeAddReference();

  // Check the index in parent.
  EXPECT_EQ(1, child2_accessible->index_in_parent());
  EXPECT_EQ(2, child3_accessible->index_in_parent());

  // Process a notification containing the changed subtree rooted at
  // the container.
  std::vector<AccessibilityHostMsg_NotificationParams> params;
  params.push_back(AccessibilityHostMsg_NotificationParams());
  AccessibilityHostMsg_NotificationParams* msg = &params[0];
  msg->notification_type = AccessibilityNotificationChildrenChanged;
  msg->acc_tree = tree2_container;
  msg->includes_children = true;
  msg->id = tree2_container.id;
  manager->OnAccessibilityNotifications(params);

  // There should be 9 objects now: the 8 from the new tree, plus the
  // reference to child3 we kept.
  EXPECT_EQ(9, CountedBrowserAccessibility::global_obj_count_);

  // Check that our references to the root and container and child2 are
  // still valid, but that the reference to child3 is now invalid.
  EXPECT_TRUE(root_accessible->instance_active());
  EXPECT_TRUE(container_accessible->instance_active());
  EXPECT_TRUE(child2_accessible->instance_active());
  EXPECT_FALSE(child3_accessible->instance_active());

  // Ensure that we retain the parent of the detached subtree.
  EXPECT_EQ(root_accessible, container_accessible->parent());
  EXPECT_EQ(0, container_accessible->index_in_parent());

  // Check that the index in parent has been updated.
  EXPECT_EQ(2, child2_accessible->index_in_parent());

  // Release our references. The object count should only decrease by 1
  // for child3.
  root_accessible->NativeReleaseReference();
  container_accessible->NativeReleaseReference();
  child2_accessible->NativeReleaseReference();
  child3_accessible->NativeReleaseReference();

  EXPECT_EQ(8, CountedBrowserAccessibility::global_obj_count_);

  // Delete the manager and make sure all memory is cleaned up.
  delete manager;
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}

TEST(BrowserAccessibilityManagerTest, TestMoveChildUp) {
  // Tree 1:
  //
  // 1
  //   2
  //   3
  //     4

  AccessibilityNodeData tree1_4;
  tree1_4.id = 4;
  tree1_4.state = 0;

  AccessibilityNodeData tree1_3;
  tree1_3.id = 3;
  tree1_3.state = 0;
  tree1_3.children.push_back(tree1_4);

  AccessibilityNodeData tree1_2;
  tree1_2.id = 2;
  tree1_2.state = 0;

  AccessibilityNodeData tree1_1;
  tree1_1.id = 1;
  tree1_1.state = 0;
  tree1_1.children.push_back(tree1_2);
  tree1_1.children.push_back(tree1_3);

  // Tree 2:
  //
  // 1
  //   4    <-- moves up a level and gains child
  //     6  <-- new
  //   5    <-- new

  AccessibilityNodeData tree2_6;
  tree2_6.id = 6;
  tree2_6.state = 0;

  AccessibilityNodeData tree2_5;
  tree2_5.id = 5;
  tree2_5.state = 0;

  AccessibilityNodeData tree2_4;
  tree2_4.id = 4;
  tree2_4.state = 0;
  tree2_4.children.push_back(tree2_6);

  AccessibilityNodeData tree2_1;
  tree2_1.id = 1;
  tree2_1.state = 0;
  tree2_1.children.push_back(tree2_4);
  tree2_1.children.push_back(tree2_5);

  // Construct a BrowserAccessibilityManager with tree1.
  CountedBrowserAccessibility::global_obj_count_ = 0;
  BrowserAccessibilityManager* manager =
      BrowserAccessibilityManager::Create(
          NULL,
          tree1_1,
          NULL,
          new CountedBrowserAccessibilityFactory());
  ASSERT_EQ(4, CountedBrowserAccessibility::global_obj_count_);

  // Process a notification containing the changed subtree.
  std::vector<AccessibilityHostMsg_NotificationParams> params;
  params.push_back(AccessibilityHostMsg_NotificationParams());
  AccessibilityHostMsg_NotificationParams* msg = &params[0];
  msg->notification_type = AccessibilityNotificationChildrenChanged;
  msg->acc_tree = tree2_1;
  msg->includes_children = true;
  msg->id = tree2_1.id;
  manager->OnAccessibilityNotifications(params);

  // There should be 4 objects now.
  EXPECT_EQ(4, CountedBrowserAccessibility::global_obj_count_);

  // Delete the manager and make sure all memory is cleaned up.
  delete manager;
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}

TEST(BrowserAccessibilityManagerTest, TestCreateEmptyDocument) {
  // Try creating an empty document with busy state. Readonly is
  // set automatically.
  const int32 busy_state = 1 << AccessibilityNodeData::STATE_BUSY;
  const int32 readonly_state = 1 << AccessibilityNodeData::STATE_READONLY;
  scoped_ptr<BrowserAccessibilityManager> manager;
  manager.reset(BrowserAccessibilityManager::CreateEmptyDocument(
      NULL,
      static_cast<AccessibilityNodeData::State>(busy_state),
      NULL,
      new CountedBrowserAccessibilityFactory()));

  // Verify the root is as we expect by default.
  BrowserAccessibility* root = manager->GetRoot();
  EXPECT_EQ(0, root->renderer_id());
  EXPECT_EQ(AccessibilityNodeData::ROLE_ROOT_WEB_AREA, root->role());
  EXPECT_EQ(busy_state | readonly_state, root->state());

  // Tree with a child textfield.
  AccessibilityNodeData tree1_1;
  tree1_1.id = 1;
  tree1_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;

  AccessibilityNodeData tree1_2;
  tree1_2.id = 2;
  tree1_2.role = AccessibilityNodeData::ROLE_TEXT_FIELD;

  tree1_1.children.push_back(tree1_2);

  // Process a load complete.
  std::vector<AccessibilityHostMsg_NotificationParams> params;
  params.push_back(AccessibilityHostMsg_NotificationParams());
  AccessibilityHostMsg_NotificationParams* msg = &params[0];
  msg->notification_type = AccessibilityNotificationLoadComplete;
  msg->acc_tree = tree1_1;
  msg->includes_children = true;
  msg->id = tree1_1.id;
  manager->OnAccessibilityNotifications(params);

  // Save for later comparison.
  BrowserAccessibility* acc1_2 = manager->GetFromRendererID(2);

  // Verify the root has changed.
  EXPECT_NE(root, manager->GetRoot());

  // And the proper child remains.
  EXPECT_EQ(AccessibilityNodeData::ROLE_TEXT_FIELD, acc1_2->role());
  EXPECT_EQ(2, acc1_2->renderer_id());

  // Tree with a child button.
  AccessibilityNodeData tree2_1;
  tree2_1.id = 1;
  tree2_1.role = AccessibilityNodeData::ROLE_ROOT_WEB_AREA;

  AccessibilityNodeData tree2_2;
  tree2_2.id = 3;
  tree2_2.role = AccessibilityNodeData::ROLE_BUTTON;

  tree2_1.children.push_back(tree2_2);

  msg->acc_tree = tree2_1;
  msg->includes_children = true;
  msg->id = tree2_1.id;

  // Fire another load complete.
  manager->OnAccessibilityNotifications(params);

  BrowserAccessibility* acc2_2 = manager->GetFromRendererID(3);

  // Verify the root has changed.
  EXPECT_NE(root, manager->GetRoot());

  // And the new child exists.
  EXPECT_EQ(AccessibilityNodeData::ROLE_BUTTON, acc2_2->role());
  EXPECT_EQ(3, acc2_2->renderer_id());

  // Ensure we properly cleaned up.
  manager.reset();
  ASSERT_EQ(0, CountedBrowserAccessibility::global_obj_count_);
}
