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

#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <cstring>

namespace flutter {
namespace testing {
namespace {
class MockDelegate : public PlatformView::Delegate {
  MOCK_METHOD1(OnPlatformViewCreated, void(std::unique_ptr<Surface>));
  MOCK_METHOD0(OnPlatformViewDestroyed, void());
  MOCK_METHOD0(OnPlatformViewScheduleFrame, void());
  MOCK_METHOD1(OnPlatformViewSetNextFrameCallback,
               void(const fml::closure& closure));
  MOCK_METHOD1(OnPlatformViewSetViewportMetrics,
               void(const ViewportMetrics& metrics));
  MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage,
               void(std::unique_ptr<PlatformMessage> message));
  MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket,
               void(std::unique_ptr<PointerDataPacket> packet));
  MOCK_METHOD3(OnPlatformViewDispatchSemanticsAction,
               void(int32_t id,
                    SemanticsAction action,
                    fml::MallocMapping args));
  MOCK_METHOD1(OnPlatformViewSetSemanticsEnabled, void(bool enabled));
  MOCK_METHOD1(OnPlatformViewSetAccessibilityFeatures, void(int32_t flags));
  MOCK_METHOD1(OnPlatformViewRegisterTexture,
               void(std::shared_ptr<Texture> texture));
  MOCK_METHOD1(OnPlatformViewUnregisterTexture, void(int64_t texture_id));
  MOCK_METHOD1(OnPlatformViewMarkTextureFrameAvailable,
               void(int64_t texture_id));
  MOCK_METHOD3(LoadDartDeferredLibrary,
               void(intptr_t loading_unit_id,
                    std::unique_ptr<const fml::Mapping> snapshot_data,
                    std::unique_ptr<const fml::Mapping> snapshot_instructions));
  MOCK_METHOD3(LoadDartDeferredLibraryError,
               void(intptr_t loading_unit_id,
                    const std::string error_message,
                    bool transient));
  MOCK_METHOD2(UpdateAssetResolverByType,
               void(std::unique_ptr<AssetResolver> updated_asset_resolver,
                    AssetResolver::AssetResolverType type));
  MOCK_CONST_METHOD0(OnPlatformViewGetSettings, const Settings&());
};

class MockResponse : public PlatformMessageResponse {
 public:
  MOCK_METHOD1(Complete, void(std::unique_ptr<fml::Mapping> data));
  MOCK_METHOD0(CompleteEmpty, void());
};
}  // namespace

TEST(PlatformViewEmbedderTest, HasPlatformMessageHandler) {
  ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
                         ThreadHost::Type::Platform);
  flutter::TaskRunners task_runners = flutter::TaskRunners(
      "HasPlatformMessageHandler", thread_host.platform_thread->GetTaskRunner(),
      nullptr, nullptr, nullptr);
  fml::AutoResetWaitableEvent latch;
  task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners] {
    MockDelegate delegate;
    EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table;
    PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table;
    std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder;
    auto embedder = std::make_unique<PlatformViewEmbedder>(
        delegate, task_runners, software_dispatch_table,
        platform_dispatch_table, external_view_embedder);

    ASSERT_TRUE(embedder->GetPlatformMessageHandler());
    latch.Signal();
  });
  latch.Wait();
}

TEST(PlatformViewEmbedderTest, Dispatches) {
  ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
                         ThreadHost::Type::Platform);
  flutter::TaskRunners task_runners = flutter::TaskRunners(
      "HasPlatformMessageHandler", thread_host.platform_thread->GetTaskRunner(),
      nullptr, nullptr, nullptr);
  bool did_call = false;
  std::unique_ptr<PlatformViewEmbedder> embedder;
  {
    fml::AutoResetWaitableEvent latch;
    task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners,
                                                    &did_call, &embedder] {
      MockDelegate delegate;
      EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table;
      PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table;
      platform_dispatch_table.platform_message_response_callback =
          [&did_call](std::unique_ptr<PlatformMessage> message) {
            did_call = true;
          };
      std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder;
      embedder = std::make_unique<PlatformViewEmbedder>(
          delegate, task_runners, software_dispatch_table,
          platform_dispatch_table, external_view_embedder);
      auto platform_message_handler = embedder->GetPlatformMessageHandler();
      fml::RefPtr<PlatformMessageResponse> response =
          fml::MakeRefCounted<MockResponse>();
      std::unique_ptr<PlatformMessage> message =
          std::make_unique<PlatformMessage>("foo", response);
      platform_message_handler->HandlePlatformMessage(std::move(message));
      latch.Signal();
    });
    latch.Wait();
  }
  {
    fml::AutoResetWaitableEvent latch;
    thread_host.platform_thread->GetTaskRunner()->PostTask([&latch, &embedder] {
      embedder.reset();
      latch.Signal();
    });
    latch.Wait();
  }

  EXPECT_TRUE(did_call);
}

TEST(PlatformViewEmbedderTest, DeletionDisabledDispatch) {
  ThreadHost thread_host("io.flutter.test." + GetCurrentTestName() + ".",
                         ThreadHost::Type::Platform);
  flutter::TaskRunners task_runners = flutter::TaskRunners(
      "HasPlatformMessageHandler", thread_host.platform_thread->GetTaskRunner(),
      nullptr, nullptr, nullptr);
  bool did_call = false;
  {
    fml::AutoResetWaitableEvent latch;
    task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners,
                                                    &did_call] {
      MockDelegate delegate;
      EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table;
      PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table;
      platform_dispatch_table.platform_message_response_callback =
          [&did_call](std::unique_ptr<PlatformMessage> message) {
            did_call = true;
          };
      std::shared_ptr<EmbedderExternalViewEmbedder> external_view_embedder;
      auto embedder = std::make_unique<PlatformViewEmbedder>(
          delegate, task_runners, software_dispatch_table,
          platform_dispatch_table, external_view_embedder);
      auto platform_message_handler = embedder->GetPlatformMessageHandler();
      fml::RefPtr<PlatformMessageResponse> response =
          fml::MakeRefCounted<MockResponse>();
      std::unique_ptr<PlatformMessage> message =
          std::make_unique<PlatformMessage>("foo", response);
      platform_message_handler->HandlePlatformMessage(std::move(message));
      embedder.reset();
      latch.Signal();
    });
    latch.Wait();
  }
  {
    fml::AutoResetWaitableEvent latch;
    thread_host.platform_thread->GetTaskRunner()->PostTask(
        [&latch] { latch.Signal(); });
    latch.Wait();
  }

  EXPECT_FALSE(did_call);
}

}  // namespace testing
}  // namespace flutter
