// 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/shelf/shelf_navigator.h"

#include "ash/ash_switches.h"
#include "ash/launcher/launcher.h"
#include "ash/launcher/launcher_model.h"
#include "ash/launcher/launcher_types.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash {

namespace {

class LauncherNavigatorTest : public testing::Test {
 public:
  LauncherNavigatorTest() {}

 protected:
  virtual void SetUp() OVERRIDE {
    model_.reset(new LauncherModel);

    // Add APP_LIST for test.
    LauncherItem app_list;
    app_list.type = TYPE_APP_LIST;
    model_->Add(app_list);

    // Initially, applist launcher item is only created.
    int total_num = model_->item_count();
    EXPECT_EQ(1, total_num);
    EXPECT_TRUE(model_->items()[0].type == TYPE_APP_LIST);

    // Add BROWSER_SHORTCUT for test.
    LauncherItem browser_shortcut;
    browser_shortcut.type = TYPE_BROWSER_SHORTCUT;
    model_->Add(browser_shortcut);
  }

  void SetupMockLauncherModel(LauncherItemType* types,
                              int types_length,
                              int focused_index) {
    for (int i = 0; i < types_length; ++i) {
      LauncherItem new_item;
      new_item.type = types[i];
      new_item.status =
          (types[i] == TYPE_PLATFORM_APP) ? STATUS_RUNNING : STATUS_CLOSED;
      model_->Add(new_item);
    }

    // Set the focused item.
    if (focused_index >= 0) {
      LauncherItem focused_item =model_->items()[focused_index];
      if (focused_item.type == TYPE_PLATFORM_APP) {
        focused_item.status = STATUS_ACTIVE;
        model_->Set(focused_index, focused_item);
      }
    }
  }

  const LauncherModel& model() { return *model_.get(); }

 private:
  scoped_ptr<LauncherModel> model_;

  DISALLOW_COPY_AND_ASSIGN(LauncherNavigatorTest);
};

class LauncherNavigatorLegacyShelfLayoutTest : public LauncherNavigatorTest {
 public:
  LauncherNavigatorLegacyShelfLayoutTest() : LauncherNavigatorTest() {}

 protected:
  virtual void SetUp() OVERRIDE {
    CommandLine::ForCurrentProcess()->AppendSwitch(
      ash::switches::kAshDisableAlternateShelfLayout);
    LauncherNavigatorTest::SetUp();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(LauncherNavigatorLegacyShelfLayoutTest);
};

}  // namespace

TEST_F(LauncherNavigatorTest, BasicCycle) {
  // An app shortcut and three platform apps.
  LauncherItemType types[] = {
    TYPE_APP_SHORTCUT, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  // LauncherModel automatically adds BROWSER_SHORTCUT item at the
  // beginning, so '3' refers the first TYPE_PLATFORM_APP item.
  SetupMockLauncherModel(types, arraysize(types), 3);

  EXPECT_EQ(4, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));

  // Fourth one.  It will skip the APP_SHORTCUT at the beginning of the list and
  // the APP_LIST item which is automatically added at the end of items.
  EXPECT_EQ(5, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorLegacyShelfLayoutTest, BasicCycle) {
  // An app shortcut and three platform apps.
  LauncherItemType types[] = {
    TYPE_APP_SHORTCUT, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  // LauncherModel automatically adds BROWSER_SHORTCUT item at the
  // beginning, so '2' refers the first TYPE_PLATFORM_APP item.
  SetupMockLauncherModel(types, arraysize(types), 2);

  EXPECT_EQ(3, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));

  // Fourth one.  It will skip the APP_SHORTCUT at the beginning of the list and
  // the APP_LIST item which is automatically added at the end of items.
  EXPECT_EQ(4, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorTest, WrapToBeginning) {
  LauncherItemType types[] = {
    TYPE_APP_SHORTCUT, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  SetupMockLauncherModel(types, arraysize(types), 5);

  // Second one.  It skips the APP_LIST item at the end of the list,
  // wraps to the beginning, and skips BROWSER_SHORTCUT and APP_SHORTCUT
  // at the beginning of the list.
  EXPECT_EQ(3, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
}

TEST_F(LauncherNavigatorLegacyShelfLayoutTest, WrapToBeginning) {
  LauncherItemType types[] = {
    TYPE_APP_SHORTCUT, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  SetupMockLauncherModel(types, arraysize(types), 4);

  // Second one.  It skips the APP_LIST item at the end of the list,
  // wraps to the beginning, and skips BROWSER_SHORTCUT and APP_SHORTCUT
  // at the beginning of the list.
  EXPECT_EQ(2, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
}

TEST_F(LauncherNavigatorTest, Empty) {
  SetupMockLauncherModel(NULL, 0, -1);
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorTest, SingleEntry) {
  LauncherItemType type = TYPE_PLATFORM_APP;
  SetupMockLauncherModel(&type, 1, 2);

  // If there's only one item there and it is already active, there's no item
  // to be activated next.
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorLegacyShelfLayoutTest, SingleEntry) {
  LauncherItemType type = TYPE_PLATFORM_APP;
  SetupMockLauncherModel(&type, 1, 1);

  // If there's only one item there and it is already active, there's no item
  // to be activated next.
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
  EXPECT_EQ(-1, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorTest, NoActive) {
  LauncherItemType types[] = {
    TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  // Special case: no items are 'STATUS_ACTIVE'.
  SetupMockLauncherModel(types, arraysize(types), -1);

  // If there are no active status, pick the first running item as a fallback.
  EXPECT_EQ(2, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
  EXPECT_EQ(2, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

TEST_F(LauncherNavigatorLegacyShelfLayoutTest, NoActive) {
  LauncherItemType types[] = {
    TYPE_PLATFORM_APP, TYPE_PLATFORM_APP,
  };
  // Special case: no items are 'STATUS_ACTIVE'.
  SetupMockLauncherModel(types, arraysize(types), -1);

  // If there are no active status, pick the first running item as a fallback.
  EXPECT_EQ(1, GetNextActivatedItemIndex(model(), CYCLE_FORWARD));
  EXPECT_EQ(1, GetNextActivatedItemIndex(model(), CYCLE_BACKWARD));
}

}  // namespace ash
