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

import("$dir_pw_build/python_action.gni")

# Takes a set of input sources and zips them up to a .zip output.
#
# Users can either pass in specific input files or entire directories.
# This target type also supports renaming files as well as specifing
# desired zip destination directories for each input source.
#
# Args:
#   deps: Dependencies for this target.
#
#   inputs: List of input files following the custom input formatting
#      convention. See below for syntax.
#
#   dirs: List of directories to be completely zipped up following the same
#     input formatting convention. See below for syntax.
#
#   output: Filename of artifact .zip file produced by script's execution.
#
# Each input follows the following convention:
#   /source_path > /zip_destination/
#
# All directories are expected to be end with a '/'. Inputs must always specify
# both a source and a destination. Destinations are expected to have a leading
# '/' which stands for the root of the archive.
#
# Example:
#   Let's say we have the following structure for a //source/ directory:
#
#     source/
#     ├── file1.txt
#     ├── file2.txt
#     ├── file3.txt
#     └── some_dir/
#         ├── file4.txt
#         └── some_other_dir/
#             └── file5.txt
#
#   And we create the following build target:
#
#     import("$dir_pw_build/zip.gni")
#
#     pw_zip("target_name") {
#       inputs = [
#         "//source/file1.txt > /",             # Copied to the zip root dir.
#         "//source/file2.txt > /renamed.txt",  # File renamed.
#         "//source/file3.txt > /bar/",         # File moved to the /bar/ dir.
#       ]
#
#       dirs = [
#         "//source/some_dir/ > /bar/some_dir/",  # Whole /some_dir/ contents
#                                                 # copied as /bar/some_dir/.
#       ]
#
#       # Note on output: if the specific output directory isn't defined
#       # (such as output = "zoo.zip") then the .zip will output to the
#       # same directory as the BUILD.gn file that called the target.
#       output = "//$target_out_dir/foo.zip",  # Where the foo.zip will end up
#     }
#
#   This will result in a .zip file called foo.zip stored in //$target_out_dir
#   with the following structure:
#
#     foo.zip
#     ├── bar/
#     │   ├── file3.txt
#     │   └── some_dir/
#     │       ├── file4.txt
#     │       └── some_other_dir/
#     │           └── file5.txt
#     ├── file1.txt
#     └── renamed.txt
#
template("pw_zip") {
  _delimiter = ">"
  pw_python_action(target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                           ])
    script = "$dir_pw_build/py/pw_build/zip.py"

    args = [ "--out_filename" ]
    args += [ rebase_path(invoker.output, root_build_dir) ]

    inputs = []
    args += [ "--input_list" ]
    if (defined(invoker.inputs)) {
      foreach(input, invoker.inputs) {
        # Adding spaces around our delimiter is great for readability,
        # but not great for the string split: remove the spacing.
        input = string_replace(input, " $_delimiter", _delimiter)
        input = string_replace(input, "$_delimiter ", _delimiter)

        input_list = []
        input_list = string_split(input, _delimiter)
        inputs += [ input_list[0] ]
        input_list[0] = rebase_path(input_list[0], root_build_dir)

        # Pass rebased and delimited path to script.
        args += [ string_join(_delimiter, input_list) ]
      }
    }

    if (defined(invoker.dirs)) {
      foreach(dir, invoker.dirs) {
        # Adding spaces around our delimiter is great for readability,
        # but not great for the string split: remove the spacing.
        dir = string_replace(dir, " $_delimiter", _delimiter)
        dir = string_replace(dir, "$_delimiter ", _delimiter)

        args += [ rebase_path(dir, root_build_dir) ]
      }
    }

    outputs = [ invoker.output ]
  }
}
