# Copyright 2022 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/group_with_inputs.gni")

# Create a product assembly config file from the lists of packages and config
# passed into the template.
#
# This template specifically converts lists of labels for fuchsia_package() and
# prebuilt_package() into the lists of output paths needed.  This keeps the
# contract about where those two templates place the package manifest internal
# to fuchsia.git.
#
# As outputs, this creates:
#
#  outputs = [
#       "${target_out_dir}/${target_name}/product_assembly_config.json"
#  ]
#
#
# Arguments:
#
#   Product-specified Package Sets:
#    These are optional lists of targets that produce Fuchsia Packages.  These
#    are NOT walked for metadata, but must be the exact desired package-creating
#    targets.
#
#   base_packages [optional]
#     [list, GN targets] A list of GN targets that are the specific targets for
#     the product-provided packages to place into the base set.
#
#   cache_packages [optional]
#     [list, GN targets] A list of GN targets that are the specific targets for
#     the product-provided packages to place into the cache set.
#
#   platform [optional]
#   [scope] This is the platform configuration scope
#
#   product [optional]
#   [scope] This is the product configuration scope
#
# GN Usual:
#   testonly
#   visibility
template("product_assembly_configuration") {
  labels = {
    # So it can be reused.
    target_name = target_name

    assembly_config = "${target_name}.product_assembly_config.json"

    # This is a publicly visible, test-only target, that allows the assembly
    # config to be used without needing the deps used create it.
    assembly_config_for_validation =
        "${target_name}.product_assembly_config.json.for_validation"

    base_package_set = "${target_name}.base_packages"
    cache_package_set = "${target_name}.cache_packages"

    # Base packages specified by the invoker, used to create the list of
    # manifests and as the deps for the package set targets.
    base_package_labels = []
    if (defined(invoker.base_packages)) {
      base_package_labels += invoker.base_packages
    }

    # Cache packages specified by the invoker, used to create the list of
    # manifests and as the deps for the package set targets.
    cache_package_labels = []
    if (defined(invoker.cache_packages)) {
      cache_package_labels += invoker.cache_packages
    }
  }

  files = {
    outdir = "$target_out_dir/$target_name"
    assembly_config_file = "$outdir/product_assembly_config.json"

    # Compute the paths for the package manifests (as files).  This is
    # closely coupled with how fuchsia_package() and prebuilt_package() both
    # create a package manifest from their label.

    base_package_manifests = []
    foreach(package_target, labels.base_package_labels) {
      _package_out_dir = get_label_info(package_target, "target_out_dir")
      _package_name = get_label_info(package_target, "name")
      base_package_manifests +=
          [ "${_package_out_dir}/${_package_name}/package_manifest.json" ]
    }

    cache_package_manifests = []
    foreach(package_target, labels.cache_package_labels) {
      _package_out_dir = get_label_info(package_target, "target_out_dir")
      _package_name = get_label_info(package_target, "name")
      cache_package_manifests +=
          [ "${_package_out_dir}/${_package_name}/package_manifest.json" ]
    }
  }

  _assembly_config = {
    # Create the platform configuration section from the caller's argument
    platform = {
      if (defined(invoker.platform)) {
        forward_variables_from(invoker.platform, "*")
      }
      assert(defined(build_type), "The platform build-type must be specified.")
    }

    # Create the product configuration section from the caller's arguments.
    product = {
      if (defined(invoker.product)) {
        forward_variables_from(invoker.product, "*")
      }

      # Create the packages.base and package.cache sets if they weren't passed
      # in from the invoker.
      if (!defined(packages)) {
        packages = {
        }
      }
      if (!defined(packages.base)) {
        packages.base = []
      }
      if (!defined(packages.cache)) {
        packages.cache = []
      }

      foreach(manifest_path, files.base_package_manifests) {
        packages.base += [
          {
            manifest = rebase_path(manifest_path, root_build_dir)
          },
        ]
      }
      foreach(manifest_path, files.cache_package_manifests) {
        packages.cache += [
          {
            manifest = rebase_path(manifest_path, root_build_dir)
          },
        ]
      }
    }
  }

  # Generate the Product Assembly configuration file itself.
  #
  # This does _not_ have deps on any of the passed in targets, which is why it
  # restricts it's visibility to the target that does dep on them.
  #
  generated_file(labels.assembly_config) {
    forward_variables_from(invoker, [ "testonly" ])
    visibility = [
      ":${labels.assembly_config_for_validation}",
      ":${labels.target_name}",
    ]
    outputs = [ files.assembly_config_file ]
    output_conversion = "json"
    contents = _assembly_config
  }

  # These are used to detect if the deps don't correspond to a set of input
  # files (the deps can be larger than the set of files, but not the other way
  # around).  Since we're computing the manifest paths from the labels, if the
  # label to something other than a package is added, we'll compute a manifest
  # path that doesn't exist.  This catches it here, instead of inside a build
  # action which can't explain why it can't find a file.

  # Create a target for the base packages, so they appear in the dep graph
  # as distinct from the cache packages, and validate that they produce all of
  # the manifests whose paths were computed from the labels.
  group_with_inputs(labels.base_package_set) {
    inputs = files.base_package_manifests
    deps = labels.base_package_labels
  }

  # Create a target for the cache packages, so they appear in the dep graph
  # as distinct from the cache packages, and validate that they produce all of
  # the manifests whose paths were computed from the labels.
  group_with_inputs(labels.cache_package_set) {
    inputs = files.cache_package_manifests
    deps = labels.cache_package_labels
  }

  group(labels.target_name) {
    forward_variables_from(invoker,
                           [
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                           ])
    if (!defined(public_deps)) {
      public_deps = []
    }
    public_deps += [ ":${labels.assembly_config}" ]

    if (!defined(deps)) {
      deps = []
    }
    deps += [
      ":${labels.base_package_set}",
      ":${labels.cache_package_set}",
    ]
  }

  # A testonly group with no visibilty restrictions, that allows the use of the
  # generated product assembly config file in validation actions that don't
  # require the existence of the packages and binaries that it points to.
  group(labels.assembly_config_for_validation) {
    testonly = true
    public_deps = [ ":${labels.assembly_config}" ]
  }
}
