# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This file introduces two related templates that act like action and
# action_foreach but instead of running a Python script, it will compile a
# given tool in the host toolchain and run that (either once or over the list
# of inputs, depending on the variant).
#
# Parameters
#
#   tool (required)
#       [label] Label of the tool to run. This should be an executable, and
#       this label should not include a toolchain (anything in parens). The
#       host compile of this tool will be used.
#
#   outputs (required)
#       [list of files] Like the outputs of action (if using "compiled_action",
#       this would be just the list of outputs), or action_foreach (if using
#       "compiled_action_foreach", this would contain source expansions mapping
#       input to output files).
#
#   args (required)
#       [list of strings] Same meaning as action/action_foreach.
#
#   inputs (optional)
#       Files the binary takes as input. The step will be re-run whenever any
#       of these change. If inputs is empty, the step will run only when the
#       binary itself changes.
#
#   visibility
#   deps
#   args   (all optional)
#       Same meaning as action/action_foreach.
#
#
# Example of usage:
#
#   compiled_action("run_my_tool") {
#     tool = "//tools/something:mytool"
#     outputs = [
#       "$target_gen_dir/mysource.cc",
#       "$target_gen_dir/mysource.h",
#     ]
#
#     # The tool takes this input.
#     inputs = [ "my_input_file.idl" ]
#
#     # In this case, the tool takes as arguments the input file and the output
#     # build dir (both relative to the "cd" that the script will be run in)
#     # and will produce the output files listed above.
#     args = [
#       rebase_path("my_input_file.idl", root_build_dir),
#       "--output-dir", rebase_path(target_gen_dir, root_build_dir),
#     ]
#   }
#
# You would typically declare your tool like this:
#   if (host_toolchain == current_toolchain) {
#     executable("mytool") {
#       ...
#     }
#   }
# The if statement around the executable is optional. That says "I only care
# about this target in the host toolchain". Usually this is what you want, and
# saves unnecessarily compiling your tool for the target platform. But if you
# need a target build of your tool as well, just leave off the if statement.

import("dart_host_sdk_toolchain.gni")

if (host_os == "win") {
  _host_executable_suffix = ".exe"
} else {
  _host_executable_suffix = ""
}

_dart_root = rebase_path("..")

template("compiled_action") {
  assert(defined(invoker.tool), "tool must be defined for $target_name")
  assert(defined(invoker.outputs), "outputs must be defined for $target_name")
  assert(defined(invoker.args), "args must be defined for $target_name")

  assert(!defined(invoker.sources),
         "compiled_action doesn't take a sources arg. Use inputs instead.")

  action(target_name) {
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }

    script = "$_dart_root/build/gn_run_binary.py"

    if (defined(invoker.inputs)) {
      inputs = invoker.inputs
    } else {
      inputs = []
    }
    outputs = invoker.outputs

    # Constuct the host toolchain version of the tool.
    host_tool = invoker.tool + "($dart_host_toolchain)"

    # Get the path to the executable. Currently, this assumes that the tool
    # does not specify output_name so that the target name is the name to use.
    # If that's not the case, we'll need another argument to the script to
    # specify this, since we can't know what the output name is (it might be in
    # another file not processed yet).
    host_executable =
        get_label_info(host_tool, "root_out_dir") + "/" +
        get_label_info(host_tool, "name") + _host_executable_suffix

    # Add the executable itself as an input.
    inputs += [ host_executable ]

    deps = [
      host_tool,
    ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    # The script takes as arguments the binary to run, and then the arguments
    # to pass it.
    args = [
             "compiled_action",
             rebase_path(host_executable, root_build_dir),
           ] + invoker.args
  }
}

template("compiled_action_foreach") {
  assert(defined(invoker.sources), "sources must be defined for $target_name")
  assert(defined(invoker.tool), "tool must be defined for $target_name")
  assert(defined(invoker.outputs), "outputs must be defined for $target_name")
  assert(defined(invoker.args), "args must be defined for $target_name")

  action_foreach(target_name) {
    # Otherwise this is a standalone action, define visibility if requested.
    if (defined(invoker.visibility)) {
      visibility = invoker.visibility
    }

    script = "$_dart_root/build/gn_run_binary.py"
    sources = invoker.sources

    if (defined(invoker.inputs)) {
      inputs = invoker.inputs
    } else {
      inputs = []
    }
    outputs = invoker.outputs

    # Constuct the host toolchain version of the tool.
    host_tool = invoker.tool + "($dart_host_toolchain)"

    # Get the path to the executable. Currently, this assumes that the tool
    # does not specify output_name so that the target name is the name to use.
    # If that's not the case, we'll need another argument to the script to
    # specify this, since we can't know what the output name is (it might be in
    # another file not processed yet).
    host_executable =
        get_label_info(host_tool, "root_out_dir") + "/" +
        get_label_info(host_tool, "name") + _host_executable_suffix

    # Add the executable itself as an input.
    inputs += [ host_executable ]

    deps = [
      host_tool,
    ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    # The script takes as arguments the binary to run, and then the arguments
    # to pass it.
    args = [
             "compiled_action",
             rebase_path(host_executable, root_build_dir),
           ] + invoker.args
  }
}
