# 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/platforms.gni")

# Extension identifying a test spec JSON file.
_test_spec_ext = "spec.json"

# TODO(joshuaseaton): Only used in package() today; consider a scheme in which
#   test specs are re-used for host tests.

# 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
#
#   location (required)
#     [string]: Unique reference to a test, e.g., a filesystem path or a
#     fuchsia URI.
#
#   output_dir (required)
#     [string]: Directory where the test spec will be written.
#
#   environments (required)
#     [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.location), "location must be defined.")
  assert(defined(invoker.output_dir), "output_dir must be defined.")
  assert(defined(invoker.environments) && invoker.environments != [],
         "environments must be defined.")

  foreach(env, invoker.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 ])
        },
      ]
    }

    if (platform.cpu == current_cpu) {
      target_platform_dims += [ platform_dims ]
    } else {
      other_platform_dims += [ platform_dims ]
    }
  }

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

    # Empty scopes may have been introduced to dims, corresponding to unset keys;
    # Add and then subtract an empty scope to remove them.
    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")
      }
    }
  }

  test_spec = {
    test = {
      name = get_label_info(":$target_name", "label_no_toolchain")
      location = invoker.location
    }
    environments = target_envs
  }

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

  # We take the basename just to make sure no other path components are given
  # in the name, for which we have no guarantees.
  target_base_name = get_path_info(target_name, "name")
  write_file("${invoker.output_dir}/${target_base_name}.${_test_spec_ext}",
             test_spec,
             "json")
}
