# 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_action.gni")

# Mirrors a directory structure to the output directory.
#
# This is similar to a GN copy target, with some differences:
#
#   - The outputs list is generated by the template based on the source_root and
#     directory arguments, rather than using source expansion.
#   - The source_root argument can be used to trim prefixes from source files.
#   - pw_mirror_tree uses hard links instead of copies for efficiency.
#
# Args:
#
#   directory: Output directory for the files.
#   sources: List of files to mirror to the output directory.
#   source_root: Root path for sources; defaults to ".".
#   path_data_keys: GN metadata data_keys from which to extract file or
#       directory paths to add to the list of sources.
#
template("pw_mirror_tree") {
  assert(defined(invoker.sources) || defined(invoker.path_data_keys),
         "At least one of 'sources' or 'path_data_keys' must be provided")
  assert(defined(invoker.directory) && invoker.directory != "",
         "The output path must be specified as 'directory'")

  if (defined(invoker.source_root)) {
    _root = invoker.source_root
  } else {
    _root = "."
  }

  _args = [
    "--source-root",
    rebase_path(_root),
    "--directory",
    rebase_path(invoker.directory),
  ]

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

  _public_deps = []
  if (defined(invoker.public_deps)) {
    _public_deps += invoker.public_deps
  }

  if (defined(invoker.path_data_keys)) {
    generated_file("$target_name._path_list") {
      data_keys = invoker.path_data_keys
      rebase = root_build_dir
      outputs = [ "$target_gen_dir/$target_name.txt" ]
      deps = _deps + _public_deps

      assert(deps != [],
             "'path_data_keys' requires at least one dependency in 'deps'")
    }

    _deps += [ ":$target_name._path_list" ]
    _args += [ "--path-file" ] +
             rebase_path(get_target_outputs(":$target_name._path_list"))
  }

  pw_python_action(target_name) {
    script = "$dir_pw_build/py/pw_build/mirror_tree.py"
    args = _args

    outputs = []

    if (defined(invoker.sources)) {
      args += rebase_path(invoker.sources)

      foreach(path, rebase_path(invoker.sources, _root)) {
        outputs += [ "${invoker.directory}/$path" ]
      }
    }

    # If path_data_keys is used, the outputs may be unknown.
    if (outputs == []) {
      stamp = true
    }

    deps = _deps
    public_deps = _public_deps

    _ignore_args = [
      "script",
      "args",
      "outputs",
      "directory",
      "deps",
      "public_deps",
    ]
    forward_variables_from(invoker, "*", _ignore_args)
  }
}
