// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <vector>

#include "cobalt/dom/keyboard_event.h"
#include "cobalt/dom/keycode.h"
#include "cobalt/webdriver/keyboard.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Each;
using testing::ElementsAre;
using testing::Eq;

namespace cobalt {
namespace webdriver {
namespace {

int32 GetKeyCode(const dom::KeyboardEvent::Data& event) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
            new dom::KeyboardEvent(event));
  return keyboard_event->key_code();
}

int32 GetCharCode(const dom::KeyboardEvent::Data& event) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
            new dom::KeyboardEvent(event));
  return keyboard_event->char_code();
}

uint32 GetModifierBitfield(const dom::KeyboardEvent::Data& event) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
            new dom::KeyboardEvent(event));
  return keyboard_event->modifiers();
}

std::string GetType(const dom::KeyboardEvent::Data& event) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
            new dom::KeyboardEvent(event));
  return keyboard_event->type().c_str();
}

int GetLocation(const dom::KeyboardEvent::Data& event) {
  scoped_refptr<dom::KeyboardEvent> keyboard_event(
            new dom::KeyboardEvent(event));
  return keyboard_event->location();
}

// Less verbose redefinitions.
const int kNoModifier = dom::UIEventWithKeyState::kNoModifier;
const int kShift = dom::UIEventWithKeyState::kShiftKey;
const int kAlt = dom::UIEventWithKeyState::kAltKey;
const int kAltAndShift = kAlt | kShift;

const int kLocationStandard =
    dom::KeyboardEvent::kDomKeyLocationStandard;
const int kLocationLeft = dom::KeyboardEvent::kDomKeyLocationLeft;

class KeyboardTest : public ::testing::Test {
 protected:
  std::vector<int32> GetKeyCodes() {
    std::vector<int32> key_codes(events_.size());
    std::transform(events_.begin(), events_.end(), key_codes.begin(),
                   GetKeyCode);
    return key_codes;
  }
  std::vector<int32> GetCharCodes() {
    std::vector<int32> char_codes(events_.size());
    std::transform(events_.begin(), events_.end(), char_codes.begin(),
                   GetCharCode);
    return char_codes;
  }
  std::vector<uint32> GetModifiers() {
    std::vector<uint32> modifiers(events_.size());
    std::transform(events_.begin(), events_.end(), modifiers.begin(),
                   GetModifierBitfield);
    return modifiers;
  }
  std::vector<int> GetLocations() {
    std::vector<int> locations(events_.size());
    std::transform(events_.begin(), events_.end(), locations.begin(),
                   GetLocation);
    return locations;
  }
  std::vector<std::string> GetTypes() {
    std::vector<std::string> types(events_.size());
    std::transform(events_.begin(), events_.end(), types.begin(), GetType);
    return types;
  }
  Keyboard::KeyboardEventVector events_;
};
}  // namespace

TEST_F(KeyboardTest, LowerCaseCharacter) {
  std::string keys = "r";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  ASSERT_EQ(events_.size(), 3);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keypress", "keyup"));
  EXPECT_THAT(GetKeyCodes(), ElementsAre('R', 0, 'R'));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 'r', 0));
  EXPECT_THAT(GetModifiers(), Each(Eq(kNoModifier)));
  EXPECT_THAT(GetLocations(), Each(Eq(kLocationStandard)));
}

TEST_F(KeyboardTest, UpperCaseCharacter) {
  std::string keys = "R";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  // keydown(shift)
  //   keydown(R), keypress(R), keyup(R)
  // keyup(shift)
  ASSERT_EQ(events_.size(), 5);
  EXPECT_THAT(GetTypes(),
              ElementsAre("keydown", "keydown", "keypress", "keyup", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kShift), 'R', 0, 'R',
                          static_cast<int>(dom::keycode::kShift)));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 0, 'R', 0, 0));
  EXPECT_THAT(GetModifiers(),
              ElementsAre(kShift, kShift, kShift, kShift, kNoModifier));
  EXPECT_THAT(GetLocations(),
              ElementsAre(kLocationLeft, kLocationStandard, kLocationStandard,
                          kLocationStandard, kLocationLeft));
}

TEST_F(KeyboardTest, ShiftedCharacter) {
  std::string keys = "&";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  // keydown(shift)
  //   keydown(7), keypress(&), keyup(7)
  // keyup(shift)
  ASSERT_EQ(events_.size(), 5);
  EXPECT_THAT(GetTypes(),
              ElementsAre("keydown", "keydown", "keypress", "keyup", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kShift), '7', 0, '7',
                          static_cast<int>(dom::keycode::kShift)));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 0, '&', 0, 0));
  EXPECT_THAT(GetModifiers(),
              ElementsAre(kShift, kShift, kShift, kShift, kNoModifier));
  EXPECT_THAT(GetLocations(),
              ElementsAre(kLocationLeft, kLocationStandard, kLocationStandard,
                          kLocationStandard, kLocationLeft));
}

TEST_F(KeyboardTest, Modifier) {
  // \uE00A is the Alt-key modifier.
  std::string keys = "\uE00A";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  ASSERT_EQ(events_.size(), 1);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kMenu)));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0));
  EXPECT_THAT(GetModifiers(), ElementsAre(kAlt));
  EXPECT_THAT(GetLocations(), ElementsAre(kLocationLeft));
}

TEST_F(KeyboardTest, ModifiersAreKept) {
  // \uE00A is the Alt-key modifier.
  // \uE008 is the Shift-key modifier.
  std::string keys = "\uE00A\uE008";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  ASSERT_EQ(events_.size(), 2);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keydown"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kMenu),
                          static_cast<int>(dom::keycode::kShift)));
  EXPECT_THAT(GetCharCodes(), Each(Eq(0)));
  EXPECT_THAT(GetModifiers(), ElementsAre(kAlt, kAltAndShift));
  EXPECT_THAT(GetLocations(), Each(Eq(kLocationLeft)));
}

TEST_F(KeyboardTest, ModifiersAreReleased) {
  // \uE00A is the Alt-key modifier.
  // \uE008 is the Shift-key modifier.
  std::string keys = "\uE00A\uE008";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kReleaseModifiers, &events_);

  ASSERT_EQ(events_.size(), 4);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keydown", "keyup", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kMenu),
                          static_cast<int>(dom::keycode::kShift),
                          static_cast<int>(dom::keycode::kMenu),
                          static_cast<int>(dom::keycode::kShift)));
  EXPECT_THAT(GetCharCodes(), Each(Eq(0)));
  EXPECT_THAT(GetModifiers(),
              ElementsAre(kAlt, kAltAndShift, kShift, kNoModifier));
  EXPECT_THAT(GetLocations(), Each(Eq(kLocationLeft)));
}

TEST_F(KeyboardTest, SpecialCharacter) {
  // \uE012 is the Left-arrow key.
  std::string keys = "\uE012";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  ASSERT_EQ(events_.size(), 2);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keyup"));
  EXPECT_THAT(GetKeyCodes(), Each(Eq(static_cast<int>(dom::keycode::kLeft))));
  EXPECT_THAT(GetCharCodes(), Each(Eq(0)));
  EXPECT_THAT(GetModifiers(), Each(Eq(kNoModifier)));
  EXPECT_THAT(GetLocations(), Each(Eq(kLocationStandard)));
}

TEST_F(KeyboardTest, ModifierIsSticky) {
  // \uE00A is the Alt-key modifier. Corresponds to the kMenu key code.
  std::string keys = "\uE00AaB";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  // keydown(alt)
  //   keydown(A), keypress(a), keyup(A),
  //   keydown(shift)
  //     keydown(B), keypress(B), keyup(B)
  //   keyup(shift)
  ASSERT_EQ(events_.size(), 9);
  EXPECT_THAT(GetTypes(),
              ElementsAre("keydown", "keydown", "keypress", "keyup", "keydown",
                          "keydown", "keypress", "keyup", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kMenu), 'A', 0, 'A',
                          static_cast<int>(dom::keycode::kShift), 'B', 0, 'B',
                          static_cast<int>(dom::keycode::kShift)));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 0, 'a', 0, 0, 0, 'B', 0, 0));
  EXPECT_THAT(GetModifiers(),
              ElementsAre(kAlt, kAlt, kAlt, kAlt, kAltAndShift, kAltAndShift,
                          kAltAndShift, kAltAndShift, kAlt));
  EXPECT_THAT(GetLocations(),
              ElementsAre(kLocationLeft, kLocationStandard, kLocationStandard,
                          kLocationStandard, kLocationLeft, kLocationStandard,
                          kLocationStandard, kLocationStandard, kLocationLeft));
}

TEST_F(KeyboardTest, ToggleModifier) {
  // \uE008 is the Shift-key modifier.
  std::string keys = "\uE008a\uE008a";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  // keydown(shift)
  //   keydown(A), keypress(A), keyup(A)
  // keyup(shift)
  // keydown(A), keypress(a), keyup(A)
  ASSERT_EQ(events_.size(), 8);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keydown", "keypress", "keyup",
                                      "keyup", "keydown", "keypress", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kShift), 'A', 0, 'A',
                          static_cast<int>(dom::keycode::kShift), 'A', 0, 'A'));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 0, 'A', 0, 0, 0, 'a', 0));

  EXPECT_THAT(GetModifiers(),
              ElementsAre(kShift, kShift, kShift, kShift, kNoModifier,
                          kNoModifier, kNoModifier, kNoModifier));
  EXPECT_THAT(GetLocations(),
              ElementsAre(kLocationLeft, kLocationStandard, kLocationStandard,
                          kLocationStandard, kLocationLeft, kLocationStandard,
                          kLocationStandard, kLocationStandard));
}

TEST_F(KeyboardTest, NullClearsModifiers) {
  std::string keys = "\uE008\uE00A\uE000a";
  Keyboard::TranslateToKeyEvents(keys, Keyboard::kKeepModifiers, &events_);

  // keydown(shift)
  //   keydown(alt)
  //   keyup(alt)
  // keyup(shift)
  // keydown(A), keypress(a), keyup(A)
  ASSERT_EQ(events_.size(), 7);
  EXPECT_THAT(GetTypes(), ElementsAre("keydown", "keydown", "keyup", "keyup",
                                      "keydown", "keypress", "keyup"));
  EXPECT_THAT(GetKeyCodes(),
              ElementsAre(static_cast<int>(dom::keycode::kShift),
                          static_cast<int>(dom::keycode::kMenu),
                          static_cast<int>(dom::keycode::kMenu),
                          static_cast<int>(dom::keycode::kShift), 'A', 0, 'A'));
  EXPECT_THAT(GetCharCodes(), ElementsAre(0, 0, 0, 0, 0, 'a', 0));

  EXPECT_THAT(GetModifiers(),
              ElementsAre(kShift, kAltAndShift, kShift, kNoModifier,
                          kNoModifier, kNoModifier, kNoModifier));
  EXPECT_THAT(
      GetLocations(),
      ElementsAre(kLocationLeft, kLocationLeft, kLocationLeft, kLocationLeft,
                  kLocationStandard, kLocationStandard, kLocationStandard));
}

}  // namespace webdriver
}  // namespace cobalt
