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

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

#include "flutter/fml/macros.h"
#include "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/common/json_method_codec.h"
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
#include "flutter/shell/platform/windows/text_input_plugin_delegate.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 constexpr char kTextPlainFormat[] = "text/plain";
// Should be identical to constants in text_input_plugin.cc.
static constexpr char kChannelName[] = "flutter/textinput";
static constexpr char kEnableDeltaModel[] = "enableDeltaModel";
static constexpr char kSetClientMethod[] = "TextInput.setClient";

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);
}

class MockTextInputPluginDelegate : public TextInputPluginDelegate {
 public:
  MockTextInputPluginDelegate() {}
  virtual ~MockTextInputPluginDelegate() = default;

  MOCK_METHOD1(OnCursorRectUpdated, void(const Rect&));
  MOCK_METHOD0(OnResetImeComposing, void());

 private:
  FML_DISALLOW_COPY_AND_ASSIGN(MockTextInputPluginDelegate);
};

}  // namespace

TEST(TextInputPluginTest, TextMethodsWorksWithEmptyModel) {
  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) {});
  MockTextInputPluginDelegate delegate;

  int redispatch_scancode = 0;
  TextInputPlugin handler(&messenger, &delegate);

  handler.KeyboardHook(VK_RETURN, 100, WM_KEYDOWN, '\n', false, false);
  handler.ComposeBeginHook();
  std::u16string text;
  text.push_back('\n');
  handler.ComposeChangeHook(text, 1);
  handler.ComposeEndHook();

  // Passes if it did not crash
}

TEST(TextInputPluginTest, ClearClientResetsComposing) {
  TestBinaryMessenger messenger([](const std::string& channel,
                                   const uint8_t* message, size_t message_size,
                                   BinaryReply reply) {});
  BinaryReply reply_handler = [](const uint8_t* reply, size_t reply_size) {};

  MockTextInputPluginDelegate delegate;
  TextInputPlugin handler(&messenger, &delegate);

  EXPECT_CALL(delegate, OnResetImeComposing());

  auto& codec = JsonMethodCodec::GetInstance();
  auto message = codec.EncodeMethodCall({"TextInput.clearClient", nullptr});
  messenger.SimulateEngineMessage(kChannelName, message->data(),
                                  message->size(), reply_handler);
}

// Verify that the embedder sends state update messages to the framework during
// IME composing.
TEST(TextInputPluginTest, VerifyComposingSendStateUpdate) {
  bool sent_message = false;
  TestBinaryMessenger messenger(
      [&sent_message](const std::string& channel, const uint8_t* message,
                      size_t message_size,
                      BinaryReply reply) { sent_message = true; });
  BinaryReply reply_handler = [](const uint8_t* reply, size_t reply_size) {};

  MockTextInputPluginDelegate delegate;
  TextInputPlugin handler(&messenger, &delegate);

  auto& codec = JsonMethodCodec::GetInstance();

  // Call TextInput.setClient to initialize the TextInputModel.
  auto arguments = std::make_unique<rapidjson::Document>(rapidjson::kArrayType);
  auto& allocator = arguments->GetAllocator();
  arguments->PushBack(42, allocator);
  rapidjson::Value config(rapidjson::kObjectType);
  config.AddMember("inputAction", "done", allocator);
  config.AddMember("inputType", "text", allocator);
  config.AddMember(kEnableDeltaModel, false, allocator);
  arguments->PushBack(config, allocator);
  auto message =
      codec.EncodeMethodCall({"TextInput.setClient", std::move(arguments)});
  messenger.SimulateEngineMessage("flutter/textinput", message->data(),
                                  message->size(), reply_handler);

  // ComposeBeginHook should send state update.
  sent_message = false;
  handler.ComposeBeginHook();
  EXPECT_TRUE(sent_message);

  // ComposeChangeHook should send state update.
  sent_message = false;
  handler.ComposeChangeHook(u"4", 1);
  EXPECT_TRUE(sent_message);

  // ComposeCommitHook should NOT send state update.
  //
  // Commit messages are always immediately followed by a change message or an
  // end message, both of which will send an update. Sending intermediate state
  // with a collapsed composing region will trigger the framework to assume
  // composing has ended, which is not the case until a WM_IME_ENDCOMPOSING
  // event is received in the main event loop, which will trigger a call to
  // ComposeEndHook.
  sent_message = false;
  handler.ComposeCommitHook();
  EXPECT_FALSE(sent_message);

  // ComposeEndHook should send state update.
  sent_message = false;
  handler.ComposeEndHook();
  EXPECT_TRUE(sent_message);
}

TEST(TextInputPluginTest, TextEditingWorksWithDeltaModel) {
  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) {});
  MockTextInputPluginDelegate delegate;

  int redispatch_scancode = 0;
  TextInputPlugin handler(&messenger, &delegate);

  auto args = std::make_unique<rapidjson::Document>(rapidjson::kArrayType);
  auto& allocator = args->GetAllocator();
  args->PushBack(123, allocator);  // client_id

  rapidjson::Value client_config(rapidjson::kObjectType);
  client_config.AddMember(kEnableDeltaModel, true, allocator);

  args->PushBack(client_config, allocator);
  auto encoded = JsonMethodCodec::GetInstance().EncodeMethodCall(
      MethodCall<rapidjson::Document>(kSetClientMethod, std::move(args)));

  EXPECT_TRUE(messenger.SimulateEngineMessage(
      kChannelName, encoded->data(), encoded->size(),
      [](const uint8_t* reply, size_t reply_size) {}));

  handler.KeyboardHook(VK_RETURN, 100, WM_KEYDOWN, '\n', false, false);
  handler.ComposeBeginHook();
  std::u16string text;
  text.push_back('\n');
  handler.ComposeChangeHook(text, 1);
  handler.ComposeEndHook();

  handler.KeyboardHook(0x4E, 100, WM_KEYDOWN, 'n', false, false);
  handler.ComposeBeginHook();
  std::u16string textN;
  text.push_back('n');
  handler.ComposeChangeHook(textN, 1);
  handler.KeyboardHook(0x49, 100, WM_KEYDOWN, 'i', false, false);
  std::u16string textNi;
  text.push_back('n');
  text.push_back('i');
  handler.ComposeChangeHook(textNi, 2);
  handler.KeyboardHook(VK_RETURN, 100, WM_KEYDOWN, '\n', false, false);
  std::u16string textChineseCharacter;
  text.push_back(u'\u4F60');
  handler.ComposeChangeHook(textChineseCharacter, 1);
  handler.ComposeCommitHook();
  handler.ComposeEndHook();

  // Passes if it did not crash
}

TEST(TextInputPluginTest, TransformCursorRect) {
  // A position of `EditableText`.
  double view_x = 100;
  double view_y = 200;

  // A position and size of marked text, in `EditableText` local coordinates.
  double ime_x = 3;
  double ime_y = 4;
  double ime_width = 50;
  double ime_height = 60;

  // Transformation matrix.
  std::array<std::array<double, 4>, 4> editabletext_transform = {
      1.0, 0.0, 0.0, view_x,  //
      0.0, 1.0, 0.0, view_y,  //
      0.0, 0.0, 0.0, 0.0,     //
      0.0, 0.0, 0.0, 1.0};

  TestBinaryMessenger messenger([](const std::string& channel,
                                   const uint8_t* message, size_t message_size,
                                   BinaryReply reply) {});
  BinaryReply reply_handler = [](const uint8_t* reply, size_t reply_size) {};

  MockTextInputPluginDelegate delegate;
  TextInputPlugin handler(&messenger, &delegate);

  auto& codec = JsonMethodCodec::GetInstance();

  EXPECT_CALL(delegate, OnCursorRectUpdated(Rect{{view_x, view_y}, {0, 0}}));

  {
    auto arguments =
        std::make_unique<rapidjson::Document>(rapidjson::kObjectType);
    auto& allocator = arguments->GetAllocator();

    rapidjson::Value transoform(rapidjson::kArrayType);
    for (int i = 0; i < 4 * 4; i++) {
      // Pack 2-dimensional array by column-major order.
      transoform.PushBack(editabletext_transform[i % 4][i / 4], allocator);
    }

    arguments->AddMember("transform", transoform, allocator);

    auto message = codec.EncodeMethodCall(
        {"TextInput.setEditableSizeAndTransform", std::move(arguments)});
    messenger.SimulateEngineMessage(kChannelName, message->data(),
                                    message->size(), reply_handler);
  }

  EXPECT_CALL(delegate,
              OnCursorRectUpdated(Rect{{view_x + ime_x, view_y + ime_y},
                                       {ime_width, ime_height}}));

  {
    auto arguments =
        std::make_unique<rapidjson::Document>(rapidjson::kObjectType);
    auto& allocator = arguments->GetAllocator();

    arguments->AddMember("x", ime_x, allocator);
    arguments->AddMember("y", ime_y, allocator);
    arguments->AddMember("width", ime_width, allocator);
    arguments->AddMember("height", ime_height, allocator);

    auto message = codec.EncodeMethodCall(
        {"TextInput.setMarkedTextRect", std::move(arguments)});
    messenger.SimulateEngineMessage(kChannelName, message->data(),
                                    message->size(), reply_handler);
  }
}

}  // namespace testing
}  // namespace flutter
