# Copyright 2018 The Fuchsia 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/testing/environments.gni")
import("//build/testing/platforms.gni")

# Describes the target device environment in which a test should run. This
# specification is written in JSON to the build directory, to be aggregated
# at test-time.
#
# Parameters
#
#   name (required)
#     [string] The test's target name.
#
#   location (required)
#     [string]: Unique reference to a test, e.g., a filesystem path or a
#     fuchsia URI.
#
#   command (optional)
#     [list of strings]: Command to invoke to run the test. If unset, location
#     will be invoked upon execution.
#
#   deps (optional)
#     [list of labels]: List of labels that the test depends on.
#
#   environments (optional, default: QEMU for fuchsia; else a VM)
#     [list of scopes] Device environments in which the test should run.
#
#     Each scope in $environments contains:
#
#       dimensions (required)
#         [scope] Dimensions of bots to target. Valid dimensions are
#         element-wise subsets of the test platform entries defined in
#         //build/testing/platforms.gni.
#
#       tags (optional)
#         [list of strings] keys on which tests may be grouped. Tests with
#         given tags will be run (1) together, and (2) only with support from
#         the Infrastructure team. Labels are used as an escape hatch from the
#         default testing pipeline for special tests or environments.
#
template("test_spec") {
  assert(defined(invoker.name), "name must be defined.")
  assert(defined(invoker.location), "location must be defined.")
  forward_variables_from(invoker,
                         [
                           "environments",

                           # Not all test-defining targets have testonly = true
                           # (e.g., rust library targets with unit tests)
                           "testonly",
                         ])

  # Set default environments: QEMU for a fuchsia test, and VMs for linux and mac
  # tests.
  if (is_fuchsia) {
    envs_specified = defined(environments)
    if (!envs_specified) {
      environments = [ qemu_env ]
    }

    if (current_cpu == "arm64") {
      # TODO(IN-876): Remove after astros are ready to be targeted.
      environments += [ astro_env ]
      if (!envs_specified) {
        # TODO(IN-571): Remove after vim2s are ready to be targeted.
        environments += [ vim2_env ]
      }
    }
  } else if (is_linux || is_mac) {
    if (!defined(environments)) {
      if (is_linux) {
        environments = [ linux_env ]
      } else if (is_mac) {
        environments = [ mac_env ]
      }
    }
  } else {
    assert(false, "$current_os not supported")
  }

  foreach(env, environments) {
    empty_scope = {  # Clear from previous iteration
    }
    assert(defined(env.dimensions) && env.dimensions != empty_scope,
           "each environment must specify dimensions")
  }

  # Call "expanding" the operation that takes a scope
  # {
  #  x = a
  #  y = b
  #  z = c
  #  ...
  # }
  # and converts it to a list [{x=a}, {y=b}, {z=c},...].
  #
  # Expand each scope of test platform dimensions and group them by architecture
  # (i.e., cpu). The same thing is done below with each environment's dimensions
  # scope to more easily compare.
  target_platform_dims = []
  other_platform_dims = []
  foreach(platform, test_platforms) {
    platform_dims = []  # Clear from previous iteration.
    foreach(key, all_dimension_keys) {
      platform_dims += [
        {
          forward_variables_from(platform, [ key ])
        },
      ]
    }

    # Empty scopes may have been introduced to platform_dims, corresponding to
    # non-existent keys;
    # Add and then subtract an empty scope to remove them.
    empty_dim = {  # Clear from previous iteration.
    }
    platform_dims += [ empty_dim ]
    platform_dims -= [ empty_dim ]

    if (!defined(platform.cpu) || platform.cpu == target_cpu) {
      target_platform_dims += [ platform_dims ]
    } else {
      other_platform_dims += [ platform_dims ]
    }
  }

  target_envs = []
  foreach(env, environments) {
    dims = []  # Clear from previous iteration.
    if (defined(env.dimensions)) {
      foreach(key, all_dimension_keys) {
        dims += [
          {
            forward_variables_from(env.dimensions, [ key ])
          },
        ]
      }
    }
    empty_dim = {  # Clear from previous iteration.
    }
    dims += [ empty_dim ]
    dims -= [ empty_dim ]

    # Check if the environment's dimensions match those of a platform of the
    # target architecture; if a match, include the environment among the
    # test spec's.
    # Note that in GN "A is a subset of B" is equivalent to `A + B - B == []`.
    match = false
    foreach(platform_dims, target_platform_dims) {
      if (dims + platform_dims - platform_dims == []) {
        match = true
        target_envs += [ env ]
      }
    }

    # If the environment's dimensions do not match a target architecture, ensure
    # that they match those of a platform of another architecture.
    if (!match) {
      foreach(platform_dims, other_platform_dims) {
        match = match || dims + platform_dims - platform_dims == []
      }
      if (!match) {
        print("Could not match environment specifications for '$target_name':")
        print("$env")
        assert(
            match,
            "Consult //build/testing/platforms.gni for all allowable specifications")
      }
    }
  }

  target_name_deps = []

  # Rely on metadata reachable through deps to determine any runtime
  # dependencies of the test; record them to a file.
  runtime_deps_file = ""
  if (defined(invoker.deps) && invoker.deps != []) {
    test_name = get_path_info(invoker.name, "name")
    runtime_deps_file = "$target_gen_dir/${test_name}.deps.json"
    runtime_deps_target_name = "${target_name}_deps"

    generated_file(runtime_deps_target_name) {
      outputs = [
        runtime_deps_file,
      ]
      data_keys = [ "test_runtime_deps" ]
      deps = invoker.deps
      rebase = root_build_dir
      output_conversion = "json"
    }

    target_name_deps += [ ":$runtime_deps_target_name" ]
  }

  test_spec = {
    test = {
      name = get_label_info(":${invoker.name}", "label_no_toolchain")
      location = invoker.location
      if (is_linux || is_mac) {
        # Trim leading //.
        location = rebase_path(location, root_build_dir)
        forward_variables_from(invoker, [ "command" ])
      }
      os = current_os
      cpu = current_cpu
      if (runtime_deps_file != "") {
        deps_file = rebase_path(runtime_deps_file, root_build_dir)
      }
    }
    environments = []  # Clear from above.
    environments = target_envs
  }

  foreach(env, target_envs) {
    dims = []  # Clear from previous iteration.
    dims = env.dimensions

    if (defined(dims.os) && dims.os == "mac") {
      # When running tests for a mac build, we only wish to run mac tests; we
      # enforce the "mac" tag in that case to filter out other tests.
      assert(defined(env.tags) && ["mac"] + env.tags  - env.tags == [],
             "Mac environments must have a tag of \"mac\"")
    }

    # TODO(IN-876): Delete this block once astros are ready to be targeted.
    if (defined(dims.device_type) && dims.device_type == "Astro") {
      assert(defined(env.tags) && [ "astro" ] + env.tags - env.tags == [],
             "astros may not yet be targeted.")
    }

    # TODO(IN-571): Delete this block once vim2s are ready to be targeted.
    if (defined(dims.device_type) && dims.device_type == "Khadas Vim2 Max") {
      assert(defined(env.tags) && [ "vim2" ] + env.tags - env.tags == [],
             "vim2s may not yet be targeted.")
    }
  }

  group(target_name) {
    metadata = {
      test_spec = [ test_spec ]
    }
    deps = target_name_deps
  }
}
