# 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("//zircon/public/gn/config/standard.gni")
import("//zircon/public/gn/toolchain/variants.gni")

# Redirect dependents to dependencies in another environment (toolchain).
#
# An environment_redirect() acts like a group() with `public_deps` set (which
# we call a "redirect" target): Depending on this target means to depend on
# its dependencies.  The special feature of environment_redirect() is that it
# selects an appropriate toolchain for those dependencies based on the other
# parameters described below.
#
# A complexity arises when redirecting to a different environment, cpu, or os.
# The information necessary to determine what variant will be selected is only
# available inside a toolchain context that is *some* variant of the same
# (environment, cpu, os) tuple.  Because of this, environment_redirect() has
# to first redirect to *some* extant variant of the right environment, cpu,
# and os and only from there can it then redirect to the correct variant.  To
# do this, it must redirect to the selfsame environment_redirect() in that
# other toolchain so that the instantiation in that toolchain can run the code
# to redirect to the correct variant.  An unfortunate side effect of this is
# that the entire BUILD.gn file containing the environment_redirect() target
# will then be instantiated in that other environment.  This can become
# problematic because not every BUILD.gn file expects to be instantiated in
# every different environment.  In fact, there are sometimes very good reasons
# for a BUILD.gn file to have an assert() that it's not instantiated in the
# "wrong" toolchain.
#
# There are two opposing cases with regard to this subtlety:
#
# 1. $deps leads to library() or other "non-terminal" targets.
#    Hence it's crucial to actually select the "right" variant.
#    There is no way to avoid the "self-reference in other toolchain".
#    We call this "indirect mode" because it bounces to itself in another
#    toolchain before going to $deps.
#
# 2. $deps leads only to "terminal" targets like executable() or host_tool().
#    (Intermediate group() targets leading to those are not a problem.)
#    Since each of those targets does its own variant selection, it doesn't
#    really matter which variant toolchain environment_redirect() redirects to.
#    If we know this is the case, then there is no need for the "self-reference
#    in other toolchain".  This lets us avoid instantiating the invoker's
#    build file in the target environment, which might be a problem.
#    We call this "direct mode" because it goes directly to $deps in
#    another toolchain.
#
# There is no way environment_redirect() can figure out which of these cases
# the $deps fall into.  So the invoker must indicate.  The $direct parameter
# requests "direct mode", so that the invoker need not worry about their
# BUILD.gn file being instantiated in the target toolchain.  The default is
# "indirect mode", which is more "safe" in the sense that it will never go to
# $deps in the wrong variant.
#
# Parameters
#
#   cpu
#     Optional: Required if $current_cpu is "" (default toolchain).
#     Defaults to $host_cpu in "host" or "host.*" environments.
#
#   os
#     Optional: Required if $current_os is "" (default toolchain).
#     Defaults to $host_os in "host" or "host.*" environments.
#
#   environment_label
#     Optional: Required if ${toolchain.environment_label} is undefined
#     (default toolchain).  This is the label of an execution environment
#     defined with environment().  The $deps will be resolved in one of the
#     toolchains defined by that environment() invocation.
#     Default: ${toolchain.environment_label}
#
#   deps
#     Required: These must be labels without toolchain suffix.  The
#     environment_redirect() target redirects its dependents to instead depend
#     on this list of labels, but in the toolchain selected by the other
#     parameters.
#     Type: list(label_no_toolchain)
#
#   direct
#     Optional: $deps reaches only "terminal" targets that do their own variant
#     selection.  See discussion above.
#     Type: bool
#     Default: false
#
#   shlib
#     Optional: Go directly to the environment's ${toolchain.shlib} toolchain.
#     Type: bool
#     Default: false
#
#   exclude_variant_tags
#     Optional: Never select a variant that has one of these tags.
#     This has no effect if $variant is set.
#     Type: list(string)
#
#   variant
#     Optional: Specific variant toolchain to select.  If omitted, one will be
#     chosen from $default_variants with the expectation that the
#     environment() named by $environment_label used a `.variants` list
#     including $default_variants (as is preset).
#     Type: string
#
template("environment_redirect") {
  forward_variables_from(invoker,
                         [
                           "cpu",
                           "environment_label",
                           "os",
                           "variant",
                         ])
  if (!defined(environment_label)) {
    assert(defined(toolchain.environment_label),
           "environment_redirect() needs `environment_label`" +
               " in $current_toolchain")
    environment_label = toolchain.environment_label
  }

  environment_label = get_label_info(environment_label, "label_no_toolchain")
  environment = get_label_info(environment_label, "name")

  # For, e.g., "host.fuzz", the base is "host".
  # This is not always needed depending on the cpu, os, and variant parameters.
  base_environment = get_path_info(environment, "name")
  not_needed([ "base_environment" ])

  if (defined(cpu)) {
    assert(cpu != "", "empty `cpu` in environment_redirect()")
  } else {
    if (base_environment == "host") {
      assert(host_cpu != "",
             "`cpu` required with empty `host_cpu` in environment_redirect()")
      cpu = host_cpu
    } else {
      assert(
          current_cpu != "",
          "`cpu` required with empty `current_cpu` in environment_redirect()")
      cpu = current_cpu
    }
  }

  if (!defined(os)) {
    if (base_environment == "host") {
      assert(host_os != "", "empty `host_os` in environment_redirect()")
      os = host_os
    } else {
      os = "fuchsia"
    }
  }
  assert(os != "", "empty `os` in environment_redirect()")

  redirect_deps = invoker.deps
  foreach(label, redirect_deps) {
    # The original string should not contain a "(toolchain)" suffix.
    # We can't easily tell if it does, but we can tell if it has any
    # suffix other than the expansion of "($current_toolchain)".
    full_label = get_label_info(label, "label_with_toolchain")
    bare_label = get_label_info(label, "label_no_toolchain")
    assert(full_label == "$bare_label($current_toolchain)",
           "environment_redirect() `deps` cannot have toolchain suffix")
  }

  if (!defined(variant) && (!defined(toolchain.environment_label) ||
                            toolchain.environment_label != environment_label ||
                            current_cpu != cpu || current_os != os)) {
    # If the caller didn't request a specific variant, then use some variant
    # known to exist.  Then redirect to this target in that toolchain, which
    # will have enough information to use _variant_target() below to do the
    # final redirect.  We could try here to find the default most likely to be
    # selected for an arbitrary target in the selected environment in hopes of
    # reducing the likelihood that a second redirect will actually be needed
    # (and thus reducing the number of extra toolchains in which any targets
    # might need to be instantiated that will never be built).  Most
    # environments select from `variants + default_variants`, so we could
    # guess based on that list.  However, we can't be sure that the target
    # environment actually uses $variants at all, so we could select a variant
    # from a catch-all selector in $variants that doesn't exist at all in the
    # target environment (let alone it being the actual correct default for
    # that environment, which we can't know).  But any such guessing would
    # never be perfect--if we could determine that correctly with the
    # information available to us, then we'd never need a second redirect in
    # the first place.  So rather than using $variants, we just take the first
    # plausible selector from $default_variants.  In the common environments
    # and when $variants is not set, this will be the right default.  In case
    # the target environment didn't even include $default_variants in its
    # selector list at all, environment() has special-case code to add a dummy
    # toolchain named for the "plausible" variant this logic will select.
    # **NOTE:** See the comments there that mention redirects.
    foreach(default, default_variants) {
      if (!defined(variant)) {
        if (default == "$default") {
          foreach(shorthand, variant_shorthands) {
            if (default != "" &&
                (default == shorthand.name ||
                 get_path_info(default, "dir") == shorthand.name)) {
              default = ""
            }
          }
          if (default != "") {
            if (get_path_info(default, "file") == default) {
              # Ignore "variant/output_name" shorthand selectors.
              default = {
                variant = default
              }
            } else {
              default = ""
            }
          }
        }
        if (!defined(variant) && default != "" &&
            (!defined(default.environment) || default.environment == [] ||
             default.environment + [ environment ] - [ environment ] !=
             default.environment ||
             default.environment + [ base_environment ] -
             [ base_environment ] != default.environment)) {
          variant = default.variant
          if (!defined(invoker.direct) || !invoker.direct) {
            redirect_deps = []
            redirect_deps = [ ":$target_name" ]
          }
          if (defined(invoker.exclude_variant_tags)) {
            not_needed(invoker, [ "exclude_variant_tags" ])
          }
        }
      }
    }
  } else if (defined(invoker.direct)) {
    not_needed(invoker, [ "direct" ])
  }

  if (defined(variant)) {
    assert(variant != "")

    if (redirect_deps != []) {
      # Name construction logic must match environment.gni.
      toolchain_base_name = "${environment_label}-${cpu}"

      # For all host environments include the OS to distinguish one from
      # another.  For other environments, it's implicit when it's "fuchsia"
      # and when it exactly matches the base environment name (e.g. "efi").
      if (base_environment == "host" ||
          (os != "fuchsia" && os != base_environment)) {
        toolchain_base_name += "-${os}"
      }

      toolchain_name = "${toolchain_base_name}-${variant}"
      if (defined(invoker.shlib) && invoker.shlib) {
        toolchain_name += ".shlib"
      }
    }

    group(target_name) {
      forward_variables_from(invoker,
                             [
                               "assert_no_deps",
                               "metadata",
                               "visibility",
                               "testonly",
                             ])
      if (defined(visibility)) {
        visibility += [ ":$target_name" ]
      }
      public_deps = []
      foreach(label, redirect_deps) {
        label = get_label_info(label, "label_no_toolchain")
        public_deps += [ "$label($toolchain_name)" ]
      }
    }
  } else {
    # This does variant selection as if it were an executable called "",
    # so it should get to the configured default variant.
    _variant_target(target_name) {
      forward_variables_from(invoker,
                             [
                               "assert_no_deps",
                               "metadata",
                               "visibility",
                               "testonly",
                             ])
      if (defined(visibility)) {
        visibility += [ ":$target_name" ]
      }
      target = {
        type = "group"
        match = "executable"
        output_name = ""
        variant_suffix_target = false
        forward_variables_from(invoker,
                               [
                                 "exclude_variant_tags",
                                 "shlib",
                               ])
      }
      no_implicit_deps = true
      public_deps = invoker.deps
    }
  }
}
