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

assert(is_fuchsia)

import("//build/fuchsia/sdk.gni")
import("//flutter/common/fuchsia_config.gni")
import("//flutter/tools/fuchsia/dart.gni")
import("//flutter/tools/fuchsia/fuchsia_archive.gni")
import("//flutter/tools/fuchsia/fuchsia_libs.gni")

template("runner") {
  assert(defined(invoker.product), "The parameter 'product' must be defined")
  assert(defined(invoker.output_name),
         "The parameter 'output_name' must be defined")

  invoker_output_name = invoker.output_name
  extra_defines = invoker.extra_defines
  extra_deps = invoker.extra_deps
  if (is_debug) {
    extra_defines += [ "DEBUG" ]  # Needed due to direct dart dependencies.
  }

  executable(target_name) {
    output_name = invoker_output_name

    sources = [
      "builtin_libraries.cc",
      "builtin_libraries.h",
      "dart_component_controller.cc",
      "dart_component_controller.h",
      "dart_runner.cc",
      "dart_runner.h",
      "logging.h",
      "main.cc",
      "service_isolate.cc",
      "service_isolate.h",
    ]

    defines = extra_defines

    dart_deps = []
    if (!invoker.product) {
      dart_deps += [
        "//flutter/shell/platform/fuchsia/runtime/dart/utils:utils",
        "//third_party/dart/runtime/bin:dart_io_api",
      ]
    } else {
      dart_deps += [
        "//flutter/shell/platform/fuchsia/runtime/dart/utils:utils_product",
        "//third_party/dart/runtime/bin:dart_io_api_product",
      ]
    }

    deps = [
             "//flutter/common",
             "//flutter/fml",
             "//flutter/shell/platform/fuchsia/dart-pkg/fuchsia",
             "//flutter/shell/platform/fuchsia/dart-pkg/zircon",
             "$fuchsia_sdk_root/pkg:async",
             "$fuchsia_sdk_root/pkg:async-cpp",
             "$fuchsia_sdk_root/pkg:async-default",
             "$fuchsia_sdk_root/pkg:async-loop",
             "$fuchsia_sdk_root/pkg:async-loop-cpp",
             "$fuchsia_sdk_root/pkg:async-loop-default",
             "$fuchsia_sdk_root/pkg:fidl_cpp",
             "$fuchsia_sdk_root/pkg:sys_inspect_cpp",
             "$fuchsia_sdk_root/pkg:sys_cpp",
             "$fuchsia_sdk_root/pkg:syslog",
             "$fuchsia_sdk_root/pkg:trace",
             "$fuchsia_sdk_root/pkg:trace-provider-so",
             "$fuchsia_sdk_root/pkg:vfs_cpp",
             "//flutter/third_party/tonic",
           ] + dart_deps + extra_deps
  }
}

runner("dart_jit_runner_bin") {
  output_name = "dart_jit_runner"
  product = false
  extra_defines = []
  if (flutter_runtime_mode == "profile") {
    extra_defines += [ "FLUTTER_PROFILE" ]
  }
  extra_deps = [
    "//third_party/dart/runtime:libdart_jit",
    "//third_party/dart/runtime/platform:libdart_platform_jit",
  ]
}

runner("dart_jit_product_runner_bin") {
  output_name = "dart_jit_product_runner"
  product = true
  extra_defines = [ "DART_PRODUCT" ]
  extra_deps = [
    "//third_party/dart/runtime:libdart_jit",
    "//third_party/dart/runtime/platform:libdart_platform_jit",
  ]
}

runner("dart_aot_runner_bin") {
  output_name = "dart_aot_runner"
  product = false
  extra_defines = [ "AOT_RUNTIME" ]
  if (flutter_runtime_mode == "profile") {
    extra_defines += [ "FLUTTER_PROFILE" ]
  }
  extra_deps = [
    "embedder:dart_aot_snapshot_cc",
    "//third_party/dart/runtime:libdart_precompiled_runtime",
    "//third_party/dart/runtime/platform:libdart_platform_precompiled_runtime",
  ]
}

runner("dart_aot_product_runner_bin") {
  output_name = "dart_aot_product_runner"
  product = true
  extra_defines = [
    "AOT_RUNTIME",
    "DART_PRODUCT",
  ]
  extra_deps = [
    "embedder:dart_aot_product_snapshot_cc",
    "//third_party/dart/runtime:libdart_precompiled_runtime",
    "//third_party/dart/runtime/platform:libdart_platform_precompiled_runtime",
  ]
}

template("aot_runner_package") {
  assert(defined(invoker.product), "The parameter 'product' must be defined")
  product_suffix = ""
  if (invoker.product) {
    product_suffix = "_product"
  }
  fuchsia_archive(target_name) {
    deps = [ ":dart_aot${product_suffix}_runner_bin" ]
    if (!invoker.product) {
      deps += [
        "vmservice:vmservice_snapshot",
        "//flutter/shell/platform/fuchsia/runtime/dart/profiler_symbols:dart_aot_runner",

        # TODO(kaushikiska): Figure out how to get the profiler symbols for `libdart_precompiled_runtime`
        # "//topaz/runtime/dart/profiler_symbols:libdart_precompiled_runtime",
        observatory_target,
      ]
    }

    binary = "dart_aot${product_suffix}_runner"

    meta_dir = "//flutter/shell/platform/fuchsia/dart_runner/meta"

    meta = [
      {
        path = rebase_path("meta/dart_aot${product_suffix}_runner.cmx")
        dest = "dart_aot${product_suffix}_runner.cmx"
      },
    ]

    libraries = common_libs

    resources = []
    if (!invoker.product) {
      vmservice_snapshot = rebase_path(
              get_label_info("vmservice:vmservice_snapshot", "target_gen_dir") +
              "/vmservice_snapshot.so")
      dart_profiler_symbols = rebase_path(
              get_label_info(
                  "//flutter/shell/platform/fuchsia/runtime/dart/profiler_symbols:dart_aot_runner",
                  "target_gen_dir") + "/dart_aot_runner.dartprofilersymbols")

      inputs = [
        vmservice_snapshot,
        observatory_archive_file,
        dart_profiler_symbols,
      ]

      resources += [
        {
          path = vmservice_snapshot
          dest = "vmservice_snapshot.so"
        },
        {
          path = rebase_path(observatory_archive_file)
          dest = "observatory.tar"
        },
        {
          path = dart_profiler_symbols
          dest = "dart_aot_runner.dartprofilersymbols"
        },
      ]
    }
  }
}

template("jit_runner_package") {
  assert(defined(invoker.product), "The parameter 'product' must be defined")
  product_suffix = ""
  if (invoker.product) {
    product_suffix = "_product"
  }

  fuchsia_archive(target_name) {
    deps = [
      ":dart_jit${product_suffix}_runner_bin",
      "kernel:kernel_core_snapshot${product_suffix}",
    ]

    if (!invoker.product) {
      deps += [
        "//flutter/shell/platform/fuchsia/runtime/dart/profiler_symbols:dart_jit_runner",
        observatory_target,
      ]
    }

    binary = "dart_jit${product_suffix}_runner"

    meta_dir = "//flutter/shell/platform/fuchsia/dart_runner/meta"

    libraries = common_libs

    resources = [
      {
        path =
            rebase_path("$target_gen_dir/kernel/vm_data${product_suffix}.bin")
        dest = "vm_snapshot_data.bin"
      },
      {
        path = rebase_path(
                "$target_gen_dir/kernel/vm_instructions${product_suffix}.bin")
        dest = "vm_snapshot_instructions.bin"
      },
      {
        path = rebase_path(
                "$target_gen_dir/kernel/isolate_data${product_suffix}.bin")
        dest = "isolate_core_snapshot_data.bin"
      },
      {
        path = rebase_path(
                "$target_gen_dir/kernel/isolate_instructions${product_suffix}.bin")
        dest = "isolate_core_snapshot_instructions.bin"
      },
    ]

    if (!invoker.product) {
      resources += [
        {
          path = rebase_path(observatory_archive_file)
          dest = "observatory.tar"
        },
        {
          path = rebase_path(
                  get_label_info(
                      "//flutter/shell/platform/fuchsia/runtime/dart/profiler_symbols:dart_jit_runner",
                      "target_gen_dir") + "/dart_jit_runner.dartprofilersymbols")
          dest = "dart_jit_runner.dartprofilersymbols"
        },
      ]
    }

    meta = [
      {
        path = rebase_path("meta/dart_jit${product_suffix}_runner.cmx")
        dest = "dart_jit${product_suffix}_runner.cmx"
      },
    ]
  }
}

aot_runner_package("dart_aot_runner") {
  product = false
}

aot_runner_package("dart_aot_product_runner") {
  product = true
}

jit_runner_package("dart_jit_runner") {
  product = false
}

jit_runner_package("dart_jit_product_runner") {
  product = true
}
