# 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",
      "--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 = [
      "--causal_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
  }
}
