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

import("//third_party/dart/runtime/bin/vmservice/vmservice_sources.gni")
import("$flutter_root/common/config.gni")
import("$flutter_root/testing/testing.gni")

source_set("test_font") {
  sources = [
    "test_font_data.cc",
    "test_font_data.h",
  ]
  deps = [
    "//third_party/skia",
  ]
  public_configs = [ "$flutter_root:config" ]
  defines = []
  if (flutter_runtime_mode == "debug" || current_toolchain == host_toolchain) {
    # Though the test font data is small, we dont want to add to the binary size
    # on the device (in profile and release modes). We only add the same on the
    # host test shells and the debug device shell.
    defines += [ "EMBED_TEST_FONT_DATA=1" ]
  }
}

# Picks the libdart implementation based on the Flutter runtime mode.
group("libdart") {
  public_deps = []

  if (!(is_fuchsia && using_fuchsia_sdk)) {
    if (flutter_runtime_mode == "profile" ||
        flutter_runtime_mode == "release") {
      public_deps +=
          [ "//third_party/dart/runtime:libdart_precompiled_runtime" ]
    } else {
      public_deps += [
        "$flutter_root/lib/snapshot",
        "//third_party/dart/runtime:libdart_jit",
      ]
    }
  }
}

source_set("runtime") {
  sources = [
    "dart_isolate.cc",
    "dart_isolate.h",
    "dart_service_isolate.cc",
    "dart_service_isolate.h",
    "dart_snapshot.cc",
    "dart_snapshot.h",
    "dart_vm.cc",
    "dart_vm.h",
    "dart_vm_data.cc",
    "dart_vm_data.h",
    "dart_vm_lifecycle.cc",
    "dart_vm_lifecycle.h",
    "embedder_resources.cc",
    "embedder_resources.h",
    "ptrace_ios.cc",
    "ptrace_ios.h",
    "runtime_controller.cc",
    "runtime_controller.h",
    "runtime_delegate.cc",
    "runtime_delegate.h",
    "service_protocol.cc",
    "service_protocol.h",
    "skia_concurrent_executor.cc",
    "skia_concurrent_executor.h",
    "start_up.cc",
    "start_up.h",
  ]

  deps = [
    ":test_font",
    "$flutter_root/assets",
    "$flutter_root/common",
    "$flutter_root/flow",
    "$flutter_root/fml",
    "$flutter_root/lib/io",
    "$flutter_root/lib/ui",
    "$flutter_root/third_party/txt",
    "//third_party/dart/runtime:dart_api",
    "//third_party/dart/runtime/bin:dart_io_api",
    "//third_party/skia",
    "//third_party/tonic",
  ]

  # On Windows the engine finds the Dart snapshot data through symbols
  # that are statically linked into the executable. On other platforms this
  # data is obtained by a dynamic symbol lookup.
  # The current Windows platform uses static-link instead of dynamic lookups.
  # Because:
  #  1. The size of the executable on Windows is not as concerned as on mobile
  #     platforms.
  #  2. If it is a dynamic lookup method, you need to modify the properties of
  #     the memory page after the *.bin is dynamically loaded at runtime and
  #     mark it as executable. This is feasible (similar to V8 on Windows), but
  #     this increases the complexity of the implementation(These operations
  #     involve the use of some system file/memory privilege APIs and there is
  #     a risk of failure).
  #  3. In the executable can enjoy the advantages of the windows preload
  #     mechanism, speed up I/O.
  if (is_win) {
    if (flutter_runtime_mode == "profile" ||
        flutter_runtime_mode == "release") {
      deps += [ "$flutter_root/lib/snapshot" ]
    }
  }

  public_deps = [
    "//third_party/rapidjson",
  ]

  public_configs = [ "$flutter_root:config" ]

  if (flutter_runtime_mode != "release" && !is_fuchsia) {
    # Only link in Observatory in non-release modes on non-Fuchsia. Fuchsia
    # instead puts Observatory into the runner's package.
    deps += [
      "//third_party/dart/runtime/observatory:embedded_observatory_archive",
    ]
  }
}

test_fixtures("runtime_fixtures") {
  dart_main = "fixtures/runtime_test.dart"
}

source_set("runtime_unittests_common") {
  visibility = [ ":*" ]

  testonly = true

  sources = [
    "runtime_test.cc",
    "runtime_test.h",
  ]

  public_deps = [
    ":libdart",
    ":runtime",
    ":runtime_fixtures",
    "$flutter_root/common",
    "$flutter_root/fml",
    "$flutter_root/lib/snapshot",
    "$flutter_root/shell/common",
    "$flutter_root/testing:dart",
    "//third_party/skia",
    "//third_party/tonic",
  ]
}

executable("runtime_unittests") {
  testonly = true

  configs += [ "$flutter_root:export_dynamic_symbols" ]

  sources = [
    "dart_isolate_unittests.cc",
    "dart_lifecycle_unittests.cc",
    "dart_service_isolate_unittests.cc",
    "dart_vm_unittests.cc",
  ]

  deps = [
    ":runtime_unittests_common",
  ]
}
