# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import("../build/dart/dart_action.gni")
import("../runtime/runtime_args.gni")
import("../sdk_args.gni")

_dart_root = get_path_info("..", "abspath")

declare_args() {
  # Default to building app-jit snapshots. The simulator and cross builds
  # override this to script snapshots to cut down on build time.
  if (target_cpu != host_cpu) {
    dart_snapshot_kind = "kernel"
  } else {
    dart_snapshot_kind = "app-jit"
  }
}

# Creates an app-jit snapshot for a Dart program based on a training run.
#
# Parameters:
#  main_dart (required):
#    The entrypoint to the Dart application.
#
#  training_args (required):
#    Arguments to pass to the Dart application for the training run.
#
#  vm_args (optional):
#    Additional arguments to the Dart VM.
#
#  name (optional):
#    The name of the snapshot if different from the target name. The output
#    will be in $root_gen_dir/$name.dart.snapshot.
#
#  extra_deps (optional):
#    Any additional build dependencies.
#
#  extra_inputs (optional):
#    Any extra build inputs.
#
#  dot_packages (optional):
#    The .packages file for the app. Defaults to the $_dart_root/.packages.
#
#  output (optional):
#    Overrides the full output path.
template("_application_snapshot") {
  assert(defined(invoker.main_dart), "Must specify 'main_dart'")
  assert(defined(invoker.training_args), "Must specify 'training_args'")
  snapshot_vm_args = []
  if (defined(invoker.vm_args)) {
    snapshot_vm_args = invoker.vm_args
  }
  main_dart = invoker.main_dart
  training_args = invoker.training_args
  name = target_name
  if (defined(invoker.name)) {
    name = invoker.name
  }
  extra_deps = []
  if (defined(invoker.deps)) {
    extra_deps += invoker.deps
  }
  extra_inputs = [ main_dart ]
  if (defined(invoker.inputs)) {
    extra_inputs += invoker.inputs
  }
  if (defined(invoker.dot_packages)) {
    dot_packages = invoker.dot_packages
  } else {
    dot_packages = rebase_path("$_dart_root/.packages")
  }
  output = "$root_gen_dir/$name.dart.snapshot"
  if (defined(invoker.output)) {
    output = invoker.output
  }

  # Build the kernel file using the prebuilt VM to speed up the debug and
  # simulator builds.
  prebuilt_dart_action(target_name + "_dill") {
    deps = extra_deps + [
             "$_dart_root/runtime/vm:kernel_platform_files($host_toolchain)",
             "$_dart_root/runtime/vm:vm_platform",
           ]
    gen_kernel_script = "$_dart_root/pkg/vm/bin/gen_kernel.dart"
    platform_dill = "$root_out_dir/vm_platform_strong.dill"

    inputs = extra_inputs + [
               gen_kernel_script,
               platform_dill,
               main_dart,
               dot_packages,
             ]
    output = "$target_gen_dir/$name.dart.dill"
    outputs = [ output ]

    depfile = "$output.d"
    abs_depfile = rebase_path(depfile)
    rebased_output = rebase_path(output, root_build_dir)
    vm_args = [
      "--depfile=$abs_depfile",
      "--depfile_output_filename=$rebased_output",
    ]

    script = gen_kernel_script

    args = [
      "--packages=" + rebase_path(dot_packages),
      "--platform=" + rebase_path(platform_dill),
      "--no-aot",
      "--no-embed-sources",
      "--no-link-platform",
      "--output=" + rebase_path(output),
    ]
    if (dart_platform_bytecode) {
      args += [
        "--gen-bytecode",
        "--drop-ast",
        "--bytecode-options=source-positions",
      ]
    }
    args += [ rebase_path(main_dart) ]
  }

  dart_action(target_name) {
    deps = extra_deps + [ ":${target_name}_dill" ]
    depfile = "$output.d"

    script = "$target_gen_dir/$name.dart.dill"

    inputs = extra_inputs

    outputs = [ output ]

    abs_depfile = rebase_path(depfile)
    abs_output = rebase_path(output, root_build_dir)

    vm_args = [
                "--deterministic",
                "--packages=$dot_packages",
                "--snapshot=$abs_output",
                "--snapshot-depfile=$abs_depfile",
              ] + snapshot_vm_args

    if (dart_snapshot_kind == "kernel") {
      vm_args += [ "--snapshot-kind=kernel" ]
      assert(training_args != "", "Ignoring unused argument")
      args = []
    } else if (dart_snapshot_kind == "app-jit") {
      vm_args += [ "--snapshot-kind=app-jit" ]
      args = training_args
    } else {
      assert(false, "Bad dart_snapshot_kind: $dart_snapshot_kind")
    }
  }
}

# Creates an app-jit snapshot for a Dart2 program based on a training run.
#
# Parameters:
#  main_dart (required):
#    The entrypoint to the Dart application.
#
#  training_args (required):
#    Arguments to pass to the Dart application for the training run.
#
#  vm_args (optional):
#    Additional arguments to the Dart VM.
#
#  name (optional):
#    The name of the snapshot if different from the target name. The output
#    will be in $root_gen_dir/$name.dart.snapshot.
#
#  deps (optional):
#    Any build dependencies.
#
#  dot_packages (optional):
#    The .packages file for the app. Defaults to the $_dart_root/.packages.
#
#  output (optional):
#    Overrides the full output path.
template("application_snapshot") {
  _application_snapshot(target_name) {
    forward_variables_from(invoker, "*")
    if (!defined(invoker.deps)) {
      deps = []
    }
    deps += [ "$_dart_root/utils/kernel-service:kernel-service" ]
  }
}

# Creates an app-jit snapshot for the common FE based on a training run.
#
# Parameters:
#  main_dart (required):
#    The entrypoint to the Dart application.
#
#  training_args (required):
#    Arguments to pass to the Dart application for the training run.
#
#  vm_args (optional):
#    Additional arguments to the Dart VM.
#
#  name (optional):
#    The name of the snapshot if different from the target name. The output
#    will be in $root_gen_dir/$name.dart.snapshot.
#
#  deps (optional):
#    Any build dependencies.
#
#  dot_packages (optional):
#    The .packages file for the app. Defaults to the $_dart_root/.packages.
#
#  output (optional):
#    Overrides the full output path.
template("kernel_application_snapshot") {
  _application_snapshot(target_name) {
    forward_variables_from(invoker, "*")
  }
}
