// 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/key_event_handler.h"

#include <rapidjson/document.h>
#include <memory>

#include "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

namespace {
static constexpr char kScanCodeKey[] = "scanCode";
static constexpr int kHandledScanCode = 20;
static constexpr int kUnhandledScanCode = 21;

static std::unique_ptr<std::vector<uint8_t>> CreateResponse(bool handled) {
  auto response_doc =
      std::make_unique<rapidjson::Document>(rapidjson::kObjectType);
  auto& allocator = response_doc->GetAllocator();
  response_doc->AddMember("handled", handled, allocator);
  return JsonMessageCodec::GetInstance().EncodeMessage(*response_doc);
}

}  // namespace

TEST(KeyEventHandlerTest, KeyboardHookHandling) {
  auto handled_message = CreateResponse(true);
  auto unhandled_message = CreateResponse(false);
  int received_scancode = 0;

  TestBinaryMessenger messenger(
      [&received_scancode, &handled_message, &unhandled_message](
          const std::string& channel, const uint8_t* message,
          size_t message_size, BinaryReply reply) {
        if (channel == "flutter/keyevent") {
          auto message_doc = JsonMessageCodec::GetInstance().DecodeMessage(
              message, message_size);
          received_scancode = (*message_doc)[kScanCodeKey].GetInt();
          if (received_scancode == kHandledScanCode) {
            reply(handled_message->data(), handled_message->size());
          } else {
            reply(unhandled_message->data(), unhandled_message->size());
          }
        }
      });

  int redispatch_scancode = 0;
  KeyEventHandler handler(&messenger,
                          [&redispatch_scancode](UINT cInputs, LPINPUT pInputs,
                                                 int cbSize) -> UINT {
                            EXPECT_TRUE(cbSize > 0);
                            redispatch_scancode = pInputs->ki.wScan;
                            return 1;
                          });

  handler.KeyboardHook(nullptr, 64, kHandledScanCode, WM_KEYDOWN, L'a', false);
  EXPECT_EQ(received_scancode, kHandledScanCode);
  EXPECT_EQ(redispatch_scancode, 0);
  received_scancode = 0;
  handler.KeyboardHook(nullptr, 64, kUnhandledScanCode, WM_KEYDOWN, L'b',
                       false);
  EXPECT_EQ(received_scancode, kUnhandledScanCode);
  EXPECT_EQ(redispatch_scancode, kUnhandledScanCode);
}

TEST(KeyEventHandlerTest, ExtendedKeysAreSentToRedispatch) {
  auto handled_message = CreateResponse(true);
  auto unhandled_message = CreateResponse(false);
  int received_scancode = 0;
  bool is_extended_key = false;

  TestBinaryMessenger messenger(
      [&received_scancode, &handled_message, &unhandled_message](
          const std::string& channel, const uint8_t* message,
          size_t message_size, BinaryReply reply) {
        if (channel == "flutter/keyevent") {
          auto message_doc = JsonMessageCodec::GetInstance().DecodeMessage(
              message, message_size);
          received_scancode = (*message_doc)[kScanCodeKey].GetInt();
          if (received_scancode == kHandledScanCode) {
            reply(handled_message->data(), handled_message->size());
          } else {
            reply(unhandled_message->data(), unhandled_message->size());
          }
        }
      });

  int redispatch_scancode = 0;
  KeyEventHandler handler(
      &messenger,
      [&redispatch_scancode, &is_extended_key](UINT cInputs, LPINPUT pInputs,
                                               int cbSize) -> UINT {
        EXPECT_TRUE(cbSize > 0);
        redispatch_scancode = pInputs->ki.wScan;
        is_extended_key = (pInputs->ki.dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
        return 1;
      });

  // Extended key flag is passed to redispatched events if set.
  handler.KeyboardHook(nullptr, 64, kUnhandledScanCode, WM_KEYDOWN, L'b', true);
  EXPECT_EQ(received_scancode, kUnhandledScanCode);
  EXPECT_EQ(redispatch_scancode, kUnhandledScanCode);
  EXPECT_EQ(is_extended_key, true);

  // Extended key flag is not passed to redispatched events if not set.
  handler.KeyboardHook(nullptr, 64, kUnhandledScanCode, WM_KEYDOWN, L'b',
                       false);
  EXPECT_EQ(received_scancode, kUnhandledScanCode);
  EXPECT_EQ(redispatch_scancode, kUnhandledScanCode);
  EXPECT_EQ(is_extended_key, false);
}

}  // namespace testing
}  // namespace flutter
