// 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 "ui/app_list/app_list_item_list.h"

#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/app_list/app_list_folder_item.h"
#include "ui/app_list/app_list_item.h"
#include "ui/app_list/app_list_item_list_observer.h"

namespace app_list {

namespace {

class TestObserver : public AppListItemListObserver {
 public:
  TestObserver() : items_added_(0), items_removed_(0), items_moved_(0) {}

  virtual ~TestObserver() {
  }

  // AppListItemListObserver overriden:
  virtual void OnListItemAdded(size_t index, AppListItem* item) OVERRIDE {
    ++items_added_;
  }

  virtual void OnListItemRemoved(size_t index, AppListItem* item) OVERRIDE {
    ++items_removed_;
  }

  virtual void OnListItemMoved(size_t from_index,
                               size_t to_index,
                               AppListItem* item) OVERRIDE {
    ++items_moved_;
  }

  size_t items_added() const { return items_added_; }
  size_t items_removed() const { return items_removed_; }
  size_t items_moved() const { return items_moved_; }

  void ResetCounts() {
    items_added_ = 0;
    items_removed_ = 0;
    items_moved_ = 0;
  }

 private:
  size_t items_added_;
  size_t items_removed_;
  size_t items_moved_;

  DISALLOW_COPY_AND_ASSIGN(TestObserver);
};

std::string GetItemId(int id) {
  return base::StringPrintf("Item %d", id);
}

}  // namespace

class AppListItemListTest : public testing::Test {
 public:
  AppListItemListTest() {}
  virtual ~AppListItemListTest() {}

  // testing::Test overrides:
  virtual void SetUp() OVERRIDE {
    item_list_.AddObserver(&observer_);
  }

  virtual void TearDown() OVERRIDE {
    item_list_.RemoveObserver(&observer_);
  }

 protected:
  AppListItem* FindItem(const std::string& id) {
    return item_list_.FindItem(id);
  }

  bool FindItemIndex(const std::string& id, size_t* index) {
    return item_list_.FindItemIndex(id, index);
  }

  scoped_ptr<AppListItem> CreateItem(const std::string& name) {
    scoped_ptr<AppListItem> item(new AppListItem(name));
    size_t nitems = item_list_.item_count();
    syncer::StringOrdinal position;
    if (nitems == 0)
      position = syncer::StringOrdinal::CreateInitialOrdinal();
    else
      position = item_list_.item_at(nitems - 1)->position().CreateAfter();
    item->set_position(position);
    return item.Pass();
  }

  AppListItem* CreateAndAddItem(const std::string& name) {
    scoped_ptr<AppListItem> item(CreateItem(name));
    return item_list_.AddItem(item.Pass());
  }

  scoped_ptr<AppListItem> RemoveItem(const std::string& id) {
    return item_list_.RemoveItem(id);
  }

  scoped_ptr<AppListItem> RemoveItemAt(size_t index) {
    return item_list_.RemoveItemAt(index);
  }

  syncer::StringOrdinal CreatePositionBefore(
      const syncer::StringOrdinal& position) {
    return item_list_.CreatePositionBefore(position);
  }

  bool VerifyItemListOrdinals() {
    bool res = true;
    for (size_t i = 1; i < item_list_.item_count(); ++i) {
      res &= (item_list_.item_at(i - 1)->position().LessThan(
          item_list_.item_at(i)->position()));
    }
    if (!res)
      PrintItems();
    return res;
  }

  bool VerifyItemOrder4(size_t a, size_t b, size_t c, size_t d) {
    if ((GetItemId(a) == item_list_.item_at(0)->id()) &&
        (GetItemId(b) == item_list_.item_at(1)->id()) &&
        (GetItemId(c) == item_list_.item_at(2)->id()) &&
        (GetItemId(d) == item_list_.item_at(3)->id()))
      return true;
    PrintItems();
    return false;
  }

  void PrintItems() {
    VLOG(1) << "ITEMS:";
    for (size_t i = 0; i < item_list_.item_count(); ++i)
      VLOG(1) << " " << item_list_.item_at(i)->ToDebugString();
  }

  AppListItemList item_list_;
  TestObserver observer_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AppListItemListTest);
};

TEST_F(AppListItemListTest, FindItemIndex) {
  AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
  AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
  AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
  EXPECT_EQ(observer_.items_added(), 3u);
  EXPECT_EQ(item_list_.item_count(), 3u);
  EXPECT_EQ(item_0, item_list_.item_at(0));
  EXPECT_EQ(item_1, item_list_.item_at(1));
  EXPECT_EQ(item_2, item_list_.item_at(2));
  EXPECT_TRUE(VerifyItemListOrdinals());

  size_t index;
  EXPECT_TRUE(FindItemIndex(item_0->id(), &index));
  EXPECT_EQ(index, 0u);
  EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
  EXPECT_EQ(index, 1u);
  EXPECT_TRUE(FindItemIndex(item_2->id(), &index));
  EXPECT_EQ(index, 2u);

  scoped_ptr<AppListItem> item_3(CreateItem(GetItemId(3)));
  EXPECT_FALSE(FindItemIndex(item_3->id(), &index));
}

TEST_F(AppListItemListTest, RemoveItemAt) {
  AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
  AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
  AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
  EXPECT_EQ(item_list_.item_count(), 3u);
  EXPECT_EQ(observer_.items_added(), 3u);
  size_t index;
  EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
  EXPECT_EQ(index, 1u);
  EXPECT_TRUE(VerifyItemListOrdinals());

  scoped_ptr<AppListItem> item_removed = RemoveItemAt(1);
  EXPECT_EQ(item_removed, item_1);
  EXPECT_FALSE(FindItem(item_1->id()));
  EXPECT_EQ(item_list_.item_count(), 2u);
  EXPECT_EQ(observer_.items_removed(), 1u);
  EXPECT_EQ(item_list_.item_at(0), item_0);
  EXPECT_EQ(item_list_.item_at(1), item_2);
  EXPECT_TRUE(VerifyItemListOrdinals());
}

TEST_F(AppListItemListTest, RemoveItem) {
  AppListItem* item_0 = CreateAndAddItem(GetItemId(0));
  AppListItem* item_1 = CreateAndAddItem(GetItemId(1));
  AppListItem* item_2 = CreateAndAddItem(GetItemId(2));
  EXPECT_EQ(item_list_.item_count(), 3u);
  EXPECT_EQ(observer_.items_added(), 3u);
  EXPECT_EQ(item_0, item_list_.item_at(0));
  EXPECT_EQ(item_1, item_list_.item_at(1));
  EXPECT_EQ(item_2, item_list_.item_at(2));
  EXPECT_TRUE(VerifyItemListOrdinals());

  size_t index;
  EXPECT_TRUE(FindItemIndex(item_1->id(), &index));
  EXPECT_EQ(index, 1u);

  scoped_ptr<AppListItem> item_removed = RemoveItem(item_1->id());
  EXPECT_EQ(item_removed, item_1);
  EXPECT_FALSE(FindItem(item_1->id()));
  EXPECT_EQ(item_list_.item_count(), 2u);
  EXPECT_EQ(observer_.items_removed(), 1u);
  EXPECT_TRUE(VerifyItemListOrdinals());

  scoped_ptr<AppListItem> not_found_item = RemoveItem("Bogus");
  EXPECT_FALSE(not_found_item.get());
}

TEST_F(AppListItemListTest, MoveItem) {
  CreateAndAddItem(GetItemId(0));
  CreateAndAddItem(GetItemId(1));
  CreateAndAddItem(GetItemId(2));
  CreateAndAddItem(GetItemId(3));

  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));

  item_list_.MoveItem(0, 0);
  EXPECT_EQ(0u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));

  item_list_.MoveItem(0, 1);
  EXPECT_EQ(1u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));

  item_list_.MoveItem(1, 2);
  EXPECT_EQ(2u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));

  item_list_.MoveItem(2, 1);
  EXPECT_EQ(3u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));

  item_list_.MoveItem(3, 0);
  EXPECT_EQ(4u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(3, 1, 0, 2));

  item_list_.MoveItem(0, 3);
  EXPECT_EQ(5u, observer_.items_moved());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
}

TEST_F(AppListItemListTest, SamePosition) {
  CreateAndAddItem(GetItemId(0));
  CreateAndAddItem(GetItemId(1));
  CreateAndAddItem(GetItemId(2));
  CreateAndAddItem(GetItemId(3));
  item_list_.SetItemPosition(item_list_.item_at(2),
                             item_list_.item_at(1)->position());
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
  EXPECT_TRUE(item_list_.item_at(1)->position().Equals(
      item_list_.item_at(2)->position()));
  // Moving an item to position 1 should fix the position.
  observer_.ResetCounts();
  item_list_.MoveItem(0, 1);
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
  EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
      item_list_.item_at(1)->position()));
  EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
      item_list_.item_at(2)->position()));
  EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
      item_list_.item_at(3)->position()));
  // One extra move notification for fixed position.
  EXPECT_EQ(2u, observer_.items_moved());

  // Restore the original order.
  item_list_.MoveItem(1, 0);
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));

  // Set all four items to the same position.
  item_list_.SetItemPosition(item_list_.item_at(1),
                             item_list_.item_at(0)->position());
  item_list_.SetItemPosition(item_list_.item_at(2),
                             item_list_.item_at(0)->position());
  item_list_.SetItemPosition(item_list_.item_at(3),
                             item_list_.item_at(0)->position());
  // Move should fix the position of the items.
  observer_.ResetCounts();
  item_list_.MoveItem(0, 1);
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
  EXPECT_TRUE(item_list_.item_at(0)->position().LessThan(
      item_list_.item_at(1)->position()));
  EXPECT_TRUE(item_list_.item_at(1)->position().LessThan(
      item_list_.item_at(2)->position()));
  EXPECT_TRUE(item_list_.item_at(2)->position().LessThan(
      item_list_.item_at(3)->position()));
  // One extra move notification for fixed position.
  EXPECT_EQ(2u, observer_.items_moved());
}

TEST_F(AppListItemListTest, CreatePositionBefore) {
  CreateAndAddItem(GetItemId(0));
  syncer::StringOrdinal position0 = item_list_.item_at(0)->position();
  syncer::StringOrdinal new_position;
  new_position = CreatePositionBefore(position0.CreateBefore());
  EXPECT_TRUE(new_position.LessThan(position0));
  new_position = CreatePositionBefore(position0);
  EXPECT_TRUE(new_position.LessThan(position0));
  new_position = CreatePositionBefore(position0.CreateAfter());
  EXPECT_TRUE(new_position.GreaterThan(position0));

  CreateAndAddItem(GetItemId(1));
  syncer::StringOrdinal position1 = item_list_.item_at(1)->position();
  EXPECT_TRUE(position1.GreaterThan(position0));
  new_position = CreatePositionBefore(position1);
  EXPECT_TRUE(new_position.GreaterThan(position0));
  EXPECT_TRUE(new_position.LessThan(position1));

  // Invalid ordinal should return a position at the end of the list.
  new_position = CreatePositionBefore(syncer::StringOrdinal());
  EXPECT_TRUE(new_position.GreaterThan(position1));
}

TEST_F(AppListItemListTest, SetItemPosition) {
  CreateAndAddItem(GetItemId(0));
  CreateAndAddItem(GetItemId(1));
  CreateAndAddItem(GetItemId(2));
  CreateAndAddItem(GetItemId(3));
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));

  // No change to position.
  item_list_.SetItemPosition(item_list_.item_at(0),
                             item_list_.item_at(0)->position());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
  // No order change.
  item_list_.SetItemPosition(item_list_.item_at(0),
                             item_list_.item_at(0)->position().CreateBetween(
                                 item_list_.item_at(1)->position()));
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(0, 1, 2, 3));
  // 0 -> 1
  item_list_.SetItemPosition(item_list_.item_at(0),
                             item_list_.item_at(1)->position().CreateBetween(
                                 item_list_.item_at(2)->position()));
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 0, 2, 3));
  // 1 -> 2
  item_list_.SetItemPosition(item_list_.item_at(1),
                             item_list_.item_at(2)->position().CreateBetween(
                                 item_list_.item_at(3)->position()));
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(1, 2, 0, 3));
  // 0 -> last
  item_list_.SetItemPosition(item_list_.item_at(0),
                             item_list_.item_at(3)->position().CreateAfter());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
  // last -> last
  item_list_.SetItemPosition(item_list_.item_at(3),
                             item_list_.item_at(3)->position().CreateAfter());
  EXPECT_TRUE(VerifyItemListOrdinals());
  EXPECT_TRUE(VerifyItemOrder4(2, 0, 3, 1));
}

}  // namespace app_list
