// 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/direct_manipulation.h"
#include "flutter/shell/platform/windows/testing/mock_window_binding_handler_delegate.h"

#include "gtest/gtest.h"

using testing::_;

namespace flutter {
namespace testing {

class MockIDirectManipulationViewport : public IDirectManipulationViewport {
 public:
  MockIDirectManipulationViewport() {}

  // Prevent copying.
  MockIDirectManipulationViewport(MockIDirectManipulationViewport const&) =
      delete;
  MockIDirectManipulationViewport& operator=(
      MockIDirectManipulationViewport const&) = delete;
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, AddRef, ULONG());
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Release, ULONG());
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             QueryInterface,
                             HRESULT(REFIID, void**));
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Abandon, HRESULT());
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             ActivateConfiguration,
                             HRESULT(DIRECTMANIPULATION_CONFIGURATION));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             AddConfiguration,
                             HRESULT(DIRECTMANIPULATION_CONFIGURATION));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             AddContent,
                             HRESULT(IDirectManipulationContent*));
  MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             AddEventHandler,
                             HRESULT(HWND,
                                     IDirectManipulationViewportEventHandler*,
                                     DWORD*));
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Disable, HRESULT());
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Enable, HRESULT());
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetPrimaryContent,
                             HRESULT(REFIID, void**));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetStatus,
                             HRESULT(DIRECTMANIPULATION_STATUS*));
  MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetTag,
                             HRESULT(REFIID, void**, UINT32*));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetViewportRect,
                             HRESULT(RECT*));
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, ReleaseAllContacts, HRESULT());
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             ReleaseContact,
                             HRESULT(UINT32));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             RemoveConfiguration,
                             HRESULT(DIRECTMANIPULATION_CONFIGURATION));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             RemoveContent,
                             HRESULT(IDirectManipulationContent*));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             RemoveEventHandler,
                             HRESULT(DWORD));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetChaining,
                             HRESULT(DIRECTMANIPULATION_MOTION_TYPES));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, SetContact, HRESULT(UINT32));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetInputMode,
                             HRESULT(DIRECTMANIPULATION_INPUT_MODE));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetManualGesture,
                             HRESULT(DIRECTMANIPULATION_GESTURE_CONFIGURATION));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetTag,
                             HRESULT(IUnknown*, UINT32));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetUpdateMode,
                             HRESULT(DIRECTMANIPULATION_INPUT_MODE));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetViewportOptions,
                             HRESULT(DIRECTMANIPULATION_VIEWPORT_OPTIONS));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetViewportRect,
                             HRESULT(const RECT*));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetViewportTransform,
                             HRESULT(const float*, DWORD));
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Stop, HRESULT());
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SyncDisplayTransform,
                             HRESULT(const float*, DWORD));
  MOCK_METHOD5_WITH_CALLTYPE(
      STDMETHODCALLTYPE,
      ZoomToRect,
      HRESULT(const float, const float, const float, const float, BOOL));
};

class MockIDirectManipulationContent : public IDirectManipulationContent {
 public:
  MockIDirectManipulationContent() {}

  // Prevent copying.
  MockIDirectManipulationContent(MockIDirectManipulationContent const&) =
      delete;
  MockIDirectManipulationContent& operator=(
      MockIDirectManipulationContent const&) = delete;
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, AddRef, ULONG());
  MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, Release, ULONG());
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             QueryInterface,
                             HRESULT(REFIID, void**));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, GetContentRect, HRESULT(RECT*));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetContentTransform,
                             HRESULT(float*, DWORD));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetOutputTransform,
                             HRESULT(float*, DWORD));
  MOCK_METHOD3_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetTag,
                             HRESULT(REFIID, void**, UINT32*));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             GetViewport,
                             HRESULT(REFIID, void**));
  MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetContentRect,
                             HRESULT(const RECT*));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SetTag,
                             HRESULT(IUnknown*, UINT32));
  MOCK_METHOD2_WITH_CALLTYPE(STDMETHODCALLTYPE,
                             SyncContentTransform,
                             HRESULT(const float*, DWORD));
};

TEST(DirectManipulationTest, TestGesture) {
  MockIDirectManipulationContent content;
  MockWindowBindingHandlerDelegate delegate;
  MockIDirectManipulationViewport viewport;
  const float scale = 1.5;
  const float pan_x = 32.0;
  const float pan_y = 16.0;
  const int DISPLAY_WIDTH = 800;
  const int DISPLAY_HEIGHT = 600;
  auto owner = std::make_unique<DirectManipulationOwner>(nullptr);
  owner->SetBindingHandlerDelegate(&delegate);
  auto handler =
      fml::MakeRefCounted<DirectManipulationEventHandler>(owner.get());
  int32_t device_id = (int32_t) reinterpret_cast<int64_t>(handler.get());
  EXPECT_CALL(viewport, GetPrimaryContent(_, _))
      .WillOnce(::testing::Invoke([&content](REFIID in, void** out) {
        *out = &content;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([scale](float* transform, DWORD size) {
        transform[0] = 1.0f;
        transform[4] = 0.0;
        transform[5] = 0.0;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(delegate, OnPointerPanZoomStart(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_RUNNING,
                                   DIRECTMANIPULATION_READY);
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke(
          [scale, pan_x, pan_y](float* transform, DWORD size) {
            transform[0] = scale;
            transform[4] = pan_x;
            transform[5] = pan_y;
            return S_OK;
          }));
  EXPECT_CALL(delegate,
              OnPointerPanZoomUpdate(device_id, pan_x, pan_y, scale, 0));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  EXPECT_CALL(delegate, OnPointerPanZoomEnd(device_id));
  EXPECT_CALL(viewport, GetViewportRect(_))
      .WillOnce(::testing::Invoke([DISPLAY_WIDTH, DISPLAY_HEIGHT](RECT* rect) {
        rect->left = 0;
        rect->top = 0;
        rect->right = DISPLAY_WIDTH;
        rect->bottom = DISPLAY_HEIGHT;
        return S_OK;
      }));
  EXPECT_CALL(viewport, ZoomToRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, false))
      .WillOnce(::testing::Return(S_OK));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_INERTIA,
                                   DIRECTMANIPULATION_RUNNING);
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_READY,
                                   DIRECTMANIPULATION_INERTIA);
}

// Verify that scale mantissa rounding works as expected
TEST(DirectManipulationTest, TestRounding) {
  MockIDirectManipulationContent content;
  MockWindowBindingHandlerDelegate delegate;
  MockIDirectManipulationViewport viewport;
  const float scale = 1.5;
  const int DISPLAY_WIDTH = 800;
  const int DISPLAY_HEIGHT = 600;
  auto owner = std::make_unique<DirectManipulationOwner>(nullptr);
  owner->SetBindingHandlerDelegate(&delegate);
  auto handler =
      fml::MakeRefCounted<DirectManipulationEventHandler>(owner.get());
  int32_t device_id = (int32_t) reinterpret_cast<int64_t>(handler.get());
  EXPECT_CALL(viewport, GetPrimaryContent(_, _))
      .WillOnce(::testing::Invoke([&content](REFIID in, void** out) {
        *out = &content;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([scale](float* transform, DWORD size) {
        transform[0] = 1.0f;
        transform[4] = 0.0;
        transform[5] = 0.0;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(delegate, OnPointerPanZoomStart(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_RUNNING,
                                   DIRECTMANIPULATION_READY);
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([scale](float* transform, DWORD size) {
        transform[0] = 1.5000001f;
        transform[4] = 4.0;
        transform[5] = 0.0;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(delegate,
              OnPointerPanZoomUpdate(device_id, 4.0, 0, 1.5000001f, 0))
      .Times(0);
  EXPECT_CALL(delegate, OnPointerPanZoomUpdate(device_id, 4.0, 0, 1.5f, 0))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([scale](float* transform, DWORD size) {
        transform[0] = 1.50000065f;
        transform[4] = 2.0;
        transform[5] = 0.0;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(delegate,
              OnPointerPanZoomUpdate(device_id, 2.0, 0, 1.50000065f, 0))
      .Times(0);
  EXPECT_CALL(delegate,
              OnPointerPanZoomUpdate(device_id, 2.0, 0, 1.50000047f, 0))
      .Times(1)
      .RetiresOnSaturation();
  EXPECT_CALL(delegate, OnPointerPanZoomEnd(device_id));
  EXPECT_CALL(viewport, GetViewportRect(_))
      .WillOnce(::testing::Invoke([DISPLAY_WIDTH, DISPLAY_HEIGHT](RECT* rect) {
        rect->left = 0;
        rect->top = 0;
        rect->right = DISPLAY_WIDTH;
        rect->bottom = DISPLAY_HEIGHT;
        return S_OK;
      }));
  EXPECT_CALL(viewport, ZoomToRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, false))
      .WillOnce(::testing::Return(S_OK));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_INERTIA,
                                   DIRECTMANIPULATION_RUNNING);
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_READY,
                                   DIRECTMANIPULATION_INERTIA);
}

TEST(DirectManipulationTest, TestInertiaCancelSentForUserCancel) {
  MockIDirectManipulationContent content;
  MockWindowBindingHandlerDelegate delegate;
  MockIDirectManipulationViewport viewport;
  const int DISPLAY_WIDTH = 800;
  const int DISPLAY_HEIGHT = 600;
  auto owner = std::make_unique<DirectManipulationOwner>(nullptr);
  owner->SetBindingHandlerDelegate(&delegate);
  auto handler =
      fml::MakeRefCounted<DirectManipulationEventHandler>(owner.get());
  int32_t device_id = (int32_t) reinterpret_cast<int64_t>(handler.get());
  // No need to mock the actual gesture, just start at the end.
  EXPECT_CALL(viewport, GetViewportRect(_))
      .WillOnce(::testing::Invoke([DISPLAY_WIDTH, DISPLAY_HEIGHT](RECT* rect) {
        rect->left = 0;
        rect->top = 0;
        rect->right = DISPLAY_WIDTH;
        rect->bottom = DISPLAY_HEIGHT;
        return S_OK;
      }));
  EXPECT_CALL(viewport, ZoomToRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, false))
      .WillOnce(::testing::Return(S_OK));
  EXPECT_CALL(delegate, OnPointerPanZoomEnd(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_INERTIA,
                                   DIRECTMANIPULATION_RUNNING);
  // Have pan_y change by 10 between inertia updates.
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([](float* transform, DWORD size) {
        transform[0] = 1;
        transform[4] = 0;
        transform[5] = 100;
        return S_OK;
      }));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([](float* transform, DWORD size) {
        transform[0] = 1;
        transform[4] = 0;
        transform[5] = 110;
        return S_OK;
      }));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  // This looks like an interruption in the middle of synthetic inertia because
  // of user input.
  EXPECT_CALL(delegate, OnScrollInertiaCancel(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_READY,
                                   DIRECTMANIPULATION_INERTIA);
}

TEST(DirectManipulationTest, TestInertiaCamcelNotSentAtInertiaEnd) {
  MockIDirectManipulationContent content;
  MockWindowBindingHandlerDelegate delegate;
  MockIDirectManipulationViewport viewport;
  const int DISPLAY_WIDTH = 800;
  const int DISPLAY_HEIGHT = 600;
  auto owner = std::make_unique<DirectManipulationOwner>(nullptr);
  owner->SetBindingHandlerDelegate(&delegate);
  auto handler =
      fml::MakeRefCounted<DirectManipulationEventHandler>(owner.get());
  int32_t device_id = (int32_t) reinterpret_cast<int64_t>(handler.get());
  // No need to mock the actual gesture, just start at the end.
  EXPECT_CALL(viewport, GetViewportRect(_))
      .WillOnce(::testing::Invoke([DISPLAY_WIDTH, DISPLAY_HEIGHT](RECT* rect) {
        rect->left = 0;
        rect->top = 0;
        rect->right = DISPLAY_WIDTH;
        rect->bottom = DISPLAY_HEIGHT;
        return S_OK;
      }));
  EXPECT_CALL(viewport, ZoomToRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, false))
      .WillOnce(::testing::Return(S_OK));
  EXPECT_CALL(delegate, OnPointerPanZoomEnd(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_INERTIA,
                                   DIRECTMANIPULATION_RUNNING);
  // Have no change in pan between events.
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([](float* transform, DWORD size) {
        transform[0] = 1;
        transform[4] = 0;
        transform[5] = 140;
        return S_OK;
      }));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([](float* transform, DWORD size) {
        transform[0] = 1;
        transform[4] = 0;
        transform[5] = 140;
        return S_OK;
      }));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  // OnScrollInertiaCancel should not be called.
  EXPECT_CALL(delegate, OnScrollInertiaCancel(device_id)).Times(0);
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_READY,
                                   DIRECTMANIPULATION_INERTIA);
}

// Have some initial values in the matrix, only the differences should be
// reported.
TEST(DirectManipulationTest, TestGestureWithInitialData) {
  MockIDirectManipulationContent content;
  MockWindowBindingHandlerDelegate delegate;
  MockIDirectManipulationViewport viewport;
  const float scale = 1.5;
  const float pan_x = 32.0;
  const float pan_y = 16.0;
  const int DISPLAY_WIDTH = 800;
  const int DISPLAY_HEIGHT = 600;
  auto owner = std::make_unique<DirectManipulationOwner>(nullptr);
  owner->SetBindingHandlerDelegate(&delegate);
  auto handler =
      fml::MakeRefCounted<DirectManipulationEventHandler>(owner.get());
  int32_t device_id = (int32_t) reinterpret_cast<int64_t>(handler.get());
  EXPECT_CALL(viewport, GetPrimaryContent(_, _))
      .WillOnce(::testing::Invoke([&content](REFIID in, void** out) {
        *out = &content;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke([scale](float* transform, DWORD size) {
        transform[0] = 2.0f;
        transform[4] = 234.0;
        transform[5] = 345.0;
        return S_OK;
      }))
      .RetiresOnSaturation();
  EXPECT_CALL(delegate, OnPointerPanZoomStart(device_id));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_RUNNING,
                                   DIRECTMANIPULATION_READY);
  EXPECT_CALL(content, GetContentTransform(_, 6))
      .WillOnce(::testing::Invoke(
          [scale, pan_x, pan_y](float* transform, DWORD size) {
            transform[0] = 2.0f * scale;
            transform[4] = 234.0 + pan_x;
            transform[5] = 345.0 + pan_y;
            return S_OK;
          }));
  EXPECT_CALL(delegate,
              OnPointerPanZoomUpdate(device_id, pan_x, pan_y, scale, 0));
  handler->OnContentUpdated((IDirectManipulationViewport*)&viewport,
                            (IDirectManipulationContent*)&content);
  EXPECT_CALL(delegate, OnPointerPanZoomEnd(device_id));
  EXPECT_CALL(viewport, GetViewportRect(_))
      .WillOnce(::testing::Invoke([DISPLAY_WIDTH, DISPLAY_HEIGHT](RECT* rect) {
        rect->left = 0;
        rect->top = 0;
        rect->right = DISPLAY_WIDTH;
        rect->bottom = DISPLAY_HEIGHT;
        return S_OK;
      }));
  EXPECT_CALL(viewport, ZoomToRect(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT, false))
      .WillOnce(::testing::Return(S_OK));
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_INERTIA,
                                   DIRECTMANIPULATION_RUNNING);
  handler->OnViewportStatusChanged((IDirectManipulationViewport*)&viewport,
                                   DIRECTMANIPULATION_READY,
                                   DIRECTMANIPULATION_INERTIA);
}

}  // namespace testing
}  // namespace flutter
