// Copyright 2013 The Flutter 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 "flutter/shell/platform/windows/keyboard_key_embedder_handler.h"

#include <string>
#include <vector>

#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "gtest/gtest.h"

namespace flutter {

namespace {

constexpr SHORT kStateMaskToggled = 0x01;
constexpr SHORT kStateMaskPressed = 0x80;

class TestFlutterKeyEvent : public FlutterKeyEvent {
 public:
  TestFlutterKeyEvent(const FlutterKeyEvent& src,
                      FlutterKeyEventCallback callback,
                      void* user_data)
      : character_str(src.character), callback(callback), user_data(user_data) {
    struct_size = src.struct_size;
    timestamp = src.timestamp;
    type = src.type;
    physical = src.physical;
    logical = src.logical;
    character = character_str.c_str();
    synthesized = src.synthesized;
  }

  TestFlutterKeyEvent(TestFlutterKeyEvent&& source)
      : FlutterKeyEvent(source),
        callback(std::move(source.callback)),
        user_data(source.user_data) {
    character = character_str.c_str();
  }

  FlutterKeyEventCallback callback;
  void* user_data;

 private:
  const std::string character_str;
};

class TestKeystate {
 public:
  void Set(int virtual_key, bool pressed, bool toggled_on = false) {
    state_[virtual_key] = (pressed ? kStateMaskPressed : 0) |
                          (toggled_on ? kStateMaskToggled : 0);
  }

  SHORT Get(int virtual_key) { return state_[virtual_key]; }

  KeyboardKeyEmbedderHandler::GetKeyStateHandler Getter() {
    return [this](int virtual_key) { return Get(virtual_key); };
  }

 private:
  std::map<int, SHORT> state_;
};

UINT DefaultMapVkToScan(UINT virtual_key, bool extended) {
  return MapVirtualKey(virtual_key,
                       extended ? MAPVK_VK_TO_VSC_EX : MAPVK_VK_TO_VSC);
}

}  // namespace

namespace testing {

namespace {
constexpr uint64_t kScanCodeKeyA = 0x1e;
constexpr uint64_t kScanCodeAltLeft = 0x38;
constexpr uint64_t kScanCodeNumpad1 = 0x4f;
constexpr uint64_t kScanCodeNumLock = 0x45;
constexpr uint64_t kScanCodeControl = 0x1d;
constexpr uint64_t kScanCodeShiftLeft = 0x2a;
constexpr uint64_t kScanCodeShiftRight = 0x36;

constexpr uint64_t kVirtualKeyA = 0x41;

using namespace ::flutter::testing::keycodes;
}  // namespace

TEST(KeyboardKeyEmbedderHandlerTest, ConvertChar32ToUtf8) {
  std::string result;

  result = ConvertChar32ToUtf8(0x0024);
  EXPECT_EQ(result.length(), 1);
  EXPECT_EQ(result[0], '\x24');

  result = ConvertChar32ToUtf8(0x00A2);
  EXPECT_EQ(result.length(), 2);
  EXPECT_EQ(result[0], '\xC2');
  EXPECT_EQ(result[1], '\xA2');

  result = ConvertChar32ToUtf8(0x0939);
  EXPECT_EQ(result.length(), 3);
  EXPECT_EQ(result[0], '\xE0');
  EXPECT_EQ(result[1], '\xA4');
  EXPECT_EQ(result[2], '\xB9');

  result = ConvertChar32ToUtf8(0x10348);
  EXPECT_EQ(result.length(), 4);
  EXPECT_EQ(result[0], '\xF0');
  EXPECT_EQ(result[1], '\x90');
  EXPECT_EQ(result[2], '\x8D');
  EXPECT_EQ(result[3], '\x88');
}

// Test the most basic key events.
//
// Press, hold, and release key A on an US keyboard.
TEST(KeyboardKeyEmbedderHandlerTest, BasicKeyPressingAndHolding) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press KeyA.
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();
  key_state.Set(kVirtualKeyA, true);

  // Hold KeyA.
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(false, event->user_data);
  EXPECT_EQ(last_handled, false);
  results.clear();

  // Release KeyA.
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  event->callback(false, event->user_data);
}

// Press numpad 1, toggle NumLock, and release numpad 1 on an US
// keyboard.
//
// This is special because the virtual key for numpad 1 will
// change in this process.
TEST(KeyboardKeyEmbedderHandlerTest, ToggleNumLockDuringNumpadPress) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press NumPad1.
  key_state.Set(VK_NUMPAD1, true);
  handler->KeyboardHook(
      VK_NUMPAD1, kScanCodeNumpad1, WM_KEYDOWN, 0, false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumpad1);
  EXPECT_EQ(event->logical, kLogicalNumpad1);
  // EXPECT_STREQ(event->character, "1"); // TODO
  EXPECT_EQ(event->synthesized, false);
  results.clear();

  // Press NumLock.
  key_state.Set(VK_NUMLOCK, true, true);
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  results.clear();

  // Release NumLock.
  key_state.Set(VK_NUMLOCK, false, true);
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYUP, 0, true, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  results.clear();

  // Release NumPad1. (The logical key is now NumpadEnd)
  handler->KeyboardHook(
      VK_END, kScanCodeNumpad1, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumpad1);
  EXPECT_EQ(event->logical, kLogicalNumpad1);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  results.clear();
}

// Key presses that trigger IME should be ignored by this API (and handled by
// compose API).
TEST(KeyboardKeyEmbedderHandlerTest, ImeEventsAreIgnored) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press A in an IME
  last_handled = false;
  handler->KeyboardHook(
      VK_PROCESSKEY, kScanCodeKeyA, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);

  // The A key down should yield an empty event.
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->physical, 0);
  EXPECT_EQ(event->logical, 0);
  EXPECT_EQ(event->callback, nullptr);
  results.clear();

  // Release A in an IME
  last_handled = false;
  handler->KeyboardHook(
      // The up event for an IME press has a normal virtual key.
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 0, true, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);

  // The A key up should yield an empty event.
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->physical, 0);
  EXPECT_EQ(event->logical, 0);
  EXPECT_EQ(event->callback, nullptr);
  results.clear();

  // Press A out of an IME
  key_state.Set(kVirtualKeyA, true);
  last_handled = false;
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  // Not decided yet
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  last_handled = false;
  key_state.Set(kVirtualKeyA, false);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
}

// Test if modifier keys that are told apart by the extended bit can be
// identified. (Their physical keys must be searched with the extended bit
// considered.)
TEST(KeyboardKeyEmbedderHandlerTest, ModifierKeysByExtendedBit) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press Ctrl left.
  last_handled = false;
  key_state.Set(VK_LCONTROL, true);
  handler->KeyboardHook(
      VK_LCONTROL, kScanCodeControl, WM_KEYDOWN, 0, false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalControlLeft);
  EXPECT_EQ(event->logical, kLogicalControlLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Press Ctrl right.
  last_handled = false;
  key_state.Set(VK_RCONTROL, true);
  handler->KeyboardHook(
      VK_RCONTROL, kScanCodeControl, WM_KEYDOWN, 0, true, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalControlRight);
  EXPECT_EQ(event->logical, kLogicalControlRight);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release Ctrl left.
  last_handled = false;
  key_state.Set(VK_LCONTROL, false);
  handler->KeyboardHook(
      VK_LCONTROL, kScanCodeControl, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalControlLeft);
  EXPECT_EQ(event->logical, kLogicalControlLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release Ctrl right.
  last_handled = false;
  key_state.Set(VK_RCONTROL, false);
  handler->KeyboardHook(
      VK_RCONTROL, kScanCodeControl, WM_KEYUP, 0, true, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalControlRight);
  EXPECT_EQ(event->logical, kLogicalControlRight);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();
}

// Test if modifier keys that are told apart by the virtual key
// can be identified.
TEST(KeyboardKeyEmbedderHandlerTest, ModifierKeysByVirtualKey) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press Shift left.
  last_handled = false;
  key_state.Set(VK_LSHIFT, true);
  handler->KeyboardHook(
      VK_LSHIFT, kScanCodeShiftLeft, WM_KEYDOWN, 0, false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalShiftLeft);
  EXPECT_EQ(event->logical, kLogicalShiftLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Press Shift right.
  last_handled = false;
  key_state.Set(VK_RSHIFT, true);
  handler->KeyboardHook(
      VK_RSHIFT, kScanCodeShiftRight, WM_KEYDOWN, 0, false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalShiftRight);
  EXPECT_EQ(event->logical, kLogicalShiftRight);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release Shift left.
  last_handled = false;
  key_state.Set(VK_LSHIFT, false);
  handler->KeyboardHook(
      VK_LSHIFT, kScanCodeShiftLeft, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalShiftLeft);
  EXPECT_EQ(event->logical, kLogicalShiftLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release Shift right.
  last_handled = false;
  key_state.Set(VK_RSHIFT, false);
  handler->KeyboardHook(
      VK_RSHIFT, kScanCodeShiftRight, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalShiftRight);
  EXPECT_EQ(event->logical, kLogicalShiftRight);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();
}

TEST(KeyboardKeyEmbedderHandlerTest, RepeatedDownIsIgnored) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);
  last_handled = false;

  // Press A (should yield a normal event)
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // KeyA's key up is missed.

  // Press A again (should yield an empty event)
  last_handled = false;
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->physical, 0);
  EXPECT_EQ(event->logical, 0);
  EXPECT_EQ(event->callback, nullptr);
  results.clear();
}

TEST(KeyboardKeyEmbedderHandlerTest, AbruptRepeatIsConvertedToDown) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);
  last_handled = false;

  key_state.Set(kVirtualKeyA, true);

  // Press A (with was_down true)
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release A
  last_handled = false;
  key_state.Set(kVirtualKeyA, false);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();
}

TEST(KeyboardKeyEmbedderHandlerTest, AbruptUpIsIgnored) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);
  last_handled = false;

  // KeyA's key down is missed.

  key_state.Set(kVirtualKeyA, true);

  // Press A again (should yield an empty event)
  last_handled = false;
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->physical, 0);
  EXPECT_EQ(event->logical, 0);
  EXPECT_EQ(event->callback, nullptr);
  results.clear();
}

TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncPressingState) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // A key down of control left is missed.
  key_state.Set(VK_LCONTROL, true);

  // Send a normal event
  key_state.Set(kVirtualKeyA, true);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 2);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalControlLeft);
  EXPECT_EQ(event->logical, kLogicalControlLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  last_handled = true;
  event->callback(false, event->user_data);
  EXPECT_EQ(last_handled, false);
  results.clear();

  // A key down of control right is missed.
  key_state.Set(VK_LCONTROL, false);

  // Hold KeyA.
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 2);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalControlLeft);
  EXPECT_EQ(event->logical, kLogicalControlLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  last_handled = true;
  event->callback(false, event->user_data);
  EXPECT_EQ(last_handled, false);
  results.clear();

  // Release KeyA.
  key_state.Set(kVirtualKeyA, false);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  event->callback(false, event->user_data);
}

TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncToggledState) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // The NumLock is desynchronized by toggled on
  key_state.Set(VK_NUMLOCK, false, true);

  // Send a normal event
  key_state.Set(kVirtualKeyA, true);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 3);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);

  event = &results[2];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Test if the NumLock is mis-toggled while it should also be pressed
  key_state.Set(VK_NUMLOCK, true, true);

  // Send a normal event
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYDOWN, 'a', false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, true);
  EXPECT_EQ(results.size(), 2);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeRepeat);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "a");
  EXPECT_EQ(event->synthesized, false);

  event->callback(false, event->user_data);
  EXPECT_EQ(last_handled, false);
  results.clear();

  // Numlock is pressed at this moment.

  // Test if the NumLock is mis-toggled while it should also be released
  key_state.Set(VK_NUMLOCK, false, false);

  // Send a normal event
  key_state.Set(kVirtualKeyA, false);
  handler->KeyboardHook(
      kVirtualKeyA, kScanCodeKeyA, WM_KEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 4);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[2];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[3];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalKeyA);
  EXPECT_EQ(event->logical, kLogicalKeyA);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  event->callback(false, event->user_data);
}

TEST(KeyboardKeyEmbedderHandlerTest,
     SynthesizeForDesyncToggledStateByItselfsUp) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // When NumLock is down
  key_state.Set(VK_NUMLOCK, true, true);
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  event = &results.back();
  event->callback(false, event->user_data);
  results.clear();

  // Numlock is desynchronized by being off and released
  key_state.Set(VK_NUMLOCK, false, false);
  // Send a NumLock key up
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYUP, 0, true, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 3);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[2];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  last_handled = false;
  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
}

TEST(KeyboardKeyEmbedderHandlerTest,
     SynthesizeForDesyncToggledStateByItselfsDown) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  // NumLock is started up and disabled
  key_state.Set(VK_NUMLOCK, false, false);
  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // NumLock is toggled somewhere else
  // key_state.Set(VK_NUMLOCK, false, true);

  // NumLock is pressed
  key_state.Set(VK_NUMLOCK, true, false);
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 3);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[1];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, true);
  EXPECT_EQ(event->callback, nullptr);

  event = &results[2];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  last_handled = false;
  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
}

TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeWithInitialTogglingState) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  // The app starts with NumLock toggled on
  key_state.Set(VK_NUMLOCK, false, true);

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // NumLock key down
  key_state.Set(VK_NUMLOCK, true, false);
  handler->KeyboardHook(
      VK_NUMLOCK, kScanCodeNumLock, WM_KEYDOWN, 0, true, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = &results[0];
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalNumLock);
  EXPECT_EQ(event->logical, kLogicalNumLock);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();
}

TEST(KeyboardKeyEmbedderHandlerTest, SysKeyPress) {
  TestKeystate key_state;
  std::vector<TestFlutterKeyEvent> results;
  TestFlutterKeyEvent* event;
  bool last_handled = false;

  std::unique_ptr<KeyboardKeyEmbedderHandler> handler =
      std::make_unique<KeyboardKeyEmbedderHandler>(
          [&results](const FlutterKeyEvent& event,
                     FlutterKeyEventCallback callback, void* user_data) {
            results.emplace_back(event, callback, user_data);
          },
          key_state.Getter(), DefaultMapVkToScan);

  // Press KeyAltLeft.
  key_state.Set(VK_LMENU, true);
  handler->KeyboardHook(
      VK_LMENU, kScanCodeAltLeft, WM_SYSKEYDOWN, 0, false, false,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(last_handled, false);
  EXPECT_EQ(results.size(), 1);
  event = results.data();
  EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
  EXPECT_EQ(event->physical, kPhysicalAltLeft);
  EXPECT_EQ(event->logical, kLogicalAltLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);

  event->callback(true, event->user_data);
  EXPECT_EQ(last_handled, true);
  results.clear();

  // Release KeyAltLeft.
  key_state.Set(VK_LMENU, false);
  handler->KeyboardHook(
      VK_LMENU, kScanCodeAltLeft, WM_SYSKEYUP, 0, false, true,
      [&last_handled](bool handled) { last_handled = handled; });
  EXPECT_EQ(results.size(), 1);
  event = results.data();
  EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
  EXPECT_EQ(event->physical, kPhysicalAltLeft);
  EXPECT_EQ(event->logical, kLogicalAltLeft);
  EXPECT_STREQ(event->character, "");
  EXPECT_EQ(event->synthesized, false);
  event->callback(false, event->user_data);
}

}  // namespace testing
}  // namespace flutter
