# 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.

import("//build/package.gni")

# Define configuration data that can be aggregated into other packages. This is
# primarily used to aggregate configuration files into the config-data package
# that supplies the /config/data namespace.
#
#   for_pkg (required)
#     [string] The name of the package this is configuration for.
#
#   outputs (optional)
#     [list of one path] This must be a relative path (no leading `/`). It can use
#     placeholders based on $sources; see copy() and `gn help source_expansion`.
#     If not provided, the outputs will be named by processing the sources
#     with the {{source_file_part}} template. Applying this template to
#     "config/mycfg.config" produces "mycfg.config". If supplied the list must
#     contain exactly one path pattern.
#
#   sources (required)
#     [list of files] List of files in the source tree or build that become
#     $outputs. See copy() for details.
#
# See copy() for other parameters.
template("config_data") {
  group(target_name) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "deps",
                             "for_pkg",
                             "metadata",
                             "outputs",
                             "public_deps",
                             "sources",
                             "testonly",
                             "visibility",
                           ])

    if (!defined(outputs)) {
      outputs = [ "{{source_file_part}}" ]
    }

    assert(outputs != [] && outputs - [ outputs[0] ] == [],
           "Exactly one output pattern required.")

    metadata = {
      config_package_entries = []
      if (defined(invoker.metadata)) {
        forward_variables_from(invoker.metadata, "*")
      }
      foreach(source, sources) {
        foreach(target, process_file_template([ source ], outputs)) {
          config_package_entries += [ "data/" + for_pkg + "/" + target + "=" +
                                      rebase_path(source, root_build_dir) ]
        }
      }
    }
  }
}

# Produce a configuration package who's content are defined by all config_data
# targets in it's dependency chain.
#
# Parameters
#
#   deps (required)
#   public_deps (optional)
#   data_deps (optional)
#   testonly (optional)
#     Usual GN meanings.
template("config_package") {
  config_package_manifest = "${target_name}.config-package-extra.manifest"
  config_package_manifest_path = target_gen_dir + "/" + config_package_manifest
  validate_sysmgr_config_target_name = "${target_name}_validate_sysmgr_config"

  generated_file(config_package_manifest) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "data_deps",
                             "testonly",
                           ])

    # This contract is known to package.gni.
    data_keys = [ "config_package_entries" ]
    walk_keys = [ "config_package_barrier" ]
    outputs = [ config_package_manifest_path ]
  }

  action(validate_sysmgr_config_target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "data_deps",
                             "testonly",
                           ])
    deps += [ ":${config_package_manifest}" ]

    script = "//build/tools/validate_sysmgr_config.py"
    inputs = [ config_package_manifest_path ]

    depfile = "$target_out_dir/$target_name.d"
    stamp_file = "$target_out_dir/$target_name.script.stamp"
    outputs = [ stamp_file ]

    args = [
      rebase_path(config_package_manifest_path, root_build_dir),
      "--stamp",
      rebase_path(stamp_file, root_build_dir),
      "--depfile",
      rebase_path(depfile, root_build_dir),
    ]
  }

  package(target_name) {
    forward_variables_from(invoker,
                           [
                             "data_deps",
                             "deps",
                             "package_name",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])
    deps += [
      ":${config_package_manifest}",
      ":${validate_sysmgr_config_target_name}",
    ]

    extra = [ config_package_manifest_path ]
    metadata = {
      if (defined(invoker.metadata)) {
        forward_variables_from(invoker.metadata, "*")
      }
      config_package_barrier = []
    }
  }
}
