# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# Generate a manifest file as used by `zbi`, `minfs`, etc.
#
# This produces a manifest file in the `TARGET=SOURCE` format where
# `SOURCE` is a host file path relative to $root_build_dir and `TARGET`
# is a path relative to some filesystem image or directory subtree being
# populated.  The manifest is populated from optional fixed entries given
# in $manifest (see below) and from the dependency graph of this target.
#
# resource() targets as well as executable() et al and any targets with
# an `install_path` parameter contribute metadata to populate manifest
# files that depend on those targets.  manifest_file() targets and other
# packaging steps act as dependency barriers to the manifest metadata
# collection, so if this target depends (directly or indirectly) on
# another manifest_file(), the dependencies of _that_ manifest_file()
# won't contribute entries to _this_ manifest (unless they are reached
# separately as dependencies of _this_ target by a dependency path not
# passing thruogh _that_ target).
#
# Parameters
#
#   data_deps
#     Optional: Has no effect on this target, but dependents will depend
#     on these targets.
#     Type: list(label)
#
#   deps
#     Optional: Dependencies examined for metadata.  Transitive dependencies
#     from here defining `metadata.manifest_lines` contribute to the manifest,
#     pruned at targets that set `metadata.manifest_barrier`.  Likewise,
#     `metadata.manifest_files` contributes manifests (like $sources).
#     Each manifest_file() target itself contributes that way, so another
#     manifest_file() in the deps will be folded into this one.
#     Type: list(label)
#
#   output_dir
#     Optional: Directory where the manifest file is written.
#     Type: dir
#     Default: target_gen_dir
#
#   output_extension
#     Optional: Extension added to $output_name.
#     Type: string
#     Default: "manifest"
#
#   output_name
#     Optional: Name of the manifest file written out.
#     Type: string
#     Default: target_name
#
#   manifest
#     Optional: Fixed entries for the manifest file.  These augment the
#     entries collected from `manifest_lines` metadata.  Each entry is
#     either a string that's a literal manifest entry line, or a scope
#     with $sources and $outputs like a resource() target.
#     Type: list(string or scope)
#
#   sources
#     Optional: Additional manifest files to be concatenated onto this one.
#     Type: list(file)
#
template("manifest_file") {
  forward_variables_from(invoker,
                         [
                           "output_dir",
                           "output_extension",
                           "output_name",
                         ])
  if (!defined(output_dir)) {
    output_dir = target_gen_dir
  }
  if (!defined(output_extension)) {
    output_extension = "manifest"
  }
  if (!defined(output_name)) {
    output_name = target_name
  }

  manifest_file = "$output_dir/$output_name"
  if (output_extension != "") {
    manifest_file += ".$output_extension"
  }

  manifest_target = target_name
  list_file = "$target_gen_dir/$target_name.list"
  raw_file = "$target_gen_dir/$target_name.raw.manifest"
  list_file_target = "_manifest_file.$target_name.list"
  raw_file_target = "_manifest_file.$target_name.raw"

  # An embedded manifest contributes to metadata.manifest_lines directly.
  manifest_entries = []
  manifest_inputs = []
  if (defined(invoker.manifest)) {
    foreach(entry, invoker.manifest) {
      if (entry == "$entry") {
        # It's a literal manifest entry string.
        # Note this doesn't express any dependency on its source file!
        manifest_entries += [ entry ]
      } else {
        # It's a manifest entry in the style of a copy() target.
        foreach(source, entry.sources) {
          manifest_inputs += [ source ]
          source_path = rebase_path(source, root_build_dir)
          foreach(target, process_file_template([ source ], entry.outputs)) {
            manifest_entries += [ "${target}=${source_path}" ]
          }
        }
      }
    }
  }

  # This target produces the raw manifest file from metadata and fixed entries.
  generated_file(raw_file_target) {
    visibility = [ ":$list_file_target" ]
    forward_variables_from(invoker,
                           [
                             "deps",
                             "testonly",
                           ])
    outputs = [
      raw_file,
    ]
    output_conversion = "list lines"
    data_keys = [ "manifest_lines" ]
    walk_keys = [ "manifest_barrier" ]
    metadata = {
      # This will be picked up by raw_file_target, below.
      manifest_files = rebase_path(outputs, root_build_dir)
      if (defined(invoker.sources)) {
        manifest_files += rebase_path(invoker.sources, root_build_dir)
      }

      # This will be picked up by this target's own collection.
      manifest_lines = manifest_entries
    }
  }

  # This target produces the list of manifest files to combine.
  # It always includes the raw file just produced and $sources,
  # but can also pick up more files from metadata.
  generated_file(list_file_target) {
    visibility = [ ":$manifest_target" ]
    forward_variables_from(invoker, [ "testonly" ])
    outputs = [
      list_file,
    ]
    output_conversion = "list lines"
    data_keys = [ "manifest_files" ]
    walk_keys = [ "manifest_barrier" ]
    deps = [
      ":$raw_file_target",
    ]
  }

  # This target produces the final manifest by combining all those files.
  # The metadata from the invoker and for other manifest_file() targets
  # goes here.  It shouldn't be seen by the generated_file() targets above.
  action(manifest_target) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "testonly",
                             "visibility",
                           ])

    script = "$zx/public/gn/manifest-cat.sh"
    sources = [
      list_file,
    ]
    outputs = [
      manifest_file,
    ]
    deps = [
      ":$list_file_target",
    ]
    inputs = manifest_inputs
    if (defined(invoker.sources)) {
      # These are listed in $list_file and will appear in the depfile.
      # Make sure they're built before the first run if necessary and let
      # GN enforce that they come from the deps.  This is the only reason
      # to include deps and not just data_deps in this action() target.
      # The deps are reached by $raw_file_target already.
      inputs += invoker.sources
      if (defined(invoker.deps)) {
        deps += invoker.deps
      }
    }
    depfile = "$manifest_file.d"
    args = rebase_path(sources + outputs + [ depfile ], root_build_dir)

    metadata = {
      images = []
      manifest_barrier = []
      manifest_files = []

      if (defined(invoker.metadata)) {
        # This lets the invoker add to `images` and `manifest_barrier`,
        # though our implicit contributions will always be there too.
        forward_variables_from(invoker.metadata, "*")
      }

      # For the //:images build_api_module().
      images += [
        {
          label = get_label_info(":$target_name", "label_with_toolchain")
          name = output_name
          path = rebase_path(manifest_file, root_build_dir)
          type = "manifest"
          cpu = current_cpu
          os = current_os
        },
      ]

      # Another manifest_file() depending on this one will fold it in,
      # just as this one folded in any `manifest_files` from its deps.
      # The `manifest_barrier` set here (above) prevents any dependents
      # from reaching dependencies we've already folded in.
      manifest_files += [ rebase_path(manifest_file, root_build_dir) ]
    }
  }
}
