// Copyright (c) 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 <list>
#include <string>

#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/chrome/ui_events.h"
#include "chrome/test/chromedriver/key_converter.h"
#include "chrome/test/chromedriver/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

void CheckEvents(const base::string16& keys,
                 KeyEvent expected_events[],
                 bool release_modifiers,
                 size_t expected_size,
                 int expected_modifiers) {
  int modifiers = 0;
  std::list<KeyEvent> events;
  EXPECT_EQ(kOk, ConvertKeysToKeyEvents(keys, release_modifiers,
                                        &modifiers, &events).code());
  EXPECT_EQ(expected_size, events.size());
  size_t i = 0;
  std::list<KeyEvent>::const_iterator it = events.begin();
  while (i < expected_size && it != events.end()) {
    EXPECT_EQ(expected_events[i].type, it->type);
    EXPECT_EQ(expected_events[i].modifiers, it->modifiers);
    EXPECT_EQ(expected_events[i].modified_text, it->modified_text);
    EXPECT_EQ(expected_events[i].unmodified_text, it->unmodified_text);
    EXPECT_EQ(expected_events[i].key_code, it->key_code);

    ++i;
    ++it;
  }
  EXPECT_EQ(expected_modifiers, modifiers);
}

void CheckEventsReleaseModifiers(const base::string16& keys,
                                 KeyEvent expected_events[],
                                 size_t expected_size) {
  CheckEvents(keys, expected_events, true /* release_modifier */,
      expected_size, 0 /* expected_modifiers */);
}

void CheckEventsReleaseModifiers(const std::string& keys,
                                 KeyEvent expected_events[],
                                 size_t expected_size) {
  CheckEventsReleaseModifiers(base::UTF8ToUTF16(keys),
      expected_events, expected_size);
}

void CheckNonShiftChar(ui::KeyboardCode key_code, char character) {
  int modifiers = 0;
  std::string char_string;
  char_string.push_back(character);
  std::list<KeyEvent> events;
  EXPECT_EQ(kOk, ConvertKeysToKeyEvents(base::ASCIIToUTF16(char_string),
                                        true /* release_modifiers*/,
                                        &modifiers, &events).code());
  ASSERT_EQ(3u, events.size()) << "Char: " << character;
  std::list<KeyEvent>::const_iterator it = events.begin();
  EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
  ++it;  // Move to the second event.
  ASSERT_EQ(1u, it->modified_text.length()) << "Char: " << character;
  ASSERT_EQ(1u, it->unmodified_text.length()) << "Char: " << character;
  EXPECT_EQ(character, it->modified_text[0]) << "Char: " << character;
  EXPECT_EQ(character, it->unmodified_text[0]) << "Char: " << character;
  ++it;  // Move to the third event.
  EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
}

void CheckShiftChar(ui::KeyboardCode key_code, char character, char lower) {
  int modifiers = 0;
  std::string char_string;
  char_string.push_back(character);
  std::list<KeyEvent> events;
  EXPECT_EQ(kOk, ConvertKeysToKeyEvents(base::ASCIIToUTF16(char_string),
                                        true /* release_modifiers*/,
                                        &modifiers, &events).code());
  ASSERT_EQ(5u, events.size()) << "Char: " << character;
  std::list<KeyEvent>::const_iterator it = events.begin();
  EXPECT_EQ(ui::VKEY_SHIFT, it->key_code) << "Char: " << character;
  ++it;  // Move to second event.
  EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
  ++it;  // Move to third event.
  ASSERT_EQ(1u, it->modified_text.length()) << "Char: " << character;
  ASSERT_EQ(1u, it->unmodified_text.length()) << "Char: " << character;
  EXPECT_EQ(character, it->modified_text[0]) << "Char: " << character;
  EXPECT_EQ(lower, it->unmodified_text[0]) << "Char: " << character;
  ++it;  // Move to fourth event.
  EXPECT_EQ(key_code, it->key_code) << "Char: " << character;
  ++it;  // Move to fifth event.
  EXPECT_EQ(ui::VKEY_SHIFT, it->key_code) << "Char: " << character;
}

}  // namespace

TEST(KeyConverter, SingleChar) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_H, 0),
      CreateCharEvent("h", "h", 0),
      CreateKeyUpEvent(ui::VKEY_H, 0)};
  CheckEventsReleaseModifiers("h", event_array, arraysize(event_array));
}

TEST(KeyConverter, SingleNumber) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_1, 0),
      CreateCharEvent("1", "1", 0),
      CreateKeyUpEvent(ui::VKEY_1, 0)};
  CheckEventsReleaseModifiers("1", event_array, arraysize(event_array));
}

TEST(KeyConverter, MultipleChars) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_H, 0),
      CreateCharEvent("h", "h", 0),
      CreateKeyUpEvent(ui::VKEY_H, 0),
      CreateKeyDownEvent(ui::VKEY_E, 0),
      CreateCharEvent("e", "e", 0),
      CreateKeyUpEvent(ui::VKEY_E, 0),
      CreateKeyDownEvent(ui::VKEY_Y, 0),
      CreateCharEvent("y", "y", 0),
      CreateKeyUpEvent(ui::VKEY_Y, 0)};
  CheckEventsReleaseModifiers("hey", event_array, arraysize(event_array));
}

TEST(KeyConverter, WebDriverSpecialChar) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SPACE, 0),
      CreateCharEvent(" ", " ", 0),
      CreateKeyUpEvent(ui::VKEY_SPACE, 0)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE00DU));
  CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
}

TEST(KeyConverter, WebDriverSpecialNonCharKey) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_F1, 0),
      CreateKeyUpEvent(ui::VKEY_F1, 0)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE031U));
  CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
}

TEST(KeyConverter, FrenchKeyOnEnglishLayout) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_UNKNOWN, 0),
      CreateCharEvent(base::WideToUTF8(L"\u00E9"),
                      base::WideToUTF8(L"\u00E9"), 0),
      CreateKeyUpEvent(ui::VKEY_UNKNOWN, 0)};
  CheckEventsReleaseModifiers(base::WideToUTF16(L"\u00E9"),
      event_array, arraysize(event_array));
}

#if defined(OS_WIN)
TEST(KeyConverter, NeedsCtrlAndAlt) {
  RestoreKeyboardLayoutOnDestruct restore;
  int ctrl_and_alt = kControlKeyModifierMask | kAltKeyModifierMask;
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_CONTROL, 0),
      CreateKeyDownEvent(ui::VKEY_MENU, 0),
      CreateKeyDownEvent(ui::VKEY_Q, ctrl_and_alt),
      CreateCharEvent("q", "@", ctrl_and_alt),
      CreateKeyUpEvent(ui::VKEY_Q, ctrl_and_alt),
      CreateKeyUpEvent(ui::VKEY_MENU, 0),
      CreateKeyUpEvent(ui::VKEY_CONTROL, 0)};
  ASSERT_TRUE(SwitchKeyboardLayout("00000407"));
  CheckEventsReleaseModifiers("@", event_array, arraysize(event_array));
}
#endif

TEST(KeyConverter, UppercaseCharDoesShift) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, 0),
      CreateKeyDownEvent(ui::VKEY_A, kShiftKeyModifierMask),
      CreateCharEvent("a", "A", kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_A, kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
  CheckEventsReleaseModifiers("A", event_array, arraysize(event_array));
}

TEST(KeyConverter, UppercaseSymbolCharDoesShift) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, 0),
      CreateKeyDownEvent(ui::VKEY_1, kShiftKeyModifierMask),
      CreateCharEvent("1", "!", kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_1, kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
  CheckEventsReleaseModifiers("!", event_array, arraysize(event_array));
}

TEST(KeyConverter, UppercaseCharUsesShiftOnlyIfNecessary) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
      CreateKeyDownEvent(ui::VKEY_A, kShiftKeyModifierMask),
      CreateCharEvent("a", "A", kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_A, kShiftKeyModifierMask),
      CreateKeyDownEvent(ui::VKEY_B, kShiftKeyModifierMask),
      CreateCharEvent("b", "B", kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_B, kShiftKeyModifierMask),
      CreateKeyDownEvent(ui::VKEY_C, kShiftKeyModifierMask),
      CreateCharEvent("c", "C", kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_C, kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_SHIFT, 0)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE008U));
  keys.append(base::UTF8ToUTF16("aBc"));
  CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
}

TEST(KeyConverter, ToggleModifiers) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_SHIFT, 0),
      CreateKeyDownEvent(ui::VKEY_CONTROL, kControlKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_CONTROL, 0),
      CreateKeyDownEvent(ui::VKEY_MENU, kAltKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_MENU, 0),
      CreateKeyDownEvent(ui::VKEY_COMMAND, kMetaKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_COMMAND, 0)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE008U));
  keys.push_back(static_cast<base::char16>(0xE008U));
  keys.push_back(static_cast<base::char16>(0xE009U));
  keys.push_back(static_cast<base::char16>(0xE009U));
  keys.push_back(static_cast<base::char16>(0xE00AU));
  keys.push_back(static_cast<base::char16>(0xE00AU));
  keys.push_back(static_cast<base::char16>(0xE03DU));
  keys.push_back(static_cast<base::char16>(0xE03DU));
  CheckEventsReleaseModifiers(keys, event_array, arraysize(event_array));
}

#if defined(OS_WIN)
// https://code.google.com/p/chromedriver/issues/detail?id=546
#define MAYBE_AllShorthandKeys DISABLED_AllShorthandKeys
#else
#define MAYBE_AllShorthandKeys AllShorthandKeys
#endif

TEST(KeyConverter, MAYBE_AllShorthandKeys) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_RETURN, 0),
      CreateCharEvent("\r", "\r", 0),
      CreateKeyUpEvent(ui::VKEY_RETURN, 0),
      CreateKeyDownEvent(ui::VKEY_RETURN, 0),
      CreateCharEvent("\r", "\r", 0),
      CreateKeyUpEvent(ui::VKEY_RETURN, 0),
      CreateKeyDownEvent(ui::VKEY_TAB, 0),
#if defined(USE_AURA) || defined(OS_LINUX)
      CreateCharEvent("\t", "\t", 0),
#endif
      CreateKeyUpEvent(ui::VKEY_TAB, 0),
      CreateKeyDownEvent(ui::VKEY_BACK, 0),
#if defined(USE_AURA) || defined(OS_LINUX)
      CreateCharEvent("\b", "\b", 0),
#endif
      CreateKeyUpEvent(ui::VKEY_BACK, 0),
      CreateKeyDownEvent(ui::VKEY_SPACE, 0),
      CreateCharEvent(" ", " ", 0),
      CreateKeyUpEvent(ui::VKEY_SPACE, 0)};
  CheckEventsReleaseModifiers("\n\r\n\t\b ",
      event_array,arraysize(event_array));
}

#if defined(OS_LINUX)
// Fails on bots: crbug.com/174962
#define MAYBE_AllEnglishKeyboardSymbols DISABLED_AllEnglishKeyboardSymbols
#else
#define MAYBE_AllEnglishKeyboardSymbols AllEnglishKeyboardSymbols
#endif

TEST(KeyConverter, MAYBE_AllEnglishKeyboardSymbols) {
  base::string16 keys;
  const ui::KeyboardCode kSymbolKeyCodes[] = {
      ui::VKEY_OEM_3,
      ui::VKEY_OEM_MINUS,
      ui::VKEY_OEM_PLUS,
      ui::VKEY_OEM_4,
      ui::VKEY_OEM_6,
      ui::VKEY_OEM_5,
      ui::VKEY_OEM_1,
      ui::VKEY_OEM_7,
      ui::VKEY_OEM_COMMA,
      ui::VKEY_OEM_PERIOD,
      ui::VKEY_OEM_2};
  std::string kLowerSymbols = "`-=[]\\;',./";
  std::string kUpperSymbols = "~_+{}|:\"<>?";
  for (size_t i = 0; i < kLowerSymbols.length(); ++i)
    CheckNonShiftChar(kSymbolKeyCodes[i], kLowerSymbols[i]);
  for (size_t i = 0; i < kUpperSymbols.length(); ++i)
    CheckShiftChar(kSymbolKeyCodes[i], kUpperSymbols[i], kLowerSymbols[i]);
}

TEST(KeyConverter, AllEnglishKeyboardTextChars) {
  std::string kLowerChars = "0123456789abcdefghijklmnopqrstuvwxyz";
  std::string kUpperChars = ")!@#$%^&*(ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  for (size_t i = 0; i < kLowerChars.length(); ++i) {
    int offset = 0;
    if (i < 10)
      offset = ui::VKEY_0;
    else
      offset = ui::VKEY_0 + 7;
    ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i);
    CheckNonShiftChar(expected_code, kLowerChars[i]);
  }
  for (size_t i = 0; i < kUpperChars.length(); ++i) {
    int offset = 0;
    if (i < 10)
      offset = ui::VKEY_0;
    else
      offset = ui::VKEY_0 + 7;
    ui::KeyboardCode expected_code = static_cast<ui::KeyboardCode>(offset + i);
    CheckShiftChar(expected_code, kUpperChars[i], kLowerChars[i]);
  }
}

#if defined(OS_LINUX) || defined(OS_WIN)
// https://code.google.com/p/chromedriver/issues/detail?id=240
// https://code.google.com/p/chromedriver/issues/detail?id=546
#define MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard \
    DISABLED_AllSpecialWebDriverKeysOnEnglishKeyboard
#else
#define MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard \
    AllSpecialWebDriverKeysOnEnglishKeyboard
#endif

TEST(KeyConverter, MAYBE_AllSpecialWebDriverKeysOnEnglishKeyboard) {
  const char kTextForKeys[] = {
#if defined(USE_AURA) || defined(OS_LINUX)
      0, 0, 0, '\b', '\t', 0, '\r', '\r', 0, 0, 0, 0, 0x1B,
      ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7F, ';', '=',
#else
      0, 0, 0, 0, 0, 0, '\r', '\r', 0, 0, 0, 0, 0,
      ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ';', '=',
#endif
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
      '*', '+', ',', '-', '.', '/'};
  for (size_t i = 0; i <= 0x3D; ++i) {
    if (i > 0x29 && i < 0x31)
      continue;
    base::string16 keys;
    int modifiers = 0;
    keys.push_back(0xE000U + i);
    std::list<KeyEvent> events;
    if (i == 1) {
      EXPECT_NE(kOk, ConvertKeysToKeyEvents(keys,
                                            true /* release_modifiers*/,
                                            &modifiers, &events).code())
          << "Index: " << i;
      EXPECT_EQ(0u, events.size()) << "Index: " << i;
    } else {
      EXPECT_EQ(kOk, ConvertKeysToKeyEvents(keys,
                                            true /* release_modifiers */,
                                            &modifiers, &events).code())
          << "Index: " << i;
      if (i == 0) {
        EXPECT_EQ(0u, events.size()) << "Index: " << i;
      } else if (i >= arraysize(kTextForKeys) || kTextForKeys[i] == 0) {
        EXPECT_EQ(2u, events.size()) << "Index: " << i;
      } else {
        ASSERT_EQ(3u, events.size()) << "Index: " << i;
        std::list<KeyEvent>::const_iterator it = events.begin();
        ++it;  // Move to the second event.
        ASSERT_EQ(1u, it->unmodified_text.length()) << "Index: " << i;
        EXPECT_EQ(kTextForKeys[i], it->unmodified_text[0])
            << "Index: " << i;
      }
    }
  }
}

TEST(KeyConverter, ModifiersState) {
  int shift_key_modifier = kShiftKeyModifierMask;
  int control_key_modifier = shift_key_modifier | kControlKeyModifierMask;
  int alt_key_modifier = control_key_modifier | kAltKeyModifierMask;
  int meta_key_modifier = alt_key_modifier | kMetaKeyModifierMask;
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, shift_key_modifier),
      CreateKeyDownEvent(ui::VKEY_CONTROL, control_key_modifier),
      CreateKeyDownEvent(ui::VKEY_MENU, alt_key_modifier),
      CreateKeyDownEvent(ui::VKEY_COMMAND, meta_key_modifier)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE008U));
  keys.push_back(static_cast<base::char16>(0xE009U));
  keys.push_back(static_cast<base::char16>(0xE00AU));
  keys.push_back(static_cast<base::char16>(0xE03DU));

  CheckEvents(keys, event_array, false /* release_modifiers */,
      arraysize(event_array), meta_key_modifier);
}

TEST(KeyConverter, ReleaseModifiers) {
  KeyEvent event_array[] = {
      CreateKeyDownEvent(ui::VKEY_SHIFT, kShiftKeyModifierMask),
      CreateKeyDownEvent(ui::VKEY_CONTROL,
          kShiftKeyModifierMask | kControlKeyModifierMask),
      CreateKeyUpEvent(ui::VKEY_SHIFT, 0),
      CreateKeyUpEvent(ui::VKEY_CONTROL, 0)};
  base::string16 keys;
  keys.push_back(static_cast<base::char16>(0xE008U));
  keys.push_back(static_cast<base::char16>(0xE009U));

  CheckEvents(keys, event_array, true /* release_modifiers */,
      arraysize(event_array), 0);
}
