# 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/fixtures_location$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 = "dart_snapshot_kernel_$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 = "dart_snapshot_aot_$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 = "fixtures_location_$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 = "copy_fixtures_$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 = "dart_snapshot_$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
  }
}
