# 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("//build/compiled_action.gni")
import("//flutter/common/config.gni")
import("//third_party/dart/build/dart/dart_action.gni")

is_aot_test =
    flutter_runtime_mode == "profile" || flutter_runtime_mode == "release"

# Unit tests targets are only enabled for host machines and Fuchsia right now
declare_args() {
  enable_unittests = current_toolchain == host_toolchain || is_fuchsia
}

# Creates a translation unit that defines the flutter::testing::GetFixturesPath
# method that tests can use to locate their fixtures.
#
# Arguments
#     assets_dir (required): The assets directory
template("fixtures_location") {
  testonly = true

  assert(defined(invoker.assets_dir), "The assets directory.")

  location_path = rebase_path(invoker.assets_dir)

  # Array of source lines. We use a list to ensure a trailing newline is
  # emitted by write_file() to comply with -Wnewline-eof.
  location_source = [ "namespace flutter {namespace testing {const char* GetFixturesPath() {return \"$location_path\";}}}" ]
  location_source_path = "$target_gen_dir/_fl_$target_name.cc"

  write_file(location_source_path, location_source)

  source_set(target_name) {
    public = []
    sources = [ location_source_path ]
  }
}

# Generates the Dart kernel snapshot.
#
# Arguments
#     dart_main (required): The Main Dart file.
#
#     dart_kernel (required): The path to the ouput kernel snapshot in the out
#                             directory.
template("dart_snapshot_kernel") {
  testonly = true

  assert(defined(invoker.dart_main), "The Dart Main file must be specified")
  assert(defined(invoker.dart_kernel),
         "The Dart Kernel file location must be specified")

  dart_action(target_name) {
    testonly = true

    deps = [
      # This generates the Frontend server snapshot used in this Dart action as
      # well as the patched SDK.
      "//third_party/dart/utils/kernel-service:frontend_server",
    ]

    if (is_aot_test) {
      deps += [ "//flutter/lib/snapshot:strong_platform" ]
    }

    script = "$root_out_dir/frontend_server.dart.snapshot"

    inputs = [ invoker.dart_main ]

    outputs = [ invoker.dart_kernel ]

    snapshot_depfile = "$target_gen_dir/snapshot_$target_name.depfile.d"
    depfile = snapshot_depfile

    args = [
      "--sdk-root",
      rebase_path("$root_out_dir/flutter_patched_sdk"),
      "--target",
      "flutter",
      "--enable-experiment=non-nullable",
      "--output-dill",
      rebase_path(invoker.dart_kernel, root_out_dir),
      "--depfile",
      rebase_path(snapshot_depfile),
    ]

    if (flutter_runtime_mode == "release" ||
        flutter_runtime_mode == "jit_release") {
      args += [ "-Ddart.vm.product=true" ]
    }

    if (is_aot_test) {
      args += [
        "--aot",

        # type flow analysis
        "--tfa",
      ]
    }

    args += [ rebase_path(invoker.dart_main) ]
  }
}

# Generates an AOT snapshot from a kernel snapshot.
#
# Arguments:
#
#     dart_kernel (required): The path to the kernel snapshot.
template("dart_snapshot_aot") {
  testonly = true

  assert(defined(invoker.dart_kernel),
         "The Dart Kernel file location must be specified")

  compiled_action(target_name) {
    testonly = true

    tool = "//third_party/dart/runtime/bin:gen_snapshot"

    inputs = [ invoker.dart_kernel ]

    # Custom ELF loader is used for Mac and Windows.
    elf_object = "$target_gen_dir/assets/app_elf_snapshot.so"

    outputs = [ elf_object ]

    args = [
      "--no-causal_async_stacks",
      "--lazy_async_stacks",
      "--deterministic",
      "--snapshot_kind=app-aot-elf",
      "--elf=" + rebase_path(elf_object),
      rebase_path(invoker.dart_kernel),
    ]

    forward_variables_from(invoker, [ "deps" ])
  }
}

# Generates a kernel or AOT snapshot as necessary from the main Dart file.
# Other Dart dependencies referenced by that main Dart file will be tracked.
#
# Arguments:
#
#     dart_main (required): The path to the main Dart file.
template("dart_snapshot") {
  assert(defined(invoker.dart_main), "The main Dart file must be specified.")

  testonly = true

  dart_snapshot_kernel_target_name = "_dsk_$target_name"
  dart_snapshot_kernel_path = "$target_gen_dir/assets/kernel_blob.bin"
  dart_snapshot_kernel(dart_snapshot_kernel_target_name) {
    dart_main = invoker.dart_main
    dart_kernel = dart_snapshot_kernel_path
  }

  snapshot_deps = []
  snapshot_public_deps = [ ":$dart_snapshot_kernel_target_name" ]

  if (is_aot_test) {
    dart_snapshot_aot_target_name = "_dsa_$target_name"
    dart_snapshot_aot(dart_snapshot_aot_target_name) {
      dart_kernel = dart_snapshot_kernel_path
      deps = [ ":$dart_snapshot_kernel_target_name" ]
    }
    snapshot_deps += [ ":$dart_snapshot_aot_target_name" ]
  }

  group(target_name) {
    testonly = true
    deps = snapshot_deps
    public_deps = snapshot_public_deps
  }
}

# Copies a (potentially empty) list of fixtures to the fixtures directory for
# the unit test.
#
# Arguments:
#
#     fixtures (required): The list of fixtures to copy.
template("copy_fixtures") {
  testonly = true

  assert(defined(invoker.fixtures), "The test fixtures must be specified.")

  has_fixtures = false
  foreach(fixture, invoker.fixtures) {
    has_fixtures = true
  }

  if (has_fixtures) {
    copy(target_name) {
      sources = invoker.fixtures
      outputs = [ "$target_gen_dir/assets/{{source_file_part}}" ]
    }
  } else {
    group(target_name) {
      # The copy target cannot accept an empty list.
    }
  }
}

# Specifies the fixtures to copy to a location known by the specific unit test.
# Test executable can only depend on one such target. You can use either one of
# both arguments to expand this template. If you have none, then you'll see the
# unused invoker scope error. In such cases specify the fixtures using an empty
# array.
#
# The targets which generate the outputs from these test fixtures (e.g. the
# Dart kernel snapshot) are exposed as public dependencies of the test fixture
# target. This is so that users can depend on the test fixture target directly
# and be able to access the generated outputs without needing to know about the
# internal dependency structure generated by this template.
#
# Arguments:
#
#     fixtures (optional): The list of test fixtures. An empty list may be
#                          specified.
#
#     dart_main (optional): The path to the main Dart file. If specified, it is
#                           snapshotted.
template("test_fixtures") {
  # Even if no fixtures are present, the location of the fixtures directory
  # must always be known to tests.
  fixtures_location_target_name = "_fl_$target_name"
  fixtures_location(fixtures_location_target_name) {
    if (is_fuchsia) {
      assets_dir = "/pkg/data/assets"
    } else {
      assets_dir = "$target_gen_dir/assets"
    }
  }
  test_deps = [ ":$fixtures_location_target_name" ]
  test_public_deps = []

  # If the fixtures are specified, copy them to the assets directory.
  if (defined(invoker.fixtures)) {
    copy_fixtures_target_name = "_cf_$target_name"
    copy_fixtures(copy_fixtures_target_name) {
      fixtures = invoker.fixtures
    }
    test_public_deps += [ ":$copy_fixtures_target_name" ]
  }

  # If a Dart file is specified, snapshot it and place it in the generated
  # assets directory.
  if (defined(invoker.dart_main)) {
    dart_snapshot_target_name = "_ds_$target_name"
    dart_snapshot(dart_snapshot_target_name) {
      dart_main = invoker.dart_main
    }
    test_public_deps += [ ":$dart_snapshot_target_name" ]
  }

  group(target_name) {
    testonly = true
    deps = test_deps
    public_deps = test_public_deps
  }
}
