// 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/runtime/dart_vm_lifecycle.h"
#include "flutter/testing/dart_isolate_runner.h"
#include "flutter/testing/fixture_test.h"
#include "flutter/testing/testing.h"
#include "flutter/third_party/tonic/converter/dart_converter.h"

// CREATE_NATIVE_ENTRY is leaky by design
// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape)

namespace flutter {
namespace testing {

class TypeConversionsTest : public FixtureTest {
 public:
  TypeConversionsTest()
      : settings_(CreateSettingsForFixture()),
        vm_(DartVMRef::Create(settings_)) {}

  ~TypeConversionsTest() = default;

  [[nodiscard]] bool RunWithEntrypoint(const std::string& entrypoint) {
    if (running_isolate_) {
      return false;
    }
    auto thread = CreateNewThread();
    TaskRunners single_threaded_task_runner(GetCurrentTestName(), thread,
                                            thread, thread, thread);
    auto isolate =
        RunDartCodeInIsolate(vm_, settings_, single_threaded_task_runner,
                             entrypoint, {}, GetDefaultKernelFilePath());
    if (!isolate || isolate->get()->GetPhase() != DartIsolate::Phase::Running) {
      return false;
    }

    running_isolate_ = std::move(isolate);
    return true;
  }

 private:
  Settings settings_;
  DartVMRef vm_;
  std::unique_ptr<AutoIsolateShutdown> running_isolate_;
  FML_DISALLOW_COPY_AND_ASSIGN(TypeConversionsTest);
};

TEST_F(TypeConversionsTest, TestFixture) {
  ASSERT_TRUE(RunWithEntrypoint("main"));
}

TEST_F(TypeConversionsTest, CanConvertEmptyList) {
  fml::AutoResetWaitableEvent event;
  AddNativeCallback(
      "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
        auto bool_handle = Dart_GetNativeArgument(args, 0);
        ASSERT_FALSE(tonic::CheckAndHandleError(bool_handle));
        ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
        event.Signal();
      }));
  AddNativeCallback(
      "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
        std::vector<int64_t> items;
        auto items_handle = tonic::ToDart(items);
        ASSERT_FALSE(tonic::CheckAndHandleError(items_handle));
        tonic::DartInvokeField(::Dart_RootLibrary(), "testCanConvertEmptyList",
                               {items_handle});
      }));
  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
  event.Wait();
}

TEST_F(TypeConversionsTest, CanConvertListOfStrings) {
  fml::AutoResetWaitableEvent event;
  AddNativeCallback(
      "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
        auto bool_handle = Dart_GetNativeArgument(args, 0);
        ASSERT_FALSE(tonic::CheckAndHandleError(bool_handle));
        ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
        event.Signal();
      }));
  AddNativeCallback(
      "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
        std::vector<std::string> items;
        items.push_back("tinker");
        items.push_back("tailor");
        items.push_back("soldier");
        items.push_back("sailor");
        auto items_handle = tonic::ToDart(items);
        ASSERT_FALSE(tonic::CheckAndHandleError(items_handle));
        tonic::DartInvokeField(::Dart_RootLibrary(),
                               "testCanConvertListOfStrings", {items_handle});
      }));
  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
  event.Wait();
}

TEST_F(TypeConversionsTest, CanConvertListOfDoubles) {
  fml::AutoResetWaitableEvent event;
  AddNativeCallback(
      "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
        auto bool_handle = Dart_GetNativeArgument(args, 0);
        ASSERT_FALSE(tonic::CheckAndHandleError(bool_handle));
        ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
        event.Signal();
      }));
  AddNativeCallback(
      "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
        std::vector<double> items;
        items.push_back(1.0);
        items.push_back(2.0);
        items.push_back(3.0);
        items.push_back(4.0);
        auto items_handle = tonic::ToDart(items);
        ASSERT_FALSE(tonic::CheckAndHandleError(items_handle));
        tonic::DartInvokeField(::Dart_RootLibrary(),
                               "testCanConvertListOfDoubles", {items_handle});
      }));
  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
  event.Wait();
}

TEST_F(TypeConversionsTest, CanConvertListOfInts) {
  fml::AutoResetWaitableEvent event;
  AddNativeCallback(
      "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
        auto bool_handle = Dart_GetNativeArgument(args, 0);
        ASSERT_FALSE(tonic::CheckAndHandleError(bool_handle));
        ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
        event.Signal();
      }));
  AddNativeCallback(
      "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
        std::vector<int32_t> items;
        items.push_back(1);
        items.push_back(2);
        items.push_back(3);
        items.push_back(4);
        auto items_handle = tonic::ToDart(items);
        ASSERT_FALSE(tonic::CheckAndHandleError(items_handle));
        tonic::DartInvokeField(::Dart_RootLibrary(), "testCanConvertListOfInts",
                               {items_handle});
      }));
  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
  event.Wait();
}

TEST_F(TypeConversionsTest, CanConvertListOfFloatsToListOfDartDoubles) {
  fml::AutoResetWaitableEvent event;
  AddNativeCallback(
      "NotifySuccess", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) {
        auto bool_handle = Dart_GetNativeArgument(args, 0);
        ASSERT_FALSE(tonic::CheckAndHandleError(bool_handle));
        ASSERT_TRUE(tonic::DartConverter<bool>::FromDart(bool_handle));
        event.Signal();
      }));
  AddNativeCallback(
      "NotifyNative", CREATE_NATIVE_ENTRY([&](Dart_NativeArguments) {
        std::vector<float> items;
        items.push_back(1.0f);
        items.push_back(2.0f);
        items.push_back(3.0f);
        items.push_back(4.0f);
        auto items_handle = tonic::ToDart(items);
        ASSERT_FALSE(tonic::CheckAndHandleError(items_handle));
        // This will fail on type mismatch.
        tonic::DartInvokeField(::Dart_RootLibrary(),
                               "testCanConvertListOfDoubles", {items_handle});
      }));
  ASSERT_TRUE(RunWithEntrypoint("trampoline"));
  event.Wait();
}

}  // namespace testing
}  // namespace flutter

// NOLINTEND(clang-analyzer-core.StackAddressEscape)
