# Copyright 2021 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/python_action.gni")
import("$dir_pw_build/zip.gni")

# Builds a directory containing a collection of Python wheels.
#
# Given one or more pw_python_package targets, this target will build their
# .wheel sub-targets along with the .wheel sub-targets of all dependencies,
# direct and indirect, as understood by GN. The resulting .whl files will be
# collected into a single directory called 'python_wheels'.
#
# Args:
#   packages: A list of pw_python_package targets whose wheels should be
#       included; their dependencies will be pulled in as wheels also.
template("pw_python_wheels") {
  _outer_name = target_name
  _wheel_paths_path = "${target_gen_dir}/${target_name}_wheel_paths.txt"

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

  _packages = []
  foreach(_pkg, invoker.packages) {
    _pkg_name = get_label_info(_pkg, "label_no_toolchain")
    _pkg_toolchain = get_label_info(_pkg, "toolchain")
    _packages += [ "${_pkg_name}.wheel(${_pkg_toolchain})" ]
  }

  # Build a list of relative paths containing all the wheels we depend on.
  generated_file("${target_name}._wheel_paths") {
    data_keys = [ "pw_python_package_wheels" ]
    rebase = root_build_dir
    deps = _packages
    outputs = [ _wheel_paths_path ]
  }

  pw_python_action(target_name) {
    forward_variables_from(invoker, [ "public_deps" ])
    deps = _deps + [ ":${_outer_name}._wheel_paths" ]
    module = "pw_build.collect_wheels"

    args = [
      "--prefix",
      rebase_path(root_build_dir, root_build_dir),
      "--suffix",
      rebase_path(_wheel_paths_path, root_build_dir),
      "--out_dir",
      rebase_path("${target_out_dir}/python_wheels", root_build_dir),
    ]

    stamp = true
  }
}

# Builds a .zip containing Python wheels and setup scripts.
#
# The resulting .zip archive will contain a directory with Python wheels for
# all pw_python_package targets listed in 'packages', plus wheels for any
# pw_python_package targets those packages depend on, directly or indirectly,
# as understood by GN.
#
# In addition to Python wheels, the resulting .zip will also contain simple
# setup scripts for Linux, MacOS, and Windows that take care of creating a
# Python venv and installing all the included wheels into it, and a README.md
# file with setup and usage instructions.
#
# Args:
#   packages: A list of pw_python_package targets whose wheels should be
#       included; their dependencies will be pulled in as wheels also.
#   inputs: An optional list of extra files to include in the generated .zip,
#       formatted the same was as the 'inputs' argument to pw_zip targets.
#   dirs: An optional list of directories to include in the generated .zip,
#       formatted the same way as the 'dirs' argument to pw_zip targets.
template("pw_python_zip_with_setup") {
  _outer_name = target_name
  _zip_path = "${target_out_dir}/${target_name}.zip"

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

  pw_python_wheels("${target_name}.wheels") {
    packages = invoker.packages
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                           ])
  }

  pw_zip("${target_name}") {
    forward_variables_from(invoker, [ "public_deps" ])
    inputs = _inputs + [
               "$dir_pw_build/python_dist/setup.bat > /${target_name}/",
               "$dir_pw_build/python_dist/setup.sh > /${target_name}/",
             ]

    dirs =
        _dirs +
        [ "${target_out_dir}/python_wheels/ > /${target_name}/python_wheels/" ]

    output = _zip_path

    deps = [ ":${_outer_name}.wheels" ]
  }
}

# Generates a directory of Python packages from source files suitable for
# deployment outside of the project developer environment.
#
# The resulting directory contains only files mentioned in each package's
# setup.cfg file. This is useful for bundling multiple Python packages up
# into a single package for distribution to other locations like
# http://pypi.org.
#
# Args:
#   packages: A list of pw_python_package targets to be installed into the build
#     directory. Their dependencies will be pulled in as wheels also.
#
#   include_tests: If true, copy Python package tests to a `tests` subdir.
#
#   extra_files: A list of extra files that should be included in the output. The
#     format of each item in this list follows this convention:
#       //some/nested/source_file > nested/destination_file
template("pw_create_python_source_tree") {
  _output_dir = "${target_out_dir}/${target_name}/"
  _metadata_json_file_list =
      "${target_gen_dir}/${target_name}_metadata_path_list.txt"

  # Convert extra_file strings to input, outputs and create_python_tree.py args.
  _delimiter = ">"
  _extra_file_inputs = []
  _extra_file_outputs = []
  _extra_file_args = []
  if (defined(invoker.extra_files)) {
    foreach(input, invoker.extra_files) {
      # Remove spaces before and after the delimiter
      input = string_replace(input, " $_delimiter", _delimiter)
      input = string_replace(input, "$_delimiter ", _delimiter)

      input_list = []
      input_list = string_split(input, _delimiter)

      # Save the input file
      _extra_file_inputs += [ input_list[0] ]

      # Save the output file
      _this_output = _output_dir + "/" + input_list[1]
      _extra_file_outputs += [ _this_output ]

      # Compose an arg for passing to create_python_tree.py with properly
      # rebased paths.
      _extra_file_args +=
          [ string_join(" $_delimiter ",
                        [
                          rebase_path(input_list[0], root_build_dir),
                          rebase_path(_this_output, root_build_dir),
                        ]) ]
    }
  }

  _include_tests = defined(invoker.include_tests) && invoker.include_tests

  # Build a list of relative paths containing all the python
  # package_metadata.json files we depend on.
  generated_file("${target_name}._metadata_path_list.txt") {
    data_keys = [ "pw_python_package_metadata_json" ]
    rebase = root_build_dir
    deps = invoker.packages
    outputs = [ _metadata_json_file_list ]
  }

  # Run the python action on the metadata_path_list.txt file
  pw_python_action(target_name) {
    deps =
        invoker.packages + [ ":${invoker.target_name}._metadata_path_list.txt" ]
    script = "$dir_pw_build/py/pw_build/create_python_tree.py"
    inputs = _extra_file_inputs

    args = [
      "--tree-destination-dir",
      rebase_path(_output_dir, root_build_dir),
      "--input-list-files",
      rebase_path(_metadata_json_file_list, root_build_dir),
    ]

    if (_extra_file_args == []) {
      # No known output files - stamp instead.
      stamp = true
    } else {
      args += [ "--extra-files" ]
      args += _extra_file_args

      # Include extra_files as outputs
      outputs = _extra_file_outputs
    }

    if (_include_tests) {
      args += [ "--include-tests" ]
    }
  }
}
