# Copyright 2020 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/dist/resource.gni")
import("//tools/cmc/build/cmc.gni")
import("//tools/cmc/build/cml.gni")
import("//tools/cmc/build/cmx.gni")

# Defines a Fuchsia component.
# See: https://fuchsia.dev/fuchsia-src/development/components/build
#
# A component is defined by a component manifest.
# Component manifests typically reference files in the package that they are
# distributed in. Therefore a component can also have dependencies on
# `resource()`, such that any package that depends on the component # will
# also include that resource.
#
# A component is launched by a URL.
# See: https://fuchsia.dev/fuchsia-src/glossary#component_url
#
# A component's URL is a function of the name of a package that includes it,
# and the path within that package to the component's manifest. For instance if
# you defined the following:
# ```
# executable("my_program") {
#   ...
# }
#
# fuchsia_component("my-component") {
#   manifest = "manifest.cml"
#   deps = [ ":my_program" ]
# }
#
# fuchsia_package("my-package") {
#   deps = [ ":my-component" ]
# }
# ```
# The component above will have the following launch URL:
# `fuchsia-pkg://fuchsia.com/my-package#meta/my-component.cm`
#
# Since the component depends on the executable target, the binary produced by
# the executable will be packaged with the manifest. Therefore the manifest
# author can reference the path `bin/my_program`.
#
# Components may depend on any number of `resource()` targets to ensure that
# any `fuchsia_package()` that includes them will include the same resources.
#
# ```
# resource("my_file") {
#   sources = [ "my_file.txt" ]
#   outputs = [ "data/{{source_file_part}}" ]
# }
#
# fuchsia_component("my-component") {
#   deps = [ ":my_file" ]
#   ...
# }
# ```
#
# The component defined above will be able to read my_file.txt under the path
# "/pkg/data/my_file.txt" in its sandbox.
#
# Parameters
#
#   manifest (required)
#     The component manifest.
#     Type: path
#
#   component_name (optional)
#     The name of the component.
#     Type: string
#     Default: target_name
#
#   check_references (optional)
#     Check component manifest references (e.g. "program.binary") against
#     package manifest.
#     Type: boolean
#     Default: true
#
#   unstable_features (optional)
#     The set of unstable CML features to allow. Only applicable to v2 components.
#     The set of features is allowlisted here: //tools/cmc/build/unstable_features/BUILD.gn
#     where each feature name is represented by a group of the same name.
#     Type: list of strings
#     Default: []
#
#   deps
#   testonly
#   visibility
template("fuchsia_component") {
  assert(
      defined(invoker.manifest),
      "A `manifest` argument was missing when calling fuchsia_component($target_name)")

  component_name = target_name
  if (defined(invoker.component_name)) {
    component_name = invoker.component_name
  }

  # Handle different manifest versions
  manifest_extension = get_path_info(invoker.manifest, "extension")
  if (manifest_extension == "cml") {
    manifest_processor = "cm"
    manifest_name = "$component_name.cm"
  } else if (manifest_extension == "cmx") {
    manifest_processor = "cmx"
    manifest_name = "$component_name.cmx"
  } else {
    assert(
        false,
        "Unknown manifest format for \"${invoker.manifest}\", must be \".cml\" or \".cmx\"")
  }

  manifest_resource_target = "${target_name}_manifest_resource"

  check_references = true
  if (defined(invoker.check_references)) {
    check_references = invoker.check_references
  }

  if (check_references) {
    validate_target = "${target_name}_cmc_validate_references"
  }

  # Process the manifest
  target(manifest_processor, target_name) {
    output_name = "$manifest_extension/$target_name/$manifest_name"
    forward_variables_from(invoker,
                           [
                             "deps",
                             "manifest",
                             "unstable_features",
                             "testonly",
                             "visibility",
                           ])

    if (!defined(deps)) {
      deps = []
    }
    deps += [ ":$manifest_resource_target" ]
    if (manifest_extension == "cmx") {
      deps += [ "//build/components/cmx:cmx_allowlist" ]
    }
    if (check_references) {
      deps += [ ":$validate_target" ]
    }
  }

  # Add the manifest
  resource(manifest_resource_target) {
    sources = get_target_outputs(":${invoker.target_name}")
    outputs = [ "meta/$manifest_name" ]
    visibility = [ ":*" ]
  }

  if (check_references) {
    # Validate the manifest against packaged files
    cmc_validate_references(validate_target) {
      forward_variables_from(invoker,
                             [
                               "deps",
                               "testonly",
                             ])
      visibility = [ ":*" ]
      component_manifest = invoker.manifest
      label = get_label_info(":$target_name", "label_with_toolchain")
    }
  }
}
