# Copyright 2023 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")

import("$dir_pw_build/python.gni")
import("$dir_pw_build/test_info.gni")

# Creates a Python action to use as a test and associated metadata.
#
# This template derives several additional targets:
#   - <target_name>.metadata produces the test metadata when included in a
#     `pw_test_group`. This metadata includes the Ninja target that runs the
#     test.
#   - <target_name>.script creates a `pw_python_action` to run the test and
#     wraps it as a standalone `pw_python_package`.
#   - <target_name>.group creates a `pw_python_group` in order to apply tools,
#     e.g. linters, to the standalone package.
#   - <target_name>.lib is an empty group for compatibility with
#     `pw_test_group`.
#   - <target_name>.run invokes the test.
#
# Targets defined using this template will produce test metadata with a
# `test_type` of "action_test" and a `ninja_target` value that will invoke the
# test when passed to Ninja, i.e. `ninja -C out <ninja_target>`.
#
# Args:
#   - The following args have the same meaning as for `pw_test`:
#         enable_if
#         envvars (may also use `environment`)
#         tags
#         extra_metadata
#         source_gen_deps
#
#   - The following args have the same meaning as for `pw_python_action`:
#         script (may be omitted if `sources` has length=1)
#         args
#         deps
#         environment (may also use `envvars`)
#         working_directory
#         command_launcher
#         venv
#
#   - The following args have the same meaning as for `pw_python_package`:
#         sources
#         python_deps
#         other_deps
#         inputs
#         static_analysis
#         pylintrc
#         mypy_ini
#         ruff_toml
#
#   - action: Optional string or scope. If a string, this should be a label to
#         a `pw_python_action` target that performs the test. If a scope, this
#         has the same meaning as for `pw_python_script`.
template("pw_python_action_test") {
  _test_target_name = target_name
  _deps = []
  _run_deps = []
  _metadata = {
  }

  _test_is_enabled = !defined(invoker.enable_if) || invoker.enable_if
  if (_test_is_enabled) {
    # Metadata for this test when used as part of a pw_test_group target.
    _test_metadata = "${target_name}.metadata"
    _ninja_target = "$target_out_dir/$target_name.run.stamp"
    _extra_metadata = {
      forward_variables_from(invoker, [ "extra_metadata" ])
      ninja_target = rebase_path(_ninja_target, root_build_dir)
    }
    pw_test_info(_test_metadata) {
      test_type = "action_test"
      test_name = _test_target_name
      forward_variables_from(invoker, [ "tags" ])
      extra_metadata = _extra_metadata
    }
    _deps += [ ":$_test_metadata" ]
    _metadata = {
      test_barrier = [ ":$_test_metadata" ]
    }

    if (defined(invoker.action) && invoker.action == "${invoker.action}") {
      # `action` is a label to an existing Python action.
      _run_deps = [ invoker.action ]
      if (defined(invoker.deps)) {
        _deps += invoker.deps
      }
    } else {
      # Wrap the action in a Python script target for additional flexibility.
      _test_script_name = _test_target_name + ".script"

      _sources = []
      if (defined(invoker.script)) {
        _sources += [ invoker.script ]
      }
      if (defined(invoker.sources)) {
        _sources += invoker.sources
      }

      pw_python_script(_test_script_name) {
        other_deps = []
        forward_variables_from(invoker,
                               [
                                 "action",
                                 "python_deps",
                                 "other_deps",
                                 "inputs",
                                 "static_analysis",
                                 "testonly",
                                 "pylintrc",
                                 "mypy_ini",
                                 "ruff_toml",
                               ])
        sources = _sources
        if (defined(invoker.source_gen_deps)) {
          other_deps += invoker.source_gen_deps
        }
        if (!defined(pylintrc)) {
          pylintrc = "$dir_pigweed/.pylintrc"
        }
        if (!defined(mypy_ini)) {
          mypy_ini = "$dir_pigweed/.mypy.ini"
        }
        if (!defined(ruff_toml)) {
          ruff_toml = "$dir_pigweed/.ruff.toml"
        }
        if (!defined(action)) {
          action = {
            environment = []
            forward_variables_from(invoker,
                                   [
                                     "script",
                                     "args",
                                     "deps",
                                     "environment",
                                     "working_directory",
                                     "command_launcher",
                                     "venv",
                                   ])
            if (defined(invoker.envvars)) {
              environment += invoker.envvars
            }
            stamp = true
          }
        }
      }
      _deps += [ ":$_test_script_name" ]
      _run_deps = [ ":$_test_script_name.action" ]

      # Create a Python group in order to ensure the package is linted.
      _test_python_group = _test_target_name + ".group"
      pw_python_group(_test_python_group) {
        python_deps = [ ":$_test_script_name" ]
      }
      _deps += [ ":$_test_python_group" ]
    }
  } else {
    not_needed(invoker, "*")
    if (defined(invoker.source_gen_deps)) {
      _deps += invoker.source_gen_deps
    }
  }

  # For compatibility with `pw_test_group`.
  group(_test_target_name + ".lib") {
    forward_variables_from(invoker, [ "testonly" ])
  }

  # For compatibility with `pw_test_group`.
  group(_test_target_name + ".run") {
    forward_variables_from(invoker, [ "testonly" ])
    deps = _run_deps
  }

  group(_test_target_name) {
    forward_variables_from(invoker, [ "testonly" ])
    deps = _deps
    metadata = _metadata
  }
}
