# Copyright 2021 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/components/fuchsia_component.gni")
import("//build/dist/distribution_manifest.gni")
import("//build/drivers/driver_manifest.gni")
import("//tools/cmc/build/cmc.gni")

# Defines a Fuchsia driver component.
# A driver component is a normal component that launches a driver.
# For more information on components see:
# https://fuchsia.dev/fuchsia-src/development/components/build
#
# At the moment this template will generate the Component Manifest
# at build time. If you'd like to write your own Component Manifest,
# simply use the fuchsia_component build template.
#
# The component manifest is automatically generated that points to the
# correct driver library and bind file. If 'deps' includes more than
# one driver library or more than one bind file, this will cause a build-time
# error.
#
# Parameters
#
#   manifest (optional)
#     The component manifest. Either this or `cm_label` must be specified.
#     Type: path
#   cm_label (optional)
#     A `fuchsia_component_manifest` target label. Either this or `manifest` must be specified.
#     Type: GN label, e.g. `:my_manifest`
#   is_v1_driver (optional)
#     If this is true then the driver is a v1 driver and it will be placed in a
#     compatibility shim when running in a DFv2 environment.
#     Type: bool
#     Default: true
#   fallback (optional)
#     If this is true then the driver is a fallback driver.
#     Type: bool
#     Default: false
#   colocate
#     If this is true, the driver will be put in the same DriverHost as its parent if possible. This
#     is advisory, and the driver manager may still put the driver in a separate DriverHost, for
#     instance if the parent device has MUST_ISOLATE set. In DFv1, a driver is always colocated if
#     the parent device is a composite; isolation may still be enforced by setting MUST_ISOLATE on
#     the primary fragment of the composite.
#     Type: boolean
#   uses_profiles (optional)
#     If this is true, the driver will be given access to the profile provider service.
#     Type: bool
#     Default: false
#   uses_sysmem (optional)
#     If this is true, the driver will be given access to sysmem.
#     Type: bool
#     Default: false
#   uses_boot_args (optional)
#     If this is true, the driver will be given access to boot arguments service.
#     Type: bool
#     Default: false
#   default_dispatcher_opts (optional)
#     If this is set, then the default dispatcher for the driver will be
#     created with these options.
#     Type: array of strings
#     Default: []
#   default_dispatcher_scheduler_role (optional)
#     If this is set, then the default dispatcher for the driver will be
#     created with this scheduler role.
#     Type: string
#     Default: ""
#   info (mandatory for //src and //zircon)
#     Name of the file containing the driver information file.
#     Type: file
#   device_categories (optional)
#      The device categories this driver is for. (The values must be from FHCP.json)
#      This is a requirement for certification of the driver.
#      Type: array of scopes
#   applicable_licenses
#   deps
#   testonly
#   visibility
template("fuchsia_driver_component") {
  if (current_toolchain == default_toolchain) {
    assert(!(defined(invoker.manifest) && defined(invoker.cm_label)),
           "`manifest` and `cm_label` cannot be defined simultaneously")
    assert(defined(invoker.manifest) || defined(invoker.cm_label),
           "`manifest` or `cm_label` must be defined")
    is_v1_driver = true
    if (defined(invoker.is_v1_driver)) {
      is_v1_driver = invoker.is_v1_driver
    }

    driver_path =
        get_path_info(get_path_info(invoker.target_name, "abspath"), "dir")
    splitted_path = string_split(driver_path, "/")
    base_folder = splitted_path[2]  # after removing "//"
    create_driver_doc = false
    if (base_folder == "src" || base_folder == "zircon") {
      # Public drivers (defined as drivers in //src and //zircon) must provide an 'info' field with
      # a driver information file.
      assert(defined(invoker.info), "Must include driver info")
      create_driver_doc = true
    } else {
      # Ignore info assignment if present, e.g. from //tools templates.
      if (defined(invoker.info)) {
        not_needed(invoker, [ "info" ])
      }
    }

    if (create_driver_doc) {
      doc_output = "${target_gen_dir}/${target_name}-doc.json"
      doc_target = "${target_name}-driver-info"

      name = invoker.target_name
      if (defined(invoker.component_name)) {
        name = invoker.component_name
      }
      doc_input = invoker.info
      action(doc_target) {
        visibility = [ ":*" ]
        forward_variables_from(invoker,
                               [
                                 "applicable_licenses",
                                 "testonly",
                               ])
        script = "//build/drivers/create_driver_doc.py"
        inputs = [
          driver_path,
          doc_input,
        ]
        outputs = [ "${doc_output}" ]
        args = [
          "--name",
          name,
          "--driver_path",
          driver_path,
          "--doc_input",
          rebase_path(doc_input, root_build_dir),
          "--doc_output",
          rebase_path(outputs[0], root_build_dir),
        ]
      }
    }

    fuchsia_component(target_name) {
      # TODO(https://fxbug.dev/42161384): Remove check_includes = false.
      if (!defined(invoker.cm_label)) {
        check_includes = false
      }
      forward_variables_from(invoker,
                             [
                               "applicable_licenses",
                               "cm_label",
                               "component_name",
                               "deps",
                               "manifest",
                               "manifest_deps",
                               "restricted_features",
                               "testonly",
                               "visibility",
                             ])
      if (!defined(deps)) {
        deps = []
      }
      if (create_driver_doc) {
        deps += [ ":${doc_target}" ]
        not_needed(invoker, [ ":${doc_target}" ])
      }
      if (is_v1_driver) {
        deps += [ "//src/devices/misc/drivers/compat:driver" ]
      }
      metadata = {
        # Used by the assert_driver_components template.
        driver_component_barrier = []

        if (create_driver_doc) {
          # Used by the create_all_drivers_doc template.
          fuchsia_driver_doc_file = [ doc_output ]
        }
      }
    }
  } else {
    group(target_name) {
      forward_variables_from(invoker,
                             [
                               "applicable_licenses",
                               "testonly",
                             ])
      deps = [ ":$target_name($default_toolchain)" ]
    }
    not_needed(invoker, "*")
  }
}
