# 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("cmc.gni")

# Defines a Fuchsia component.
# See: https://fuchsia.dev/fuchsia-src/glossary#component
#
# A component is defined by a component manifest.
# A component is a unit of executable software on Fuchsia. When the componet is executed, there are usually many files
# needed at runtime, such as the executable itself, shared libraries, and possibly other data resources. These files are
# specified by using the GN concept of "data_deps".
#
# Components are distributed using a fuchsia package which can contain multiple components. The component manifest and
# the runtime dependencies of the component are packaged using the fuchsia_package rule.
#
# By default, the runtime depenencies of the component are included in the package using relative paths calcualted from
# the "closest" root of: $root_gen_dir, $root_dir, $out_dir. If a specific path is desired in the package, the "resources" parameter can
# be used to explicitly specify the path of a specific file.
#
# A component is launched by a URL which identifies the package and the component manifest.
# See: https://fuchsia.dev/fuchsia-src/glossary#component_url
#
# Example
#
# ```
#   fuchsia_component("my_component") {
#      manifest = "meta/component-manifest.cmx"
#      resources = [
#        path = "testdata/use_case1.json"
#        dest = "data/testdata/use_case1.json"
#      ]
#      data_deps = [ ":hello_world_executable"]
#   }
# ```
#
# Parameters
#
#   manifest
#     The source manifest file for this component. This can be either v1 (.cmx)
#     or v2 (.cml) manifest.
#
#     Type: string (filepath)
#
#   data_deps
#     The labels of targets that generate the files needed at runtime by the component.
#     At minimum, this should include the label of the binary to include in the component.
#
#     Type: list of labels
#
#   manifest_output_name [optional]
#     The name of the manifest file contained in the distribution that this
#     component is included in. The output name should have no extension or
#     prefixes. The resulting filename will have the extension correct for the
#     manifest version. For example, if `manifest` is "foo.cmx"
#     and `manifest_output_name` is "bar", the filename will be "bar.cmx". If
#     `manifest` is "foo.cml" (a v2 manifest), the filename will be "bar.cm".
#
#     Type: string
#     Default: The base file name of `manifest` without an extension.
#
#   resources [optional]
#     Lists additional files to include for runtime access by the component.
#     Defines the resources in a package containing this component. A resource
#     is a data file that may be produced by the build system, checked in to a
#     source repository, or produced by another system that runs before the
#     build. Resources are placed in the `data/` directory of the assembled
#     package.

#     Type: list of scopes.  Entries in a scope in the resources list:
#       path (required)
#             Location of resource in source or build directory. If the
#             resource is checked in, this will typically be specified
#             as a path relative to the BUILD.gn file containing the
#             `package()` target. If the resource is generated, this will
#             typically be specified relative to `$target_gen_dir`.
#
#        dest (required) string (path) Location the resource will be placed within `data/`.
#
#   Standard parameters:
#     deps
#     testonly
#     visibility
#
#   Metadata
#     contents - list of scopes describing files for this component. This metadata is consumed by
#       The fuchsia_package rule, which describes the entries used.
#       Entries in scope:
#         type: the usage type of the element, manifest or resource.
#                Each type can have specific properties included in the scope.
#         source [type == manifest || resource] The source file to include in
#           the package for this component. In the case of v2 components,
#           this is the compiled manifest.
#         output_name [type == manifest] The basename of the manifest as it should appear in the package.
#         manifest_version [type == manifest]
#       dest: [type == resource] The package relative path of the resource.

template("fuchsia_component") {
  forward_variables_from(invoker,
                         [
                           "manifest",
                           "manifest_output_name",
                         ])

  assert(defined(manifest), "manifest file required for this component")

  if (!defined(manifest_output_name)) {
    manifest_output_name = get_path_info(manifest, "name")
  }

  # Determine manifest_version from the `manifest` file extension.
  _manifest_extension = get_path_info(manifest, "extension")
  assert(_manifest_extension == "cmx" || _manifest_extension == "cml",
         "Manifest file extension must be .cmx or .cml")
  if (_manifest_extension == "cmx") {
    _manifest_version = "v1"
  } else if (_manifest_extension == "cml") {
    _manifest_version = "v2"
  }

  # The component manifest validated using cmx_validation for v1,
  # or cmc_compile for v2.
  _cm_validation_target =
      "${target_name}_validate_" + get_path_info(manifest, "file")

  if (_manifest_version == "v1") {
    cmc_validate(_cm_validation_target) {
      forward_variables_from(invoker,
                             [
                               "deps",
                               "testonly",
                             ])
      manifest = manifest
    }

    _manifest_source = manifest
  } else if (_manifest_version == "v2") {
    cmc_compile(_cm_validation_target) {
      forward_variables_from(invoker,
                             [
                               "deps",
                               "testonly",
                             ])
      manifest = rebase_path(manifest)
    }

    _compiled_manifest_outputs = get_target_outputs(":$_cm_validation_target")
    _manifest_source = _compiled_manifest_outputs[0]
  }

  group(target_name) {
    forward_variables_from(invoker,
                           [
                             "data",
                             "deps",
                             "data_deps",
                             "resources",
                             "testonly",
                             "visibility",
                           ])

    # Data is used for adding files as runtime dependencies. Files used as
    # sources in the resources parameter are added as data to make sure
    # non-generated files listed are captured as dependencies.
    if (!defined(data)) {
      data = []
    }

    if (!defined(resources)) {
      resources = []
    }

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

    # Create the component metadata entries. These capture the manifest information and
    # the resources parameter contents.  The metadata is intended for the fuchsia_package rule.
    component_contents = [
      {
        type = "manifest"
        source = rebase_path(_manifest_source)
        output_name = manifest_output_name
        manifest_version = _manifest_version
      },
    ]
    foreach(resource, resources) {
      data += [ resource.path ]
      component_contents += [
        {
          type = "resource"
          source = rebase_path(resource.path)
          dest = resource.dest
        },
      ]
    }

    # The contents of the component are enumerated in the
    # metadata.
    metadata = {
      contents = [ component_contents ]
    }
  }
}
