# 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_includes (optional)
#     Check against expect_includes() in deps.
#     Warning: Do not disable this unless there is a good, documented reason.
#     Type: boolean
#     Default: true
#
#   check_references (optional)
#     Check component manifest references (e.g. "program.binary") against
#     package manifest.
#     Type: boolean
#     Default: true
#
#   restricted_features (optional)
#     The set of restricted CML features to allow. Only applicable to v2 components.
#     The set of features is allowlisted here: //tools/cmc/build/restricted_features/BUILD.gn
#     where each feature name is represented by a group of the same name.
#     Type: list of strings
#     Default: []
#
#   experimental_force_runner (optional)
#     Set the --experimental-force-runner flag to the given value.
#     This flag is experimental and may be removed without warning.
#     Type: string
#
#   deps
#   testonly
#   visibility
template("fuchsia_component") {
  if (current_toolchain == default_toolchain) {
    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",
                               "restricted_features",
                               "check_includes",
                               "testonly",
                               "visibility",
                               "experimental_force_runner",
                             ])

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

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

        test_component_manifest_program_barrier = []
        test_component_manifest_barrier = []

        # Don't collect expected includes via transitive deps of components
        expect_includes_barrier = []
      }
    }

    # 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",
                               ])
        if (!defined(deps)) {
          deps = []
        }
        visibility = [ ":*" ]
        component_manifest = invoker.manifest
        label = get_label_info(":$target_name", "label_with_toolchain")
      }
    }
  } else {
    group(target_name) {
      forward_variables_from(invoker, [ "testonly" ])
      deps = [ ":$target_name($default_toolchain)" ]
    }
    not_needed(invoker, "*")
  }
}
