# 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`.
#     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.  **Note:**
#     This does not express any dependency on the $sources files;
#     they will be noted in a depfile for incremental builds, but
#     if they are created by the build the actions that create them
#     must also be in $deps and this is not enforced by GN.
#     Type: list(string or scope)
#
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
  file_target = "_manifest_file.$target_name.manifest"

  # An embedded manifest contributes to metadata.manifest_lines directly.
  entries = []
  if (defined(invoker.manifest)) {
    foreach(entry, invoker.manifest) {
      if (entry == "$entry") {
        # It's a literal manifest entry string.
        entries += [ entry ]
      } else {
        # It's a manifest entry in the style of a copy() target.
        foreach(source, entry.sources) {
          source_path = rebase_path(source, root_build_dir)
          foreach(target, process_file_template([ source ], entry.outputs)) {
            entries += [ "${target}=${source_path}" ]
          }
        }
      }
    }
  }

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

  if (entries != []) {
    # generated_file() doesn't collect its own metadata, so we need an
    # extra group() here just to contain the explicit manifest metadata.
    metadata_target = "_manifest_file.$target_name.metadata"
    manifest_deps += [ ":$metadata_target" ]
    group(metadata_target) {
      visibility = [ ":$file_target" ]
      metadata = {
        manifest_lines = entries
      }
    }
  }

  # This target produces the actual manifest file.
  generated_file(file_target) {
    visibility = [ ":$manifest_target" ]
    forward_variables_from(invoker, [ "testonly" ])
    deps = manifest_deps
    outputs = [
      manifest_file,
    ]
    output_conversion = "list lines"
    data_keys = [ "manifest_lines" ]
    walk_keys = [ "manifest_barrier" ]
    metadata = {
      manifest_barrier = []
    }
  }

  # Putting $data_deps into the generated_file() would mean those all get
  # visited for the metadata collection, which is not right.  So we always
  # have a group() target wrapping the generated_file().  For clarity we
  # pass the invoker's metadata on here instead of inside the
  # generated_file() though it doesn't really matter for collections.
  group(manifest_target) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "testonly",
                             "visibility",
                           ])
    deps = [
      ":$file_target",
    ]
    metadata = {
      images = []

      if (defined(invoker.metadata)) {
        # This lets the invoker add to `images`, 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
        },
      ]
    }
  }
}
