// 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 <memory>
#include <string>

#include "flutter/shell/platform/windows/client_wrapper/include/flutter/plugin_registrar_windows.h"
#include "flutter/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h"
#include "gtest/gtest.h"

namespace flutter {

namespace {

// Stub implementation to validate calls to the API.
class TestWindowsApi : public testing::StubFlutterWindowsApi {
 public:
  void PluginRegistrarRegisterTopLevelWindowProcDelegate(
      FlutterDesktopWindowProcCallback delegate,
      void* user_data) override {
    ++registered_delegate_count_;
    last_registered_delegate_ = delegate;
    last_registered_user_data_ = user_data;
  }

  void PluginRegistrarUnregisterTopLevelWindowProcDelegate(
      FlutterDesktopWindowProcCallback delegate) override {
    --registered_delegate_count_;
  }

  int registered_delegate_count() { return registered_delegate_count_; }

  FlutterDesktopWindowProcCallback last_registered_delegate() {
    return last_registered_delegate_;
  }

  void* last_registered_user_data() { return last_registered_user_data_; }

 private:
  int registered_delegate_count_ = 0;
  FlutterDesktopWindowProcCallback last_registered_delegate_ = nullptr;
  void* last_registered_user_data_ = nullptr;
};

// A test plugin that tries to access registrar state during destruction and
// reports it out via a flag provided at construction.
class TestPlugin : public Plugin {
 public:
  // registrar_valid_at_destruction will be set at destruction to indicate
  // whether or not |registrar->GetView()| was non-null.
  TestPlugin(PluginRegistrarWindows* registrar,
             bool* registrar_valid_at_destruction)
      : registrar_(registrar),
        registrar_valid_at_destruction_(registrar_valid_at_destruction) {}
  virtual ~TestPlugin() {
    *registrar_valid_at_destruction_ = registrar_->GetView() != nullptr;
  }

 private:
  PluginRegistrarWindows* registrar_;
  bool* registrar_valid_at_destruction_;
};

}  // namespace

TEST(PluginRegistrarWindowsTest, GetView) {
  testing::ScopedStubFlutterWindowsApi scoped_api_stub(
      std::make_unique<TestWindowsApi>());
  auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
  PluginRegistrarWindows registrar(
      reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));
  EXPECT_NE(registrar.GetView(), nullptr);
}

// Tests that the registrar runs plugin destructors before its own teardown.
TEST(PluginRegistrarWindowsTest, PluginDestroyedBeforeRegistrar) {
  auto dummy_registrar_handle =
      reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1);
  bool registrar_valid_at_destruction = false;
  {
    PluginRegistrarWindows registrar(dummy_registrar_handle);

    auto plugin = std::make_unique<TestPlugin>(&registrar,
                                               &registrar_valid_at_destruction);
    registrar.AddPlugin(std::move(plugin));
  }
  EXPECT_TRUE(registrar_valid_at_destruction);
}

TEST(PluginRegistrarWindowsTest, RegisterUnregister) {
  testing::ScopedStubFlutterWindowsApi scoped_api_stub(
      std::make_unique<TestWindowsApi>());
  auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
  PluginRegistrarWindows registrar(
      reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));

  WindowProcDelegate delegate = [](HWND hwnd, UINT message, WPARAM wparam,
                                   LPARAM lparam) {
    return std::optional<LRESULT>();
  };
  int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate);
  EXPECT_EQ(test_api->registered_delegate_count(), 1);
  int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate);
  // All the C++-level delegates are driven by a since C callback, so the
  // registration count should stay the same.
  EXPECT_EQ(test_api->registered_delegate_count(), 1);

  // Unregistering one of the two delegates shouldn't cause the underlying C
  // callback to be unregistered.
  registrar.UnregisterTopLevelWindowProcDelegate(id_a);
  EXPECT_EQ(test_api->registered_delegate_count(), 1);
  // Unregistering both should unregister it.
  registrar.UnregisterTopLevelWindowProcDelegate(id_b);
  EXPECT_EQ(test_api->registered_delegate_count(), 0);

  EXPECT_NE(id_a, id_b);
}

TEST(PluginRegistrarWindowsTest, CallsRegisteredDelegates) {
  testing::ScopedStubFlutterWindowsApi scoped_api_stub(
      std::make_unique<TestWindowsApi>());
  auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
  PluginRegistrarWindows registrar(
      reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));

  HWND dummy_hwnd;
  bool called_a = false;
  WindowProcDelegate delegate_a = [&called_a, &dummy_hwnd](
                                      HWND hwnd, UINT message, WPARAM wparam,
                                      LPARAM lparam) {
    called_a = true;
    EXPECT_EQ(hwnd, dummy_hwnd);
    EXPECT_EQ(message, 2);
    EXPECT_EQ(wparam, 3);
    EXPECT_EQ(lparam, 4);
    return std::optional<LRESULT>();
  };
  bool called_b = false;
  WindowProcDelegate delegate_b = [&called_b](HWND hwnd, UINT message,
                                              WPARAM wparam, LPARAM lparam) {
    called_b = true;
    return std::optional<LRESULT>();
  };
  int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate_a);
  int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate_b);

  LRESULT result = 0;
  bool handled = test_api->last_registered_delegate()(
      dummy_hwnd, 2, 3, 4, test_api->last_registered_user_data(), &result);
  EXPECT_TRUE(called_a);
  EXPECT_TRUE(called_b);
  EXPECT_FALSE(handled);
}

TEST(PluginRegistrarWindowsTest, StopsOnceHandled) {
  testing::ScopedStubFlutterWindowsApi scoped_api_stub(
      std::make_unique<TestWindowsApi>());
  auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());
  PluginRegistrarWindows registrar(
      reinterpret_cast<FlutterDesktopPluginRegistrarRef>(1));

  bool called_a = false;
  WindowProcDelegate delegate_a = [&called_a](HWND hwnd, UINT message,
                                              WPARAM wparam, LPARAM lparam) {
    called_a = true;
    return std::optional<LRESULT>(7);
  };
  bool called_b = false;
  WindowProcDelegate delegate_b = [&called_b](HWND hwnd, UINT message,
                                              WPARAM wparam, LPARAM lparam) {
    called_b = true;
    return std::optional<LRESULT>(7);
  };
  int id_a = registrar.RegisterTopLevelWindowProcDelegate(delegate_a);
  int id_b = registrar.RegisterTopLevelWindowProcDelegate(delegate_b);

  HWND dummy_hwnd;
  LRESULT result = 0;
  bool handled = test_api->last_registered_delegate()(
      dummy_hwnd, 2, 3, 4, test_api->last_registered_user_data(), &result);
  // Only one of the delegates should have been called, since each claims to
  // have fully handled the message.
  EXPECT_TRUE(called_a || called_b);
  EXPECT_NE(called_a, called_b);
  // The return value should propagate through.
  EXPECT_TRUE(handled);
  EXPECT_EQ(result, 7);
}

}  // namespace flutter
