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

#include <rapidjson/document.h>
#include <memory>

#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

namespace {

static constexpr int kHandledScanCode = 20;
static constexpr int kHandledScanCode2 = 22;
static constexpr int kUnhandledScanCode = 21;

constexpr uint64_t kScanCodeShiftRight = 0x36;
constexpr uint64_t kScanCodeControlLeft = 0x1D;
constexpr uint64_t kScanCodeAltLeft = 0x38;

typedef std::function<void(bool)> Callback;
typedef std::function<void(Callback&)> CallbackHandler;
void dont_respond(Callback& callback) {}
void respond_true(Callback& callback) {
  callback(true);
}
void respond_false(Callback& callback) {
  callback(false);
}

// A testing |KeyHandlerDelegate| that records all calls
// to |KeyboardHook| and can be customized with whether
// the hook is handled in async.
class MockKeyHandlerDelegate
    : public KeyboardKeyHandler::KeyboardKeyHandlerDelegate {
 public:
  class KeyboardHookCall {
   public:
    int delegate_id;
    int key;
    int scancode;
    int action;
    char32_t character;
    bool extended;
    bool was_down;
    std::function<void(bool)> callback;
  };

  // Create a |MockKeyHandlerDelegate|.
  //
  // The |delegate_id| is an arbitrary ID to tell between delegates
  // that will be recorded in |KeyboardHookCall|.
  //
  // The |hook_history| will store every call to |KeyboardHookCall| that are
  // handled asynchronously.
  //
  // The |is_async| is a function that the class calls upon every
  // |KeyboardHookCall| to decide whether the call is handled asynchronously.
  // Defaults to always returning true (async).
  MockKeyHandlerDelegate(int delegate_id,
                         std::list<KeyboardHookCall>* hook_history)
      : delegate_id(delegate_id),
        hook_history(hook_history),
        callback_handler(dont_respond) {}
  virtual ~MockKeyHandlerDelegate() = default;

  virtual void KeyboardHook(int key,
                            int scancode,
                            int action,
                            char32_t character,
                            bool extended,
                            bool was_down,
                            std::function<void(bool)> callback) {
    hook_history->push_back(KeyboardHookCall{
        .delegate_id = delegate_id,
        .key = key,
        .scancode = scancode,
        .character = character,
        .extended = extended,
        .was_down = was_down,
        .callback = std::move(callback),
    });
    callback_handler(hook_history->back().callback);
  }

  CallbackHandler callback_handler;
  int delegate_id;
  std::list<KeyboardHookCall>* hook_history;
};

class TestKeyboardKeyHandler : public KeyboardKeyHandler {
 public:
  explicit TestKeyboardKeyHandler(EventDispatcher redispatch_event)
      : KeyboardKeyHandler(redispatch_event) {}

  bool HasRedispatched() { return RedispatchedCount() > 0; }
};

}  // namespace

TEST(KeyboardKeyHandlerTest, SingleDelegateWithAsyncResponds) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });
  // Add one delegate
  auto delegate = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  handler.AddDelegate(std::move(delegate));

  /// Test 1: One event that is handled by the framework

  // Dispatch a key event
  delegate_handled =
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.back().delegate_id, 1);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, true);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.back().callback(true);
  EXPECT_EQ(redispatch_scancode, 0);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.clear();

  /// Test 2: Two events that are unhandled by the framework

  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.back().delegate_id, 1);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  // Dispatch another key event
  delegate_handled =
      handler.KeyboardHook(65, kHandledScanCode2, WM_KEYUP, L'b', false, true);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.back().delegate_id, 1);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode2);
  EXPECT_EQ(hook_history.back().was_down, true);

  // Resolve the second event first to test out-of-order response
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode2);

  // Resolve the first event then
  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);

  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);
  EXPECT_EQ(
      handler.KeyboardHook(65, kHandledScanCode2, WM_KEYUP, L'b', false, false),
      false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.clear();
  redispatch_scancode = 0;
}

TEST(KeyboardKeyHandlerTest, SingleDelegateWithSyncResponds) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });
  // Add one delegate
  auto delegate = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  CallbackHandler& delegate_handler = delegate->callback_handler;
  handler.AddDelegate(std::move(delegate));

  /// Test 1: One event that is handled by the framework

  // Dispatch a key event
  delegate_handler = respond_true;
  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.back().delegate_id, 1);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.clear();

  /// Test 2: An event unhandled by the framework

  delegate_handler = respond_false;
  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.back().delegate_id, 1);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  EXPECT_EQ(handler.HasRedispatched(), true);

  // Resolve the event
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.clear();
  redispatch_scancode = 0;
}

TEST(KeyboardKeyHandlerTest, WithTwoAsyncDelegates) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });

  auto delegate1 = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  CallbackHandler& delegate1_handler = delegate1->callback_handler;
  handler.AddDelegate(std::move(delegate1));

  auto delegate2 = std::make_unique<MockKeyHandlerDelegate>(2, &hook_history);
  CallbackHandler& delegate2_handler = delegate2->callback_handler;
  handler.AddDelegate(std::move(delegate2));

  /// Test 1: One delegate responds true, the other false

  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().delegate_id, 1);
  EXPECT_EQ(hook_history.front().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.front().was_down, false);
  EXPECT_EQ(hook_history.back().delegate_id, 2);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  EXPECT_EQ(handler.HasRedispatched(), false);

  hook_history.back().callback(true);
  EXPECT_EQ(redispatch_scancode, 0);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, 0);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  /// Test 2: All delegates respond false

  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().delegate_id, 1);
  EXPECT_EQ(hook_history.front().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.front().was_down, false);
  EXPECT_EQ(hook_history.back().delegate_id, 2);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  EXPECT_EQ(handler.HasRedispatched(), false);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, 0);

  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);

  EXPECT_EQ(handler.HasRedispatched(), true);
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.clear();
  redispatch_scancode = 0;

  /// Test 3: All delegates responds true

  delegate_handled = handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN,
                                          L'a', false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().delegate_id, 1);
  EXPECT_EQ(hook_history.front().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.front().was_down, false);
  EXPECT_EQ(hook_history.back().delegate_id, 2);
  EXPECT_EQ(hook_history.back().scancode, kHandledScanCode);
  EXPECT_EQ(hook_history.back().was_down, false);

  EXPECT_EQ(handler.HasRedispatched(), false);

  hook_history.back().callback(true);
  EXPECT_EQ(redispatch_scancode, 0);
  // Only resolve after everyone has responded
  EXPECT_EQ(handler.HasRedispatched(), false);

  hook_history.front().callback(true);
  EXPECT_EQ(redispatch_scancode, 0);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}

// Regression test for a crash in an earlier implementation.
//
// In real life, the framework responds slowly. The next real event might
// arrive earlier than the framework response, and if the 2nd event is identical
// to the one waiting for response, an earlier implementation will crash upon
// the response.
TEST(KeyboardKeyHandlerTest, WithSlowFrameworkResponse) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });

  auto delegate1 = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  CallbackHandler& delegate1_handler = delegate1->callback_handler;
  handler.AddDelegate(std::move(delegate1));

  // The first native event.
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);

  // The second identical native event, received between the first and its
  // framework response.
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);

  EXPECT_EQ(handler.HasRedispatched(), false);

  // The first response.
  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);

  // Redispatch the first event.
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);
  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;

  // The second response.
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);

  // Redispatch the second event.
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}

// A key down event for shift right must not be redispatched even if
// the framework returns unhandled.
//
// The reason for this test is documented in |IsKeyDownShiftRight|.
TEST(KeyboardKeyHandlerTest, NeverRedispatchShiftRightKeyDown) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });

  auto delegate = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  delegate->callback_handler = respond_false;
  handler.AddDelegate(std::move(delegate));

  // Press ShiftRight and the delegate responds false.

  delegate_handled = handler.KeyboardHook(VK_RSHIFT, kScanCodeShiftRight,
                                          WM_KEYDOWN, 0, false, false);
  EXPECT_EQ(delegate_handled, true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}

TEST(KeyboardKeyHandlerTest, AltGr) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });

  auto delegate = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  delegate->callback_handler = dont_respond;
  handler.AddDelegate(std::move(delegate));

  // Sequence 1: Tap AltGr.

  // The key down event causes a ControlLeft down and a AltRight (extended
  // AltLeft) down.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            true);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.front().was_down, false);
  EXPECT_EQ(hook_history.back().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.back().was_down, false);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            false);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  // The key up event only causes a AltRight (extended AltLeft) up.
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      true);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.front().was_down, true);

  // A ControlLeft key up is synthesized.
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            true);

  EXPECT_EQ(hook_history.back().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.back().was_down, true);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            false);
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  // Sequence 2: Tap CtrlLeft and AltGr.
  // This also tests tapping AltGr twice in a row when combined with sequence
  // 1 since "tapping CtrlLeft and AltGr" only sends an extra CtrlLeft key up
  // than "tapping AltGr".

  // Key down ControlLeft.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.front().was_down, false);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  hook_history.clear();
  redispatch_scancode = 0;

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            false);

  // Key down AltRight.
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.front().was_down, false);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);
  hook_history.clear();

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            false);

  redispatch_scancode = 0;

  // Key up AltRight.
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      true);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.front().was_down, true);

  // A ControlLeft key up is synthesized.
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            true);

  EXPECT_EQ(hook_history.back().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.back().was_down, true);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            false);
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      false);

  hook_history.clear();
  redispatch_scancode = 0;

  // Key up ControlLeft should be dispatched to delegates, but will be properly
  // handled by delegates' logic.

  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.front().was_down, true);

  hook_history.front().callback(true);
  EXPECT_EQ(redispatch_scancode, 0);
  hook_history.clear();

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  // Sequence 3: Hold AltGr for repeated events.
  // Every AltGr key repeat event is also preceded by a ControlLeft down
  // (repeat).

  // Key down AltRight.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            true);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.front().was_down, false);
  EXPECT_EQ(hook_history.back().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.back().was_down, false);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            false);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  // Another key down AltRight.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, true),
            true);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, true),
            true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.front().was_down, true);
  EXPECT_EQ(hook_history.back().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.back().was_down, true);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYDOWN,
                                 0, false, false),
            false);
  EXPECT_EQ(handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYDOWN, 0,
                                 true, false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();

  // Key up AltRight.
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      true);
  EXPECT_EQ(hook_history.size(), 1);
  EXPECT_EQ(hook_history.front().scancode, kScanCodeAltLeft);
  EXPECT_EQ(hook_history.front().was_down, true);

  // A ControlLeft key up is synthesized.
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            true);

  EXPECT_EQ(hook_history.back().scancode, kScanCodeControlLeft);
  EXPECT_EQ(hook_history.back().was_down, true);

  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeAltLeft);
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kScanCodeControlLeft);

  // Resolve redispatches.
  EXPECT_EQ(handler.KeyboardHook(VK_LCONTROL, kScanCodeControlLeft, WM_KEYUP, 0,
                                 false, true),
            false);
  EXPECT_EQ(
      handler.KeyboardHook(VK_RMENU, kScanCodeAltLeft, WM_KEYUP, 0, true, true),
      false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}

}  // namespace testing
}  // namespace flutter
