# Copyright 2019 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.

# These rules are only used by the Fuchsia host build
# (i.e. generating host executables for testing with the Fuchsia build system).

import("//build/testing/environments.gni")
import("build_settings.gni")

_is_fuchsia_tree = defined(is_fuchsia_tree) && is_fuchsia_tree
if (_is_fuchsia_tree) {
  import("//build/testing/test_spec.gni")
}

# A target providing access to Vulkan at compile time when added to deps.
graphics_compute_vulkan_loader_target = "//src/lib/vulkan"

# A target that provides the GTest main() function for the host.
graphics_compute_gtest_main_target = "//src/lib/fxl/test:gtest_main"

# NOTE: These definitions are used by those in build_rules.gni.

# Accepts same variables as GN executable() rule, as well as:
#   needs_vulkan: Optional flag. Set to true to add Vulkan dependencies.
template("graphics_compute_executable_rule") {
  _binary_target = "bin_${target_name}"

  executable(_binary_target) {
    forward_variables_from(invoker,
                           "*",
                           [
                             # Avoid clobbering default configs
                             "configs",
                             "needs_vulkan",
                           ])
    if (!defined(output_name)) {
      output_name = target_name
    }
    if (defined(invoker.configs)) {
      configs += invoker.configs
    }
    if (defined(invoker.needs_vulkan) && invoker.needs_vulkan) {
      if (!defined(deps)) {
        deps = []
      }
      deps += [ graphics_compute_vulkan_loader_target ]
    }
  }

  group(target_name) {
    # This host executable is never a tool to be used outside the build
    if (is_host) {
      metadata = {
        tool_barrier = []
      }
    }
    if (defined(invoker.testonly)) {
      testonly = invoker.testonly
    }
    public_deps = [ ":${_binary_target}" ]
  }
}

# Accepts same variables as GN executable() rule, as well as:
#   needs_vulkan: Optional flag. Set to true to add Vulkan dependencies.
template("graphics_compute_test_rule") {
  _binary_target = "bin_${target_name}"

  graphics_compute_executable_rule(_binary_target) {
    testonly = true
    output_name = invoker.target_name
    forward_variables_from(invoker, "*", [ "target_name" ])
  }

  _deps = [ ":${_binary_target}" ]

  # For Fuchsia, ensure the test is visible for 'fx run-host-tests <test_name>'
  if (_is_fuchsia_tree) {
    _test_spec_target_name = "${target_name}__test_spec"
    test_spec(_test_spec_target_name) {
      target = get_label_info(":${invoker.target_name}", "label_with_toolchain")
      path = "${root_out_dir}/${invoker.target_name}"
      if (defined(invoker.needs_vulkan) && invoker.needs_vulkan) {
        environments = []  # There are no host environments with Vulkan
      }
    }

    _deps += [ ":${_test_spec_target_name}" ]
  }

  group(target_name) {
    # This executable is *never* a tool to be used outside the build
    metadata = {
      tool_barrier = []
    }
    testonly = true
    deps = _deps
  }
}
