# 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.
#
#       label (optional)
#         [string] A key on which tests may be grouped. Tests with a given
#         label 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

    # 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.label) &&
                 (env.label == "astro" || env.label == "system-ota-tests"),
             "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.label) &&
                 (env.label == "vim2" || env.label == "system-ota-tests"),
             "vim2s may not yet be targeted.")
    }
  }

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