# Copyright 2020 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import("//build_overrides/pigweed.gni")

# Defines an action that runs a Python script.
#
# This wraps a regular Python script GN action with an invocation of a script-
# runner script that adds useful features. pw_python_action() uses the same
# actions as GN's action(), with the following additions or changes:
#
#   module          May be used in place of the script argument to run the
#                   provided Python module with `python -m` instead of a script.
#                   Either script or module must be provided.
#
#   capture_output  If true, script output is hidden unless the script fails
#                   with an error. Defaults to true.
#
#   stamp           File to touch if the script is successful. Actions that
#                   don't create output files can use this stamp file instead of
#                   creating their own placeholder file. If true, a generic file
#                   is used. If false or not set, no file is touched.
#
#   environment     Environment variables to set, passed as a list of NAME=VALUE
#                   strings.
#
#   args            Same as the standard action args, except special expressions
#                   may be used to extract information not normally accessible
#                   in GN. These include the following:
#
#                     <TARGET_FILE(//some/label:here)> - expands to the
#                         output file (such as a .a or .elf) from a GN target
#                     <TARGET_FILE_IF_EXISTS(//some/label:here)> - expands to
#                         the output file if the target exists, or nothing
#                     <TARGET_OBJECTS(//some/label:here)> - expands to the
#                         object files produced by the provided GN target
#
#   python_deps     Dependencies on pw_python_package or related Python targets.
#
#   working_directory  Switch to the provided working directory before running
#                      the Python script or action.
#
template("pw_python_action") {
  assert(defined(invoker.script) != defined(invoker.module),
         "pw_python_action requires either 'script' or 'module'")

  _script_args = [
    # GN root directory relative to the build directory (in which the runner
    # script is invoked).
    "--gn-root",
    rebase_path("//", root_build_dir),

    # Current directory, used to resolve relative paths.
    "--current-path",
    rebase_path(".", root_build_dir),

    "--default-toolchain=$default_toolchain",
    "--current-toolchain=$current_toolchain",
  ]

  if (defined(invoker.environment)) {
    foreach(variable, invoker.environment) {
      _script_args += [ "--env=$variable" ]
    }
  }

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

  # List the script to run as an input so that the action is re-run when it is
  # modified.
  if (defined(invoker.script)) {
    _inputs += [ invoker.script ]
  }

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

  # If a stamp file is requested, add it as an output of the runner script.
  if (defined(invoker.stamp) && invoker.stamp != false) {
    if (invoker.stamp == true) {
      _stamp_file = "$target_gen_dir/$target_name.pw_pystamp"
    } else {
      _stamp_file = invoker.stamp
    }

    _outputs += [ _stamp_file ]
    _script_args += [
      "--touch",
      rebase_path(_stamp_file, root_build_dir),
    ]
  }

  # Capture output or not (defaults to true).
  if (!defined(invoker.capture_output) || invoker.capture_output) {
    _script_args += [ "--capture-output" ]
  }

  if (defined(invoker.module)) {
    _script_args += [
      "--module",
      invoker.module,
    ]
  }

  if (defined(invoker.working_directory)) {
    _script_args += [
      "--working-directory",
      invoker.working_directory,
    ]
  }

  # "--" indicates the end of arguments to the runner script.
  # Everything beyond this point is interpreted as the command and arguments
  # of the Python script to run.
  _script_args += [ "--" ]

  if (defined(invoker.script)) {
    _script_args += [ rebase_path(invoker.script, root_build_dir) ]
  }

  if (defined(invoker.args)) {
    _script_args += invoker.args
  }

  if (defined(invoker._pw_action_type)) {
    _action_type = invoker._pw_action_type
  } else {
    _action_type = "action"
  }

  if (defined(invoker.deps)) {
    _deps = invoker.deps
  } else {
    _deps = []
  }

  if (defined(invoker.python_deps)) {
    foreach(dep, invoker.python_deps) {
      _deps += [ get_label_info(dep, "label_no_toolchain") + ".install(" +
                 get_label_info(dep, "toolchain") + ")" ]
    }

    # Add the base target as a dep so the action reruns when any source files
    # change, even if the package does not have to be reinstalled.
    _deps += invoker.python_deps
  }

  target(_action_type, target_name) {
    _ignore_vars = [
      "script",
      "args",
      "deps",
      "inputs",
      "outputs",
    ]
    forward_variables_from(invoker, "*", _ignore_vars)

    script = "$dir_pw_build/py/pw_build/python_runner.py"
    args = _script_args
    inputs = _inputs
    outputs = _outputs
    deps = _deps
  }
}

# Runs pw_python_action once per file over a set of sources.
#
# This template brings pw_python_action's features to action_foreach. Usage is
# the same as pw_python_action, except that sources must be provided and source
# expansion (e.g. "{{source}}") may be used in args and outputs.
#
# See the pw_python_action and action_foreach documentation for full details.
template("pw_python_action_foreach") {
  assert(defined(invoker.sources) && invoker.sources != [],
         "pw_python_action_foreach requires a list of one or more sources")

  pw_python_action(target_name) {
    if (defined(invoker.stamp) && invoker.stamp != false) {
      if (invoker.stamp == true) {
        # Use source file names in the generated stamp file path so they are
        # unique for each source.
        stamp = "$target_gen_dir/{{source_file_part}}.pw_pystamp"
      } else {
        stamp = invoker.stamp
      }
    } else {
      stamp = false
    }

    forward_variables_from(invoker, "*", [ "stamp" ])

    _pw_action_type = "action_foreach"
  }
}
