// 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/lib/ui/compositing/scene_builder.h"

#include <memory>

#include "flutter/common/task_runners.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/shell/common/shell_test.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"

namespace flutter {
namespace testing {

TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) {
  auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();

  // prevent ClearDartWrapper() from deleting the scene builder.
  SceneBuilder* retained_scene_builder;
  Scene* retained_scene;

  auto validate_builder_has_layers =
      [&retained_scene_builder](Dart_NativeArguments args) {
        auto handle = Dart_GetNativeArgument(args, 0);
        intptr_t peer = 0;
        Dart_Handle result = Dart_GetNativeInstanceField(
            handle, tonic::DartWrappable::kPeerIndex, &peer);
        ASSERT_FALSE(Dart_IsError(result));
        retained_scene_builder = reinterpret_cast<SceneBuilder*>(peer);
        retained_scene_builder->AddRef();
        ASSERT_TRUE(retained_scene_builder);
        ASSERT_EQ(retained_scene_builder->layer_stack().size(), 2ul);
      };

  auto validate_builder_has_no_layers =
      [&retained_scene_builder](Dart_NativeArguments args) {
        ASSERT_EQ(retained_scene_builder->layer_stack().size(), 0ul);
        retained_scene_builder->Release();
        retained_scene_builder = nullptr;
      };

  auto capture_scene = [&retained_scene](Dart_NativeArguments args) {
    auto handle = Dart_GetNativeArgument(args, 0);
    intptr_t peer = 0;
    Dart_Handle result = Dart_GetNativeInstanceField(
        handle, tonic::DartWrappable::kPeerIndex, &peer);
    ASSERT_FALSE(Dart_IsError(result));
    retained_scene = reinterpret_cast<Scene*>(peer);
    retained_scene->AddRef();
    ASSERT_TRUE(retained_scene);
  };

  auto validate_scene_has_no_layers =
      [message_latch, &retained_scene](Dart_NativeArguments args) {
        EXPECT_FALSE(retained_scene->takeLayerTree());
        retained_scene->Release();
        retained_scene = nullptr;
        message_latch->Signal();
      };

  Settings settings = CreateSettingsForFixture();
  TaskRunners task_runners("test",                  // label
                           GetCurrentTaskRunner(),  // platform
                           CreateNewThread(),       // raster
                           CreateNewThread(),       // ui
                           CreateNewThread()        // io
  );

  AddNativeCallback("ValidateBuilderHasLayers",
                    CREATE_NATIVE_ENTRY(validate_builder_has_layers));
  AddNativeCallback("ValidateBuilderHasNoLayers",
                    CREATE_NATIVE_ENTRY(validate_builder_has_no_layers));

  AddNativeCallback("CaptureScene", CREATE_NATIVE_ENTRY(capture_scene));
  AddNativeCallback("ValidateSceneHasNoLayers",
                    CREATE_NATIVE_ENTRY(validate_scene_has_no_layers));

  std::unique_ptr<Shell> shell =
      CreateShell(std::move(settings), std::move(task_runners));

  ASSERT_TRUE(shell->IsSetup());
  auto configuration = RunConfiguration::InferFromSettings(settings);
  configuration.SetEntrypoint("validateSceneBuilderAndScene");

  shell->RunEngine(std::move(configuration), [](auto result) {
    ASSERT_EQ(result, Engine::RunStatus::Success);
  });

  message_latch->Wait();
  DestroyShell(std::move(shell), std::move(task_runners));
}

TEST_F(ShellTest, EngineLayerDisposeReleasesReference) {
  auto message_latch = std::make_shared<fml::AutoResetWaitableEvent>();

  std::shared_ptr<ContainerLayer> root_layer;

  auto capture_root_layer = [&root_layer](Dart_NativeArguments args) {
    auto handle = Dart_GetNativeArgument(args, 0);
    intptr_t peer = 0;
    Dart_Handle result = Dart_GetNativeInstanceField(
        handle, tonic::DartWrappable::kPeerIndex, &peer);
    ASSERT_FALSE(Dart_IsError(result));
    SceneBuilder* scene_builder = reinterpret_cast<SceneBuilder*>(peer);
    ASSERT_TRUE(scene_builder);
    root_layer = scene_builder->layer_stack()[0];
    ASSERT_TRUE(root_layer);
  };

  auto validate_layer_tree_counts = [&root_layer](Dart_NativeArguments args) {
    // One for the EngineLayer, one for our pointer in the test.
    EXPECT_EQ(root_layer->layers().front().use_count(), 2);
  };

  auto validate_engine_layer_dispose =
      [message_latch, &root_layer](Dart_NativeArguments args) {
        // Just one for our pointer now.
        EXPECT_EQ(root_layer->layers().front().use_count(), 1);
        root_layer.reset();
        message_latch->Signal();
      };

  Settings settings = CreateSettingsForFixture();
  TaskRunners task_runners("test",                  // label
                           GetCurrentTaskRunner(),  // platform
                           CreateNewThread(),       // raster
                           CreateNewThread(),       // ui
                           CreateNewThread()        // io
  );

  AddNativeCallback("CaptureRootLayer",
                    CREATE_NATIVE_ENTRY(capture_root_layer));
  AddNativeCallback("ValidateLayerTreeCounts",
                    CREATE_NATIVE_ENTRY(validate_layer_tree_counts));
  AddNativeCallback("ValidateEngineLayerDispose",
                    CREATE_NATIVE_ENTRY(validate_engine_layer_dispose));

  std::unique_ptr<Shell> shell =
      CreateShell(std::move(settings), std::move(task_runners));

  ASSERT_TRUE(shell->IsSetup());
  auto configuration = RunConfiguration::InferFromSettings(settings);
  configuration.SetEntrypoint("validateEngineLayerDispose");

  shell->RunEngine(std::move(configuration), [](auto result) {
    ASSERT_EQ(result, Engine::RunStatus::Success);
  });

  message_latch->Wait();
  DestroyShell(std::move(shell), std::move(task_runners));
}

}  // namespace testing
}  // namespace flutter
