# 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/components.gni")
import("//build/dist/distribution_manifest.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",
                             "for_pkg",
                             "outputs",
                             "public_deps",
                             "sources",
                             "testonly",
                             "visibility",
                           ])

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

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

    if (defined(invoker.for_pkg)) {
      if (string_replace(target_out_dir, "vendor/google", "") !=
          target_out_dir) {
        import("//vendor/google/build/config_data_for_pkg_allowlist.gni")
      } else {
        import("//build/config_data_for_pkg_allowlist.gni")
      }
      assert(config_data_for_pkg_allowlist == [] ||
                 config_data_for_pkg_allowlist + [ invoker.for_pkg ] -
                     [ invoker.for_pkg ] != config_data_for_pkg_allowlist,
             "${invoker.for_pkg} is not an allowed value for for_pkg")
    }

    metadata = {
      if (defined(invoker.metadata)) {
        forward_variables_from(invoker.metadata, "*")
      }
      config_package_entries = []
      foreach(source, sources) {
        foreach(target, process_file_template([ source ], outputs)) {
          # Config files are usually small, so package them in meta/ so they're
          # archived together rather than spread across individual blobs.
          # See also: https://fxbug.dev/42112652
          config_package_entries += [
            {
              source = rebase_path(source, root_build_dir)
              destination = "meta/data/$for_pkg/$target"
              label = get_label_info(":$target_name", "label_with_toolchain")
            },
          ]
        }
      }
    }

    deps = [ "//build/validate:config_data_tag" ]
    if (defined(invoker.deps)) {
      deps += invoker.deps
    }

    deps += [ "//build:config_data_template_allowlist" ]
  }
}

# Produce a configuration package who's content are defined by all config_data
# targets in its dependency chain.
#
# Parameters
#
#   deps (required)
#   testonly (optional)
#   visibility (optional)
#     Usual GN meanings.
template("config_package") {
  config_package_entries_target = "${target_name}_config_package_entries"
  config_package_entries = "$target_out_dir/$config_package_entries_target"
  generated_file(config_package_entries_target) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "testonly",
                           ])
    visibility = [
      ":*",
      "//build/assembly/*",
    ]
    data_keys = [ "config_package_entries" ]
    walk_keys = [ "config_package_barrier" ]
    outputs = [ config_package_entries ]
    output_conversion = "json"
    metadata = {
      # Don't pick up resources from deps
      distribution_entries_barrier = []
    }
  }

  distribution_entries_target = "${target_name}_distribution_entries_file"
  distribution_entries_file(distribution_entries_target) {
    forward_variables_from(invoker, [ "testonly" ])
    visibility = [ ":*" ]
    deps = [ ":$config_package_entries_target" ]
    file = config_package_entries
  }

  fuchsia_package(target_name) {
    forward_variables_from(invoker,
                           [
                             "package_name",
                             "testonly",
                             "visibility",
                           ])
    deps = [ ":$distribution_entries_target" ]

    if (defined(golden_file_target)) {
      deps += [ ":$golden_file_target" ]
    }

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