// 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 "ui/base/accelerators/accelerator_manager.h"

#include <map>

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator_manager_delegate.h"
#include "ui/events/event_constants.h"
#include "ui/events/keycodes/keyboard_codes.h"

namespace ui {
namespace test {

namespace {

class TestTarget : public AcceleratorTarget {
 public:
  TestTarget() : accelerator_pressed_count_(0) {}
  ~TestTarget() override {}

  int accelerator_pressed_count() const {
    return accelerator_pressed_count_;
  }

  void set_accelerator_pressed_count(int accelerator_pressed_count) {
    accelerator_pressed_count_ = accelerator_pressed_count;
  }

  // Overridden from AcceleratorTarget:
  bool AcceleratorPressed(const Accelerator& accelerator) override;
  bool CanHandleAccelerators() const override;

 private:
  int accelerator_pressed_count_;

  DISALLOW_COPY_AND_ASSIGN(TestTarget);
};

bool TestTarget::AcceleratorPressed(const Accelerator& accelerator) {
  ++accelerator_pressed_count_;
  return true;
}

bool TestTarget::CanHandleAccelerators() const {
  return true;
}

Accelerator GetAccelerator(KeyboardCode code, int mask) {
  return Accelerator(code, mask);
}

// Possible flags used for accelerators.
const int kAcceleratorModifiers[] = {EF_SHIFT_DOWN, EF_CONTROL_DOWN,
                                     EF_ALT_DOWN, EF_COMMAND_DOWN};

// Returns a set of flags from id, where id is a bitmask into
// kAcceleratorModifiers used to determine which flags are set.
int BuildAcceleratorModifier(int id) {
  int result = 0;
  for (size_t i = 0; i < arraysize(kAcceleratorModifiers); ++i) {
    if (((1 << i) & id) != 0)
      result |= kAcceleratorModifiers[i];
  }
  return result;
}

// AcceleratorManagerDelegate implementation that records calls to interface
// using the following format.
// . OnAcceleratorsRegistered() -> A list of "'Register ' + <id>" separated by
// whitespaces.
// . OnAcceleratorUnregistered() -> 'Unregister' + id
// where the id is specified using SetIdForAccelerator().
class TestAcceleratorManagerDelegate : public AcceleratorManagerDelegate {
 public:
  TestAcceleratorManagerDelegate() {}
  ~TestAcceleratorManagerDelegate() override {}

  void SetIdForAccelerator(const Accelerator& accelerator,
                           const std::string& id) {
    accelerator_to_id_[accelerator] = id;
  }

  std::string GetAndClearCommands() {
    std::string commands;
    std::swap(commands, commands_);
    return commands;
  }

  // AcceleratorManagerDelegate:
  void OnAcceleratorsRegistered(
      const std::vector<Accelerator>& accelerators) override {
    for (const Accelerator& accelerator : accelerators) {
      if (!commands_.empty())
        commands_ += " ";
      commands_ += "Register " + accelerator_to_id_[accelerator];
    }
  }
  void OnAcceleratorUnregistered(const Accelerator& accelerator) override {
    if (!commands_.empty())
      commands_ += " ";
    commands_ += "Unregister " + accelerator_to_id_[accelerator];
  }

 private:
  std::map<Accelerator, std::string> accelerator_to_id_;
  std::string commands_;

  DISALLOW_COPY_AND_ASSIGN(TestAcceleratorManagerDelegate);
};

}  // namespace

class AcceleratorManagerTest : public testing::Test {
 public:
  AcceleratorManagerTest() : manager_(&delegate_) {}
  ~AcceleratorManagerTest() override {}

 protected:
  TestAcceleratorManagerDelegate delegate_;
  AcceleratorManager manager_;
};

TEST_F(AcceleratorManagerTest, Register) {
  TestTarget target;
  const Accelerator accelerator_a(VKEY_A, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_a, "a");

  const Accelerator accelerator_b(VKEY_B, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_b, "b");

  const Accelerator accelerator_c(VKEY_C, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_c, "c");

  const Accelerator accelerator_d(VKEY_D, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_d, "d");

  manager_.Register(
      {accelerator_a, accelerator_b, accelerator_c, accelerator_d},
      AcceleratorManager::kNormalPriority, &target);
  EXPECT_EQ("Register a Register b Register c Register d",
            delegate_.GetAndClearCommands());

  // The registered accelerators are processed.
  EXPECT_TRUE(manager_.Process(accelerator_a));
  EXPECT_TRUE(manager_.Process(accelerator_b));
  EXPECT_TRUE(manager_.Process(accelerator_c));
  EXPECT_TRUE(manager_.Process(accelerator_d));
  EXPECT_EQ(4, target.accelerator_pressed_count());
}

TEST_F(AcceleratorManagerTest, RegisterMultipleTarget) {
  const Accelerator accelerator_a(VKEY_A, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_a, "a");
  TestTarget target1;
  manager_.Register({accelerator_a}, AcceleratorManager::kNormalPriority,
                    &target1);
  EXPECT_EQ("Register a", delegate_.GetAndClearCommands());
  TestTarget target2;
  manager_.Register({accelerator_a}, AcceleratorManager::kNormalPriority,
                    &target2);
  // Registering the same command shouldn't notify the delegate.
  EXPECT_TRUE(delegate_.GetAndClearCommands().empty());

  // If multiple targets are registered with the same accelerator, the target
  // registered later processes the accelerator.
  EXPECT_TRUE(manager_.Process(accelerator_a));
  EXPECT_EQ(0, target1.accelerator_pressed_count());
  EXPECT_EQ(1, target2.accelerator_pressed_count());
}

TEST_F(AcceleratorManagerTest, Unregister) {
  const Accelerator accelerator_a(VKEY_A, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_a, "a");
  TestTarget target;
  const Accelerator accelerator_b(VKEY_B, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_b, "b");
  manager_.Register({accelerator_a, accelerator_b},
                    AcceleratorManager::kNormalPriority, &target);
  EXPECT_EQ("Register a Register b", delegate_.GetAndClearCommands());

  // Unregistering a different accelerator does not affect the other
  // accelerator.
  manager_.Unregister(accelerator_b, &target);
  EXPECT_EQ("Unregister b", delegate_.GetAndClearCommands());
  EXPECT_TRUE(manager_.Process(accelerator_a));
  EXPECT_EQ(1, target.accelerator_pressed_count());

  // The unregistered accelerator is no longer processed.
  target.set_accelerator_pressed_count(0);
  manager_.Unregister(accelerator_a, &target);
  EXPECT_EQ("Unregister a", delegate_.GetAndClearCommands());
  EXPECT_FALSE(manager_.Process(accelerator_a));
  EXPECT_EQ(0, target.accelerator_pressed_count());
}

TEST_F(AcceleratorManagerTest, UnregisterAll) {
  const Accelerator accelerator_a(VKEY_A, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_a, "a");
  TestTarget target1;
  const Accelerator accelerator_b(VKEY_B, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_b, "b");
  manager_.Register({accelerator_a, accelerator_b},
                    AcceleratorManager::kNormalPriority, &target1);
  const Accelerator accelerator_c(VKEY_C, EF_NONE);
  delegate_.SetIdForAccelerator(accelerator_c, "c");
  TestTarget target2;
  manager_.Register({accelerator_c}, AcceleratorManager::kNormalPriority,
                    &target2);
  EXPECT_EQ("Register a Register b Register c",
            delegate_.GetAndClearCommands());
  manager_.UnregisterAll(&target1);
  {
    const std::string commands = delegate_.GetAndClearCommands();
    // Ordering is not guaranteed.
    EXPECT_TRUE(commands == "Unregister a Unregister b" ||
                commands == "Unregister b Unregister a");
  }

  // All the accelerators registered for |target1| are no longer processed.
  EXPECT_FALSE(manager_.Process(accelerator_a));
  EXPECT_FALSE(manager_.Process(accelerator_b));
  EXPECT_EQ(0, target1.accelerator_pressed_count());

  // UnregisterAll with a different target does not affect the other target.
  EXPECT_TRUE(manager_.Process(accelerator_c));
  EXPECT_EQ(1, target2.accelerator_pressed_count());
}

TEST_F(AcceleratorManagerTest, Process) {
  TestTarget target;

  // Test all cases of possible modifiers.
  for (size_t i = 0; i < (1 << arraysize(kAcceleratorModifiers)); ++i) {
    const int modifiers = BuildAcceleratorModifier(i);
    Accelerator accelerator(GetAccelerator(VKEY_A, modifiers));
    manager_.Register({accelerator}, AcceleratorManager::kNormalPriority,
                      &target);

    // The registered accelerator is processed.
    const int last_count = target.accelerator_pressed_count();
    EXPECT_TRUE(manager_.Process(accelerator)) << i;
    EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << i;

    // The non-registered accelerators are not processed.
    accelerator.set_type(ET_UNKNOWN);
    EXPECT_FALSE(manager_.Process(accelerator)) << i;  // different type
    accelerator.set_type(ET_KEY_RELEASED);
    EXPECT_FALSE(manager_.Process(accelerator)) << i;  // different type

    EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_UNKNOWN, modifiers)))
        << i;  // different vkey
    EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_B, modifiers)))
        << i;  // different vkey
    EXPECT_FALSE(manager_.Process(GetAccelerator(VKEY_SHIFT, modifiers)))
        << i;  // different vkey

    for (size_t test_i = 0; test_i < (1 << arraysize(kAcceleratorModifiers));
         ++test_i) {
      if (test_i == i)
        continue;
      const int test_modifiers = BuildAcceleratorModifier(test_i);
      const Accelerator test_accelerator(
          GetAccelerator(VKEY_A, test_modifiers));
      EXPECT_FALSE(manager_.Process(test_accelerator)) << " i=" << i
                                                       << " test_i=" << test_i;
    }

    EXPECT_EQ(last_count + 1, target.accelerator_pressed_count()) << i;
    manager_.UnregisterAll(&target);
  }
}

// Verifies delegate is notifed correctly when unregistering and registering
// with the same accelerator.
TEST_F(AcceleratorManagerTest, Reregister) {
  const Accelerator accelerator_a(VKEY_A, EF_NONE);
  TestTarget target;
  delegate_.SetIdForAccelerator(accelerator_a, "a");
  manager_.Register({accelerator_a}, AcceleratorManager::kNormalPriority,
                    &target);
  EXPECT_EQ("Register a", delegate_.GetAndClearCommands());
  manager_.UnregisterAll(&target);
  EXPECT_EQ("Unregister a", delegate_.GetAndClearCommands());
  manager_.Register({accelerator_a}, AcceleratorManager::kNormalPriority,
                    &target);
  EXPECT_EQ("Register a", delegate_.GetAndClearCommands());
}

}  // namespace test
}  // namespace ui
