// 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/window_proc_delegate_manager.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

namespace {

#ifdef _WIN32
#define FLUTTER_NOINLINE __declspec(noinline)
#else
#define FLUTTER_NOINLINE __attribute__((noinline))
#endif

using TestWindowProcDelegate = std::function<std::optional<
    LRESULT>(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)>;

// A FlutterDesktopWindowProcCallback that forwards to a std::function provided
// as user_data.
FLUTTER_NOINLINE
bool TestWindowProcCallback(HWND hwnd,
                            UINT message,
                            WPARAM wparam,
                            LPARAM lparam,
                            void* user_data,
                            LRESULT* result) {
  TestWindowProcDelegate& delegate =
      *static_cast<TestWindowProcDelegate*>(user_data);
  auto delegate_result = delegate(hwnd, message, wparam, lparam);
  if (delegate_result) {
    *result = *delegate_result;
  }
  return delegate_result.has_value();
}

// Same as the above, but with a different address, to test multiple
// registration.
bool TestWindowProcCallback2(HWND hwnd,
                             UINT message,
                             WPARAM wparam,
                             LPARAM lparam,
                             void* user_data,
                             LRESULT* result) {
  return TestWindowProcCallback(hwnd, message, wparam, lparam, user_data,
                                result);
}

}  // namespace

TEST(WindowProcDelegateManagerTest, CallsCorrectly) {
  WindowProcDelegateManager manager;
  HWND dummy_hwnd;

  bool called = false;
  TestWindowProcDelegate delegate = [&called, &dummy_hwnd](
                                        HWND hwnd, UINT message, WPARAM wparam,
                                        LPARAM lparam) {
    called = true;
    EXPECT_EQ(hwnd, dummy_hwnd);
    EXPECT_EQ(message, 2);
    EXPECT_EQ(wparam, 3);
    EXPECT_EQ(lparam, 4);
    return std::optional<LRESULT>();
  };
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback, &delegate);
  auto result = manager.OnTopLevelWindowProc(dummy_hwnd, 2, 3, 4);

  EXPECT_TRUE(called);
  EXPECT_FALSE(result);
}

TEST(WindowProcDelegateManagerTest, ReplacementRegister) {
  WindowProcDelegateManager manager;

  bool called_a = false;
  TestWindowProcDelegate delegate_a =
      [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_a = true;
        return std::optional<LRESULT>();
      };
  bool called_b = false;
  TestWindowProcDelegate delegate_b =
      [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_b = true;
        return std::optional<LRESULT>();
      };
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
                                             &delegate_a);
  // The function pointer is the same, so this should replace, not add.
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
                                             &delegate_b);
  manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);

  EXPECT_FALSE(called_a);
  EXPECT_TRUE(called_b);
}

TEST(WindowProcDelegateManagerTest, RegisterMultiple) {
  WindowProcDelegateManager manager;

  bool called_a = false;
  TestWindowProcDelegate delegate_a =
      [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_a = true;
        return std::optional<LRESULT>();
      };
  bool called_b = false;
  TestWindowProcDelegate delegate_b =
      [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_b = true;
        return std::optional<LRESULT>();
      };
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
                                             &delegate_a);
  // Function pointer is different, so both should be called.
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
                                             &delegate_b);
  manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);

  EXPECT_TRUE(called_a);
  EXPECT_TRUE(called_b);
}

TEST(WindowProcDelegateManagerTest, ConflictingDelegates) {
  WindowProcDelegateManager manager;

  bool called_a = false;
  TestWindowProcDelegate delegate_a =
      [&called_a](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_a = true;
        return std::optional<LRESULT>(1);
      };
  bool called_b = false;
  TestWindowProcDelegate delegate_b =
      [&called_b](HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
        called_b = true;
        return std::optional<LRESULT>(1);
      };
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback,
                                             &delegate_a);
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback2,
                                             &delegate_b);
  auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);

  EXPECT_TRUE(result);
  // Exactly one of the handlers should be called since each will claim to have
  // handled the message. Which one is unspecified, since the calling order is
  // unspecified.
  EXPECT_TRUE(called_a || called_b);
  EXPECT_NE(called_a, called_b);
}

TEST(WindowProcDelegateManagerTest, Unregister) {
  WindowProcDelegateManager manager;

  bool called = false;
  TestWindowProcDelegate delegate = [&called](HWND hwnd, UINT message,
                                              WPARAM wparam, LPARAM lparam) {
    called = true;
    return std::optional<LRESULT>();
  };
  manager.RegisterTopLevelWindowProcDelegate(TestWindowProcCallback, &delegate);
  manager.UnregisterTopLevelWindowProcDelegate(TestWindowProcCallback);
  auto result = manager.OnTopLevelWindowProc(nullptr, 0, 0, 0);

  EXPECT_FALSE(result);
  EXPECT_FALSE(called);
}

}  // namespace testing
}  // namespace flutter
