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

#include <memory>
#include <vector>

#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_result_functions.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/testing/flutter_windows_engine_builder.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler.h"
#include "flutter/shell/platform/windows/testing/test_binary_messenger.h"
#include "flutter/shell/platform/windows/testing/windows_test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

namespace {
using ::testing::_;
using ::testing::NotNull;
using ::testing::Return;

static constexpr char kChannelName[] = "flutter/mousecursor";

static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
static constexpr char kCreateCustomCursorMethod[] =
    "createCustomCursor/windows";
static constexpr char kSetCustomCursorMethod[] = "setCustomCursor/windows";
static constexpr char kDeleteCustomCursorMethod[] =
    "deleteCustomCursor/windows";

void SimulateCursorMessage(TestBinaryMessenger* messenger,
                           const std::string& method_name,
                           std::unique_ptr<EncodableValue> arguments,
                           MethodResult<EncodableValue>* result_handler) {
  MethodCall<> call(method_name, std::move(arguments));

  auto message = StandardMethodCodec::GetInstance().EncodeMethodCall(call);

  EXPECT_TRUE(messenger->SimulateEngineMessage(
      kChannelName, message->data(), message->size(),
      [&result_handler](const uint8_t* reply, size_t reply_size) {
        StandardMethodCodec::GetInstance().DecodeAndProcessResponseEnvelope(
            reply, reply_size, result_handler);
      }));
}

}  // namespace

class CursorHandlerTest : public WindowsTest {
 protected:
  FlutterWindowsEngine* engine() { return engine_.get(); }
  FlutterWindowsView* view() { return view_.get(); }
  MockWindowBindingHandler* window() { return window_; }

  void use_headless_engine() {
    FlutterWindowsEngineBuilder builder{GetContext()};

    engine_ = builder.Build();
  }

  void use_engine_with_view() {
    FlutterWindowsEngineBuilder builder{GetContext()};

    auto window = std::make_unique<MockWindowBindingHandler>();

    window_ = window.get();
    EXPECT_CALL(*window_, SetView).Times(1);
    EXPECT_CALL(*window_, GetRenderTarget).WillOnce(Return(nullptr));

    engine_ = builder.Build();
    view_ = std::make_unique<FlutterWindowsView>(std::move(window));

    engine_->SetView(view_.get());
  }

 private:
  std::unique_ptr<FlutterWindowsEngine> engine_;
  std::unique_ptr<FlutterWindowsView> view_;
  MockWindowBindingHandler* window_;
};

TEST_F(CursorHandlerTest, ActivateSystemCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  EXPECT_CALL(*window(), UpdateFlutterCursor("click")).Times(1);

  bool success = false;
  MethodResultFunctions<> result_handler(
      [&success](const EncodableValue* result) {
        success = true;
        EXPECT_EQ(result, nullptr);
      },
      nullptr, nullptr);

  SimulateCursorMessage(&messenger, kActivateSystemCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("device"), EncodableValue(0)},
                            {EncodableValue("kind"), EncodableValue("click")},
                        }),
                        &result_handler);

  EXPECT_TRUE(success);
}

TEST_F(CursorHandlerTest, ActivateSystemCursorRequiresView) {
  use_headless_engine();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  bool error = false;
  MethodResultFunctions<> result_handler(
      nullptr,
      [&error](const std::string& error_code, const std::string& error_message,
               const EncodableValue* value) {
        error = true;
        EXPECT_EQ(error_message,
                  "Cursor is not available in Windows headless mode");
      },
      nullptr);

  SimulateCursorMessage(&messenger, kActivateSystemCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("device"), EncodableValue(0)},
                            {EncodableValue("kind"), EncodableValue("click")},
                        }),
                        &result_handler);

  EXPECT_TRUE(error);
}

TEST_F(CursorHandlerTest, CreateCustomCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  // Create a 4x4 raw BGRA test cursor buffer.
  std::vector<uint8_t> buffer(4 * 4 * 4, 0);

  bool success = false;
  MethodResultFunctions<> result_handler(
      [&success](const EncodableValue* result) {
        success = true;
        EXPECT_EQ(std::get<std::string>(*result), "hello");
      },
      nullptr, nullptr);

  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                            {EncodableValue("buffer"), EncodableValue(buffer)},
                            {EncodableValue("width"), EncodableValue(4)},
                            {EncodableValue("height"), EncodableValue(4)},
                            {EncodableValue("hotX"), EncodableValue(0.0)},
                            {EncodableValue("hotY"), EncodableValue(0.0)},
                        }),
                        &result_handler);

  EXPECT_TRUE(success);
}

TEST_F(CursorHandlerTest, SetCustomCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  // Create a 4x4 raw BGRA test cursor buffer.
  std::vector<uint8_t> buffer(4 * 4 * 4, 0);

  bool success = false;
  MethodResultFunctions<> create_result_handler(nullptr, nullptr, nullptr);
  MethodResultFunctions<> set_result_handler(
      [&success](const EncodableValue* result) {
        success = true;
        EXPECT_EQ(result, nullptr);
      },
      nullptr, nullptr);

  EXPECT_CALL(*window(), SetFlutterCursor(/*cursor=*/NotNull())).Times(1);

  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                            {EncodableValue("buffer"), EncodableValue(buffer)},
                            {EncodableValue("width"), EncodableValue(4)},
                            {EncodableValue("height"), EncodableValue(4)},
                            {EncodableValue("hotX"), EncodableValue(0.0)},
                            {EncodableValue("hotY"), EncodableValue(0.0)},
                        }),
                        &create_result_handler);

  SimulateCursorMessage(&messenger, kSetCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                        }),
                        &set_result_handler);

  EXPECT_TRUE(success);
}

TEST_F(CursorHandlerTest, SetCustomCursorRequiresView) {
  use_headless_engine();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  // Create a 4x4 raw BGRA test cursor buffer.
  std::vector<uint8_t> buffer(4 * 4 * 4, 0);

  bool error = false;
  MethodResultFunctions<> create_result_handler(nullptr, nullptr, nullptr);
  MethodResultFunctions<> set_result_handler(
      nullptr,
      [&error](const std::string& error_code, const std::string& error_message,
               const EncodableValue* value) {
        error = true;
        EXPECT_EQ(error_message,
                  "Cursor is not available in Windows headless mode");
      },
      nullptr);

  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                            {EncodableValue("buffer"), EncodableValue(buffer)},
                            {EncodableValue("width"), EncodableValue(4)},
                            {EncodableValue("height"), EncodableValue(4)},
                            {EncodableValue("hotX"), EncodableValue(0.0)},
                            {EncodableValue("hotY"), EncodableValue(0.0)},
                        }),
                        &create_result_handler);

  SimulateCursorMessage(&messenger, kSetCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                        }),
                        &set_result_handler);

  EXPECT_TRUE(error);
}

TEST_F(CursorHandlerTest, SetNonexistentCustomCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  bool error = false;
  MethodResultFunctions<> result_handler(
      nullptr,
      [&error](const std::string& error_code, const std::string& error_message,
               const EncodableValue* value) {
        error = true;
        EXPECT_EQ(
            error_message,
            "The custom cursor identified by the argument key cannot be found");
      },
      nullptr);

  EXPECT_CALL(*window(), SetFlutterCursor).Times(0);

  SimulateCursorMessage(&messenger, kSetCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                        }),
                        &result_handler);

  EXPECT_TRUE(error);
}

TEST_F(CursorHandlerTest, DeleteCustomCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  // Create a 4x4 raw BGRA test cursor buffer.
  std::vector<uint8_t> buffer(4 * 4 * 4, 0);

  bool success = false;
  MethodResultFunctions<> create_result_handler(nullptr, nullptr, nullptr);
  MethodResultFunctions<> delete_result_handler(
      [&success](const EncodableValue* result) {
        success = true;
        EXPECT_EQ(result, nullptr);
      },
      nullptr, nullptr);

  SimulateCursorMessage(&messenger, kCreateCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                            {EncodableValue("buffer"), EncodableValue(buffer)},
                            {EncodableValue("width"), EncodableValue(4)},
                            {EncodableValue("height"), EncodableValue(4)},
                            {EncodableValue("hotX"), EncodableValue(0.0)},
                            {EncodableValue("hotY"), EncodableValue(0.0)},
                        }),
                        &create_result_handler);

  SimulateCursorMessage(&messenger, kDeleteCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("hello")},
                        }),
                        &delete_result_handler);

  EXPECT_TRUE(success);
}

TEST_F(CursorHandlerTest, DeleteNonexistentCustomCursor) {
  use_engine_with_view();

  TestBinaryMessenger messenger;
  CursorHandler cursor_handler(&messenger, engine());

  bool success = false;
  MethodResultFunctions<> result_handler(
      [&success](const EncodableValue* result) {
        success = true;
        EXPECT_EQ(result, nullptr);
      },
      nullptr, nullptr);

  SimulateCursorMessage(&messenger, kDeleteCustomCursorMethod,
                        std::make_unique<EncodableValue>(EncodableMap{
                            {EncodableValue("name"), EncodableValue("fake")},
                        }),
                        &result_handler);

  EXPECT_TRUE(success);
}

}  // namespace testing
}  // namespace flutter
