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

declare_args() {
  # WARNING: This is a TEMPORARY workaround to allow developers to skip the
  # sysmgr config validation perfomed below. Allowing config conflicts will
  # allow you to build but cause non-determistic behavior in sysmgr since
  # sysmgr may pick any of the conflicting configs to use at runtime
  #
  # This will be removed shortly and should only be used locally by developers
  # either through 'fx set' or in 'args.gn', never checked into a product
  # config file.
  #
  # TODO(fxb/39576): Remove this when landing the runtime conflict check in sysmgr
  dangerous_allow_sysmgr_config_conflicts = false
}

# 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
  if (!dangerous_allow_sysmgr_config_conflicts) {
    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 ]
  }

  if (!dangerous_allow_sysmgr_config_conflicts) {
    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}" ]
    if (!dangerous_allow_sysmgr_config_conflicts) {
      deps += [ ":${validate_sysmgr_config_target_name}" ]
    }

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