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

declare_args() {
  # If a package is referenced in monolith and in preinstall, monolith takes
  # priority, and the package will be added to OTA images as part of the
  # verified boot set of static packages.

  # These arguments should be set by the product definition gni file.

  # a list of packages included in OTA images, base system images, and the
  # distribution repository.
  monolith = []

  # a list of packages pre-installed on the system (also added to the
  # distribution repository)
  preinstall = []

  # a list of packages only added to the distribution repository)
  available = []

  # These arguments should be set by the board definition gni file.

  # A list of packages included in the monolith from the board definition.
  # This list is appended with the list from the product definition and any
  # additional specified packages
  board_packages = []

  # List of packages (a GN list of strings).
  # This list of packages is currently added to the set of "monolith" packages,
  # see `products` for more information; in the future, these packages will be
  # added to the "preinstall".
  # If unset, layer will be guessed using //.jiri_manifest and
  # //{layer}/products/default.gni will be used.
  fuchsia_packages = []

  # Legacy product definitions.
  fuchsia_products = []
}

monolith += board_packages
monolith += fuchsia_packages

# Print a warning message if the legacy fuchsia_products field is set.
# Only print in the default toolchain so the warning only shows up once.
if (fuchsia_products != [] && current_toolchain == default_toolchain) {
  print("WARNING! Deprecated fuchsia product specification detected")
  print("Please re-run 'fx set' to update your build configuration")
  print(
      "See https://fuchsia.googlesource.com/fuchsia/+/master/docs/development/build/")
  print("or BLD-240 for more details")
}

if (monolith == [] && preinstall == [] && available == [] &&
    fuchsia_packages == []) {
  _jiri_manifest = "//.jiri_manifest"
  _layers = exec_script("//build/gn/guess_layer.py",
                        [ rebase_path(_jiri_manifest) ],
                        "list lines",
                        [ _jiri_manifest ])
  foreach(layer, _layers) {
    import("//$layer/products/default.gni")
  }
}

# Resolve all the `fuchsia_products` JSON files and their dependencies
# into lists of GN labels:
# monolith - package labels for base system and verified boot image
# preinstall - package labels for preinstall, but not OTA
# available - package labels for the install and update repository
# host_tests - labels for host tests
# data_deps - labels for host tools and non-package build targets
_preprocessed_products = exec_script("preprocess_products.py",
                                     [
                                       # A list of strings in GN syntax is
                                       # valid JSON too.
                                       "--monolith=$monolith",
                                       "--preinstall=$preinstall",
                                       "--available=$available",
                                       "--legacy-products=$fuchsia_products",
                                     ],
                                     "json")

# Tell GN that the files preprocess_products.py ran are inputs to the
# generation step, by declaring them as file inputs to a (silly) exec_script
# invocation.
exec_script("/bin/sh",
            [
              "-c",
              ":",
            ],
            "",
            _preprocessed_products.files_read)

monolith_packages = []
foreach(pkg, _preprocessed_products.monolith) {
  monolith_packages += [ get_label_info(pkg, "label_no_toolchain") ]
}
preinstall_packages = []
foreach(pkg, _preprocessed_products.preinstall) {
  preinstall_packages += [ get_label_info(pkg, "label_no_toolchain") ]
}
available_packages = []
foreach(pkg, _preprocessed_products.available) {
  available_packages += [ get_label_info(pkg, "label_no_toolchain") ]
}

# Every extra GN target the package JSON requests be built on the side.
# This is for things like install_host_tools() targets whose output should
# be on hand for a developer to use in conjuction with a Fuchsia package.
package_data_deps = []
foreach(pkg, _preprocessed_products.data_deps) {
  package_data_deps += [ get_label_info(pkg, "label_no_toolchain") ]
}

# Labels of test() targets to be copied into $root_build_dir/host_tests.
package_host_tests = []
foreach(label, _preprocessed_products.host_tests) {
  package_host_tests += [ get_label_info(label, "label_no_toolchain") ]
}
