// 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.

#define FML_USED_ON_EMBEDDER

#include <cstdlib>
#include <cstring>
#include <iostream>

#include "flutter/assets/asset_manager.h"
#include "flutter/assets/directory_asset_bundle.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/fml/build_config.h"
#include "flutter/fml/file.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/message_loop.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/synchronization/waitable_event.h"
#include "flutter/fml/task_runner.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/gpu/gpu_surface_software.h"
#include "flutter/third_party/abseil-cpp/absl/base/no_destructor.h"

#include "third_party/dart/runtime/include/bin/dart_io_api.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/skia/include/core/SkSurface.h"

// Impeller should only be enabled if the Vulkan backend is enabled.
#define ALLOW_IMPELLER (IMPELLER_SUPPORTS_RENDERING && IMPELLER_ENABLE_VULKAN)

#if ALLOW_IMPELLER
#include <vulkan/vulkan.h>                                        // nogncheck
#include "impeller/entity/vk/entity_shaders_vk.h"                 // nogncheck
#include "impeller/entity/vk/framebuffer_blend_shaders_vk.h"      // nogncheck
#include "impeller/entity/vk/modern_shaders_vk.h"                 // nogncheck
#include "impeller/renderer/backend/vulkan/context_vk.h"          // nogncheck
#include "impeller/renderer/backend/vulkan/surface_context_vk.h"  // nogncheck
#include "impeller/renderer/context.h"                            // nogncheck
#include "impeller/renderer/vk/compute_shaders_vk.h"              // nogncheck
#include "shell/gpu/gpu_surface_vulkan_impeller.h"                // nogncheck
#if IMPELLER_ENABLE_3D
#include "impeller/scene/shaders/vk/scene_shaders_vk.h"  // nogncheck
#endif                                                   // IMPELLER_ENABLE_3D

static std::vector<std::shared_ptr<fml::Mapping>> ShaderLibraryMappings() {
  return {
      std::make_shared<fml::NonOwnedMapping>(impeller_entity_shaders_vk_data,
                                             impeller_entity_shaders_vk_length),
      std::make_shared<fml::NonOwnedMapping>(impeller_modern_shaders_vk_data,
                                             impeller_modern_shaders_vk_length),
      std::make_shared<fml::NonOwnedMapping>(
          impeller_framebuffer_blend_shaders_vk_data,
          impeller_framebuffer_blend_shaders_vk_length),
#if IMPELLER_ENABLE_3D
      std::make_shared<fml::NonOwnedMapping>(impeller_scene_shaders_vk_data,
                                             impeller_scene_shaders_vk_length),
#endif  // IMPELLER_ENABLE_3D
      std::make_shared<fml::NonOwnedMapping>(
          impeller_compute_shaders_vk_data, impeller_compute_shaders_vk_length),
  };
}

struct ImpellerVulkanContextHolder {
  ImpellerVulkanContextHolder() = default;
  ImpellerVulkanContextHolder(ImpellerVulkanContextHolder&&) = default;
  std::shared_ptr<impeller::ContextVK> context;
  std::shared_ptr<impeller::SurfaceContextVK> surface_context;

  bool Initialize(bool enable_validation);
};

bool ImpellerVulkanContextHolder::Initialize(bool enable_validation) {
  impeller::ContextVK::Settings context_settings;
  context_settings.proc_address_callback = &vkGetInstanceProcAddr;
  context_settings.shader_libraries_data = ShaderLibraryMappings();
  context_settings.cache_directory = fml::paths::GetCachesDirectory();
  context_settings.enable_validation = enable_validation;

  context = impeller::ContextVK::Create(std::move(context_settings));
  if (!context || !context->IsValid()) {
    VALIDATION_LOG << "Could not create Vulkan context.";
    return false;
  }

  impeller::vk::SurfaceKHR vk_surface;
  impeller::vk::HeadlessSurfaceCreateInfoEXT surface_create_info;
  auto res = context->GetInstance().createHeadlessSurfaceEXT(
      &surface_create_info,  // surface create info
      nullptr,               // allocator
      &vk_surface            // surface
  );
  if (res != impeller::vk::Result::eSuccess) {
    VALIDATION_LOG << "Could not create surface for tester "
                   << impeller::vk::to_string(res);
    return false;
  }

  impeller::vk::UniqueSurfaceKHR surface{vk_surface, context->GetInstance()};
  surface_context = context->CreateSurfaceContext();
  if (!surface_context->SetWindowSurface(std::move(surface),
                                         impeller::ISize{1, 1})) {
    VALIDATION_LOG << "Could not set up surface for context.";
    return false;
  }
  return true;
}

#else
struct ImpellerVulkanContextHolder {};
#endif  // IMPELLER_SUPPORTS_RENDERING

#if defined(FML_OS_WIN)
#include <combaseapi.h>
#endif  // defined(FML_OS_WIN)

#if defined(FML_OS_POSIX)
#include <signal.h>
#endif  // defined(FML_OS_POSIX)

namespace flutter {

static absl::NoDestructor<std::unique_ptr<Shell>> g_shell;

static constexpr int64_t kImplicitViewId = 0ll;

static void ConfigureShell(Shell* shell) {
  auto device_pixel_ratio = 3.0;
  auto physical_width = 2400.0;   // 800 at 3x resolution.
  auto physical_height = 1800.0;  // 600 at 3x resolution.

  std::vector<std::unique_ptr<Display>> displays;
  displays.push_back(std::make_unique<Display>(
      0, 60, physical_width, physical_height, device_pixel_ratio));
  shell->OnDisplayUpdates(std::move(displays));

  flutter::ViewportMetrics metrics{};
  metrics.device_pixel_ratio = device_pixel_ratio;
  metrics.physical_width = physical_width;
  metrics.physical_height = physical_height;
  metrics.display_id = 0;
  shell->GetPlatformView()->SetViewportMetrics(kImplicitViewId, metrics);
}

class TesterExternalViewEmbedder : public ExternalViewEmbedder {
  // |ExternalViewEmbedder|
  DlCanvas* GetRootCanvas() override { return nullptr; }

  // |ExternalViewEmbedder|
  void CancelFrame() override {}

  // |ExternalViewEmbedder|
  void BeginFrame(GrDirectContext* context,
                  const fml::RefPtr<fml::RasterThreadMerger>&
                      raster_thread_merger) override {}

  // |ExternalViewEmbedder|
  void PrepareFlutterView(SkISize frame_size,
                          double device_pixel_ratio) override {}

  // |ExternalViewEmbedder|
  void PrerollCompositeEmbeddedView(
      int64_t view_id,
      std::unique_ptr<EmbeddedViewParams> params) override {}

  // |ExternalViewEmbedder|
  DlCanvas* CompositeEmbeddedView(int64_t view_id) override {
    return &builder_;
  }

 private:
  DisplayListBuilder builder_;
};

class TesterGPUSurfaceSoftware : public GPUSurfaceSoftware {
 public:
  TesterGPUSurfaceSoftware(GPUSurfaceSoftwareDelegate* delegate,
                           bool render_to_surface)
      : GPUSurfaceSoftware(delegate, render_to_surface) {}

  bool EnableRasterCache() const override { return false; }
};

class TesterPlatformView : public PlatformView,
                           public GPUSurfaceSoftwareDelegate {
 public:
  TesterPlatformView(Delegate& delegate,
                     const TaskRunners& task_runners,
                     ImpellerVulkanContextHolder&& impeller_context_holder)
      : PlatformView(delegate, task_runners),
        impeller_context_holder_(std::move(impeller_context_holder)) {}

  ~TesterPlatformView() {
#if ALLOW_IMPELLER
    if (impeller_context_holder_.context) {
      impeller_context_holder_.context->Shutdown();
    }
#endif
  }

  // |PlatformView|
  std::shared_ptr<impeller::Context> GetImpellerContext() const override {
#if ALLOW_IMPELLER
    return std::static_pointer_cast<impeller::Context>(
        impeller_context_holder_.context);
#else
    return nullptr;
#endif  // ALLOW_IMPELLER
  }

  // |PlatformView|
  std::unique_ptr<Surface> CreateRenderingSurface() override {
#if ALLOW_IMPELLER
    if (delegate_.OnPlatformViewGetSettings().enable_impeller) {
      FML_DCHECK(impeller_context_holder_.context);
      auto surface = std::make_unique<GPUSurfaceVulkanImpeller>(
          impeller_context_holder_.surface_context);
      FML_DCHECK(surface->IsValid());
      return surface;
    }
#endif  // ALLOW_IMPELLER
    auto surface = std::make_unique<TesterGPUSurfaceSoftware>(
        this, true /* render to surface */);
    FML_DCHECK(surface->IsValid());
    return surface;
  }

  // |GPUSurfaceSoftwareDelegate|
  sk_sp<SkSurface> AcquireBackingStore(const SkISize& size) override {
    if (sk_surface_ != nullptr &&
        SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
      // The old and new surface sizes are the same. Nothing to do here.
      return sk_surface_;
    }

    SkImageInfo info =
        SkImageInfo::MakeN32(size.fWidth, size.fHeight, kPremul_SkAlphaType,
                             SkColorSpace::MakeSRGB());
    sk_surface_ = SkSurfaces::Raster(info, nullptr);

    if (sk_surface_ == nullptr) {
      FML_LOG(ERROR)
          << "Could not create backing store for software rendering.";
      return nullptr;
    }

    return sk_surface_;
  }

  // |GPUSurfaceSoftwareDelegate|
  bool PresentBackingStore(sk_sp<SkSurface> backing_store) override {
    return true;
  }

  // |PlatformView|
  std::shared_ptr<ExternalViewEmbedder> CreateExternalViewEmbedder() override {
    return external_view_embedder_;
  }

 private:
  sk_sp<SkSurface> sk_surface_ = nullptr;
  [[maybe_unused]] ImpellerVulkanContextHolder impeller_context_holder_;
  std::shared_ptr<TesterExternalViewEmbedder> external_view_embedder_ =
      std::make_shared<TesterExternalViewEmbedder>();
};

// Checks whether the engine's main Dart isolate has no pending work.  If so,
// then exit the given message loop.
class ScriptCompletionTaskObserver {
 public:
  ScriptCompletionTaskObserver(Shell& shell,
                               fml::RefPtr<fml::TaskRunner> main_task_runner,
                               bool run_forever)
      : shell_(shell),
        main_task_runner_(std::move(main_task_runner)),
        run_forever_(run_forever) {}

  int GetExitCodeForLastError() const {
    return static_cast<int>(last_error_.value_or(DartErrorCode::NoError));
  }

  void DidProcessTask() {
    last_error_ = shell_.GetUIIsolateLastError();
    if (shell_.EngineHasLivePorts()) {
      // The UI isolate still has live ports and is running. Nothing to do
      // just yet.
      return;
    }

    if (run_forever_) {
      // We need this script to run forever. We have already recorded the last
      // error. Keep going.
      return;
    }

    if (!has_terminated_) {
      // Only try to terminate the loop once.
      has_terminated_ = true;
      fml::TaskRunner::RunNowOrPostTask(main_task_runner_, []() {
        fml::MessageLoop::GetCurrent().Terminate();
      });
    }
  }

 private:
  Shell& shell_;
  fml::RefPtr<fml::TaskRunner> main_task_runner_;
  bool run_forever_ = false;
  std::optional<DartErrorCode> last_error_;
  bool has_terminated_ = false;

  FML_DISALLOW_COPY_AND_ASSIGN(ScriptCompletionTaskObserver);
};

// Processes spawned via dart:io inherit their signal handling from the parent
// process. As part of spawning, the spawner blocks signals temporarily, so we
// need to explicitly unblock the signals we care about in the new process. In
// particular, we need to unblock SIGPROF for CPU profiling to work on the
// mutator thread in the main isolate in this process (threads spawned by the VM
// know about this limitation and automatically have this signal unblocked).
static void UnblockSIGPROF() {
#if defined(FML_OS_POSIX)
  sigset_t set;
  sigemptyset(&set);
  sigaddset(&set, SIGPROF);
  pthread_sigmask(SIG_UNBLOCK, &set, NULL);
#endif  // defined(FML_OS_POSIX)
}

int RunTester(const flutter::Settings& settings,
              bool run_forever,
              bool multithreaded) {
  const auto thread_label = "io.flutter.test.";

  // Necessary if we want to use the CPU profiler on the main isolate's mutator
  // thread.
  //
  // OSX WARNING: avoid spawning additional threads before this call due to a
  // kernel bug that may enable SIGPROF on an unintended thread in the process.
  UnblockSIGPROF();

  fml::MessageLoop::EnsureInitializedForCurrentThread();

  auto current_task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner();

  std::unique_ptr<ThreadHost> threadhost;
  fml::RefPtr<fml::TaskRunner> platform_task_runner;
  fml::RefPtr<fml::TaskRunner> raster_task_runner;
  fml::RefPtr<fml::TaskRunner> ui_task_runner;
  fml::RefPtr<fml::TaskRunner> io_task_runner;

  if (multithreaded) {
    threadhost = std::make_unique<ThreadHost>(
        thread_label, ThreadHost::Type::kPlatform | ThreadHost::Type::kIo |
                          ThreadHost::Type::kUi | ThreadHost::Type::kRaster);
    platform_task_runner = current_task_runner;
    raster_task_runner = threadhost->raster_thread->GetTaskRunner();
    ui_task_runner = threadhost->ui_thread->GetTaskRunner();
    io_task_runner = threadhost->io_thread->GetTaskRunner();
  } else {
    platform_task_runner = raster_task_runner = ui_task_runner =
        io_task_runner = current_task_runner;
  }

  const flutter::TaskRunners task_runners(thread_label,  // dart thread label
                                          platform_task_runner,  // platform
                                          raster_task_runner,    // raster
                                          ui_task_runner,        // ui
                                          io_task_runner         // io
  );

  ImpellerVulkanContextHolder impeller_context_holder;

#if ALLOW_IMPELLER
  if (settings.enable_impeller) {
    if (!impeller_context_holder.Initialize(
            settings.enable_vulkan_validation)) {
      return EXIT_FAILURE;
    }
  }
#endif  // ALLOW_IMPELLER

  Shell::CreateCallback<PlatformView> on_create_platform_view =
      fml::MakeCopyable([impeller_context_holder = std::move(
                             impeller_context_holder)](Shell& shell) mutable {
        return std::make_unique<TesterPlatformView>(
            shell, shell.GetTaskRunners(), std::move(impeller_context_holder));
      });

  Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
    return std::make_unique<Rasterizer>(
        shell, Rasterizer::MakeGpuImageBehavior::kBitmap);
  };

  g_shell->reset(Shell::Create(flutter::PlatformData(),  //
                               task_runners,             //
                               settings,                 //
                               on_create_platform_view,  //
                               on_create_rasterizer      //
                               )
                     .release());
  auto shell = g_shell->get();

  if (!shell || !shell->IsSetup()) {
    FML_LOG(ERROR) << "Could not set up the shell.";
    return EXIT_FAILURE;
  }

  if (settings.application_kernel_asset.empty()) {
    FML_LOG(ERROR) << "Dart kernel file not specified.";
    return EXIT_FAILURE;
  }

  shell->GetPlatformView()->NotifyCreated();

  // Initialize default testing locales. There is no platform to
  // pass locales on the tester, so to retain expected locale behavior,
  // we emulate it in here by passing in 'en_US' and 'zh_CN' as test locales.
  const char* locale_json =
      "{\"method\":\"setLocale\",\"args\":[\"en\",\"US\",\"\",\"\",\"zh\","
      "\"CN\",\"\",\"\"]}";
  auto locale_bytes = fml::MallocMapping::Copy(
      locale_json, locale_json + std::strlen(locale_json));
  fml::RefPtr<flutter::PlatformMessageResponse> response;
  shell->GetPlatformView()->DispatchPlatformMessage(
      std::make_unique<flutter::PlatformMessage>(
          "flutter/localization", std::move(locale_bytes), response));

  std::initializer_list<fml::FileMapping::Protection> protection = {
      fml::FileMapping::Protection::kRead};
  auto main_dart_file_mapping = std::make_unique<fml::FileMapping>(
      fml::OpenFile(
          fml::paths::AbsolutePath(settings.application_kernel_asset).c_str(),
          false, fml::FilePermission::kRead),
      protection);

  auto isolate_configuration =
      IsolateConfiguration::CreateForKernel(std::move(main_dart_file_mapping));

  if (!isolate_configuration) {
    FML_LOG(ERROR) << "Could create isolate configuration.";
    return EXIT_FAILURE;
  }

  auto asset_manager = std::make_shared<flutter::AssetManager>();
  asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
      fml::Duplicate(settings.assets_dir), true));
  asset_manager->PushBack(std::make_unique<flutter::DirectoryAssetBundle>(
      fml::OpenDirectory(settings.assets_path.c_str(), false,
                         fml::FilePermission::kRead),
      true));

  RunConfiguration run_configuration(std::move(isolate_configuration),
                                     std::move(asset_manager));

  // The script completion task observer that will be installed on the UI thread
  // that watched if the engine has any live ports.
  ScriptCompletionTaskObserver completion_observer(
      *shell,  // a valid shell
      fml::MessageLoop::GetCurrent()
          .GetTaskRunner(),  // the message loop to terminate
      run_forever            // should the exit be ignored
  );

  bool engine_did_run = false;

  fml::AutoResetWaitableEvent latch;
  auto task_observer_add = [&completion_observer]() {
    fml::MessageLoop::GetCurrent().AddTaskObserver(
        reinterpret_cast<intptr_t>(&completion_observer),
        [&completion_observer]() { completion_observer.DidProcessTask(); });
  };

  auto task_observer_remove = [&completion_observer, &latch]() {
    fml::MessageLoop::GetCurrent().RemoveTaskObserver(
        reinterpret_cast<intptr_t>(&completion_observer));
    latch.Signal();
  };

  shell->RunEngine(std::move(run_configuration),
                   [&engine_did_run, &ui_task_runner,
                    &task_observer_add](Engine::RunStatus run_status) mutable {
                     if (run_status != flutter::Engine::RunStatus::Failure) {
                       engine_did_run = true;
                       // Now that our engine is initialized we can install the
                       // ScriptCompletionTaskObserver
                       fml::TaskRunner::RunNowOrPostTask(ui_task_runner,
                                                         task_observer_add);
                     }
                   });

  ConfigureShell(shell);

  // Run the message loop and wait for the script to do its thing.
  fml::MessageLoop::GetCurrent().Run();

  // Cleanup the completion observer synchronously as it is living on the
  // stack.
  fml::TaskRunner::RunNowOrPostTask(ui_task_runner, task_observer_remove);
  latch.Wait();

  delete g_shell->release();

  if (!engine_did_run) {
    // If the engine itself didn't have a chance to run, there is no point in
    // asking it if there was an error. Signal a failure unconditionally.
    return EXIT_FAILURE;
  }

  return completion_observer.GetExitCodeForLastError();
}

#ifdef _WIN32
#define EXPORTED __declspec(dllexport)
#else
#define EXPORTED __attribute__((visibility("default")))
#endif

extern "C" {
EXPORTED Dart_Handle LoadLibraryFromKernel(const char* path) {
  std::shared_ptr<fml::FileMapping> mapping =
      fml::FileMapping::CreateReadOnly(path);
  if (!mapping) {
    return Dart_Null();
  }
  return DartIsolate::LoadLibraryFromKernel(mapping);
}

EXPORTED Dart_Handle LookupEntryPoint(const char* uri, const char* name) {
  if (!uri || !name) {
    return Dart_Null();
  }
  Dart_Handle lib = Dart_LookupLibrary(Dart_NewStringFromCString(uri));
  if (Dart_IsError(lib)) {
    return lib;
  }
  return Dart_GetField(lib, Dart_NewStringFromCString(name));
}

EXPORTED void Spawn(const char* entrypoint, const char* route) {
  auto shell = g_shell->get();
  auto isolate = Dart_CurrentIsolate();
  auto spawn_task = [shell, entrypoint = std::string(entrypoint),
                     route = std::string(route)]() {
    auto configuration = RunConfiguration::InferFromSettings(
        shell->GetSettings(), /*io_worker=*/nullptr,
        /*launch_type=*/IsolateLaunchType::kExistingGroup);
    configuration.SetEntrypoint(entrypoint);

    Shell::CreateCallback<PlatformView> on_create_platform_view =
        fml::MakeCopyable([](Shell& shell) mutable {
          ImpellerVulkanContextHolder impeller_context_holder;
          return std::make_unique<TesterPlatformView>(
              shell, shell.GetTaskRunners(),
              std::move(impeller_context_holder));
        });

    Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
      return std::make_unique<Rasterizer>(
          shell, Rasterizer::MakeGpuImageBehavior::kBitmap);
    };

    // Spawn a shell, and keep it running until it has no live ports, then
    // delete it on the platform thread.
    auto spawned_shell =
        shell
            ->Spawn(std::move(configuration), route, on_create_platform_view,
                    on_create_rasterizer)
            .release();

    ConfigureShell(spawned_shell);

    fml::TaskRunner::RunNowOrPostTask(
        spawned_shell->GetTaskRunners().GetUITaskRunner(), [spawned_shell]() {
          fml::MessageLoop::GetCurrent().AddTaskObserver(
              reinterpret_cast<intptr_t>(spawned_shell), [spawned_shell]() {
                if (spawned_shell->EngineHasLivePorts()) {
                  return;
                }

                fml::MessageLoop::GetCurrent().RemoveTaskObserver(
                    reinterpret_cast<intptr_t>(spawned_shell));
                // Shell must be deleted on the platform task runner.
                fml::TaskRunner::RunNowOrPostTask(
                    spawned_shell->GetTaskRunners().GetPlatformTaskRunner(),
                    [spawned_shell]() { delete spawned_shell; });
              });
        });
  };
  Dart_ExitIsolate();
  // The global shell pointer is never deleted, short of application exit.
  // This UI task runner cannot be latched because it will block spawning a new
  // shell in the case where flutter_tester is running multithreaded.
  fml::TaskRunner::RunNowOrPostTask(
      shell->GetTaskRunners().GetPlatformTaskRunner(), spawn_task);

  Dart_EnterIsolate(isolate);
}

EXPORTED void ForceShutdownIsolate() {
  // Enable Isolate.exit().
  FML_DCHECK(Dart_CurrentIsolate() != nullptr);
  Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
  FML_CHECK(!tonic::CheckAndHandleError(isolate_lib));
  Dart_Handle isolate_type = Dart_GetNonNullableType(
      isolate_lib, tonic::ToDart("Isolate"), 0, nullptr);
  FML_CHECK(!tonic::CheckAndHandleError(isolate_type));
  Dart_Handle result =
      Dart_SetField(isolate_type, tonic::ToDart("_mayExit"), Dart_True());
  FML_CHECK(!tonic::CheckAndHandleError(result));
}
}

}  // namespace flutter

int main(int argc, char* argv[]) {
  dart::bin::SetExecutableName(argv[0]);
  dart::bin::SetExecutableArguments(argc - 1, argv);

  auto command_line = fml::CommandLineFromPlatformOrArgcArgv(argc, argv);

  if (command_line.HasOption(flutter::FlagForSwitch(flutter::Switch::Help))) {
    flutter::PrintUsage("flutter_tester");
    return EXIT_SUCCESS;
  }

  auto settings = flutter::SettingsFromCommandLine(command_line);
  if (!command_line.positional_args().empty()) {
    // The tester may not use the switch for the main dart file path. Specifying
    // it as a positional argument instead.
    settings.application_kernel_asset = command_line.positional_args()[0];
  }

  if (settings.application_kernel_asset.empty()) {
    FML_LOG(ERROR) << "Dart kernel file not specified.";
    return EXIT_FAILURE;
  }

  settings.leak_vm = false;
  settings.enable_platform_isolates = true;

  if (settings.icu_data_path.empty()) {
    settings.icu_data_path = "icudtl.dat";
  }

  // The tools that read logs get confused if there is a log tag specified.
  settings.log_tag = "";

  settings.log_message_callback = [](const std::string& tag,
                                     const std::string& message) {
    if (!tag.empty()) {
      std::cout << tag << ": ";
    }
    std::cout << message << std::endl;
  };

  settings.task_observer_add = [](intptr_t key, const fml::closure& callback) {
    fml::MessageLoop::GetCurrent().AddTaskObserver(key, callback);
  };

  settings.task_observer_remove = [](intptr_t key) {
    fml::MessageLoop::GetCurrent().RemoveTaskObserver(key);
  };

  settings.unhandled_exception_callback = [](const std::string& error,
                                             const std::string& stack_trace) {
    FML_LOG(ERROR) << "Unhandled exception" << std::endl
                   << "Exception: " << error << std::endl
                   << "Stack trace: " << stack_trace;
    ::exit(1);
    return true;
  };

#if defined(FML_OS_WIN)
  CoInitializeEx(nullptr, COINIT_MULTITHREADED);
#endif  // defined(FML_OS_WIN)

  return flutter::RunTester(settings,
                            command_line.HasOption(flutter::FlagForSwitch(
                                flutter::Switch::RunForever)),
                            command_line.HasOption(flutter::FlagForSwitch(
                                flutter::Switch::ForceMultithreading)));
}
