# Copyright 2019 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

import("//build_overrides/pigweed.gni")

import("$dir_pw_build/error.gni")
import("$dir_pw_build/target_types.gni")

# Declare a facade.
#
# A Pigweed facade is an API layer that has a single implementation it must
# link against. Typically this will be done by pointing a build arg like
# `pw_[module]_BACKEND` at a backend implementation for that module.
#
# pw_facade creates two targets:
#
#   $target_name: The public-facing pw_source_set that provides the API and
#     implementation (backend). Users of the facade should depend on this.
#   $target_name.facade: A private source_set that provides ONLY the API. ONLY
#     backends should depend on this.
#
# If the target name matches the directory name (e.g. //foo:foo), a ":facade"
# alias of the facade target (e.g. //foo:facade) is also provided. This avoids
# the need to repeat the directory name, for consistency with the main target.
#
# The facade's headers are split out into the *.facade target to avoid circular
# dependencies. Here's a concrete example to illustrate why this is needed:
#
#   foo_BACKEND = "//foo:foo_backend_bar"
#
#   pw_facade("foo") {
#     backend = foo_BACKEND
#     public = [ "foo.h" ]
#     sources = [ "foo.cc" ]
#   }
#
#   pw_source_set("foo_backend_bar") {
#     deps = [ ":foo.facade" ]
#     sources = [ "bar.cc" ]
#   }
#
# This creates the following dependency graph:
#
#   foo.facade  <-.
#    ^             \
#    |              \
#    |               \
#   foo  ---------->  foo_backend_bar
#
# This allows foo_backend_bar to include "foo.h". If you tried to directly
# depend on `foo` from `foo_backend_bar`, you'd get a dependency cycle error in
# GN.
#
# Accepts the standard pw_source_set args with the following additions:
#
# Args:
#  backend: (required) The dependency that implements this facade (a GN
#    variable)
#  public: (required) The headers exposed by this facade. A facade acts as a
#    tool to break dependency cycles that come from the backend trying to
#    include headers from the facade itself. If the facade doesn't expose any
#    headers, it's basically the same as just depending directly on the build
#    arg that `backend` is set to.
#  require_link_deps: A list of build targets that must be included in
#    pw_build_LINK_DEPS if this facade is used. This mechanism is used to
#    avoid circular dependencies in low-level facades like pw_assert.
#
template("pw_facade") {
  assert(defined(invoker.backend),
         "pw_facade requires a reference to a backend variable for the facade")
  assert(defined(invoker.public),
         "If your facade does not explicitly expose an API that a backend " +
             "must depend on, you can just directly depend on the build arg " +
             "that the `backend` template argument would have been set to.")

  _facade_name = "$target_name.facade"

  if (get_path_info(get_label_info(":$target_name", "dir"), "name") ==
      get_label_info(":$target_name", "name")) {
    group("facade") {
      public_deps = [ ":$_facade_name" ]
    }
  }

  _facade_vars = [
    # allow_circular_includes_from should very rarely be used, but when it is,
    # it only applies to headers, so should be in the .facade target.
    "allow_circular_includes_from",
    "public_configs",
    "public_deps",
    "public",
  ]
  pw_source_set(_facade_name) {
    forward_variables_from(invoker, _facade_vars, [ "require_link_deps" ])
  }

  if (invoker.backend == "") {
    # Try to guess the name of the facade's backend variable.
    _dir = get_path_info(get_label_info(":$target_name", "dir"), "name")
    if (target_name == _dir) {
      _varname = target_name + "_BACKEND"
    } else {
      # There is no way to capitalize this string in GN, so use <FACADE_NAME>
      # instead of the lowercase target name.
      _varname = _dir + "_<FACADE_NAME>_BACKEND"
    }

    # If backend is not set to anything, create a script that emits an error.
    # This will be added as a data dependency to the actual target, so that
    # attempting to build the facade without a backend fails with a relevant
    # error message.
    pw_error(target_name + ".NO_BACKEND_SET") {
      _label = get_label_info(":${invoker.target_name}", "label_no_toolchain")
      message_lines = [
        "Attempted to build the $_label facade with no backend.",
        "",
        "If you are using this facade, ensure you have configured a backend ",
        "properly. The build arg for the facade must be set to a valid ",
        "backend in the toolchain. For example, you may need to add a line ",
        "like the following to the toolchain's .gni file:",
        "",
        "  $_varname = \"//path/to/the:backend\"",
        "",
        "Alternatively, if the target depending on this facade is a `pw_test`",
        "which should only be built in toolchains with a provided backend,",
        "consider adding an `enable_if` to the dependent target:",
        "",
        "  pw_test(...) {",
        "    enable_if = $_varname != \"\"",
        "    ...",
        "  }",
        "",
        "If you are NOT using this facade, this error may have been triggered ",
        "by trying to build all targets.",
      ]
    }
  }

  # Create a target that defines the main facade library. Always emit this
  # target, even if the backend isn't defined, so that the dependency graph is
  # correctly expressed for gn check.
  pw_source_set(target_name) {
    # The main library contains everything else specified in the template.
    _ignore_vars = _facade_vars + [
                     "backend",
                     "require_link_deps",
                   ]
    forward_variables_from(invoker, "*", _ignore_vars)

    public_deps = [ ":$_facade_name" ]

    # If the backend is set, inject it as a dependency.
    if (invoker.backend != "") {
      public_deps += [ invoker.backend ]
    } else {
      # If the backend is not set, depend on the *.NO_BACKEND_SET target.
      public_deps += [ ":$target_name.NO_BACKEND_SET" ]
    }
  }

  if (defined(invoker.require_link_deps) && invoker.backend != "") {
    # Check that the specified labels are listed in pw_build_LINK_DEPS. This
    # ensures these dependencies are available during linking, even if nothing
    # else in the build depends on them.
    foreach(label, invoker.require_link_deps) {
      _required_dep = get_label_info(label, "label_no_toolchain")
      _dep_is_in_link_dependencies = false

      foreach(link_dep, pw_build_LINK_DEPS) {
        if (get_label_info(link_dep, "label_no_toolchain") == _required_dep) {
          _dep_is_in_link_dependencies = true
        }
      }

      _facade_name = get_label_info(":$target_name", "label_no_toolchain")
      assert(_dep_is_in_link_dependencies,
             "$_required_dep must be listed in the pw_build_LINK_DEPS build " +
                 "arg when the $_facade_name facade is in use. Please update " +
                 "your toolchain configuration.")
    }
  } else {
    not_needed(invoker, [ "require_link_deps" ])
  }
}
