# Copyright 2023 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/renamed_binary.gni")
import("config.gni")  # icu_flavors, icu_fixup_deps

# Args:
#   - icu_flavor({name(string), commit_id(string)}): the ICU flavor to use.
#
# Refer to icu_source_set.gni for detailed comments on some constructs below,
# the ideas of which are commonly reused in all icu_* templates.
template("_common") {
  forward_variables_from(invoker, [ "output_name" ])
  assert(defined(invoker.icu_flavor), "icu_flavor is required")
  not_needed([ "output_name" ])

  _original_target = "${target_name}.original"

  if (defined(output_name)) {
    original_output_name = output_name
  } else {
    original_output_name = target_name
  }

  executable(_original_target) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "testonly",
                             "visibility",
                             "icu_deps",
                             "icu_public_deps",
                           ])
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])

    _flavored_icu_deps = [
      get_label_info("//third_party/icu/${icu_flavor.name}:icu",
                     "label_with_toolchain"),
      get_label_info("//third_party/icu/${icu_flavor.name}:icudata",
                     "label_with_toolchain"),
    ]
    not_needed([
                 "output_name",
                 "_flavored_icu_deps",
               ])

    # Fix-up executable naming.
    if (defined(output_name)) {
      output_name =
          "${output_name}.icu_${icu_flavor.name}_${icu_flavor.commit_id}"
    } else {
      output_name = target_name
    }

    if (defined(invoker.icu_deps)) {
      if (!defined(deps)) {
        deps = []
      }

      deps += icu_fixup_deps + _flavored_icu_deps
      deps -= icu_fixup_deps

      foreach(icu_dep, invoker.icu_deps) {
        deps += [ "${icu_dep}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
      }
    }

    if (defined(icu_public_deps)) {
      if (!defined(public_deps)) {
        public_deps = []
      }
      public_deps += icu_fixup_deps + _flavored_icu_deps
      public_deps -= icu_fixup_deps
      foreach(icu_public_dep, icu_public_deps) {
        public_deps += [ "${icu_public_dep}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
      }
    }
  }

  # The binary must be renamed after compilation, because otherwise it
  # will have the same name as the binary produced by $target_name.
  renamed_binary(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "deps",
                             "public_deps",
                             "testonly",
                             "visibility",
                             "icu_deps",
                             "icu_public_deps",
                           ])
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])
    source = "$root_out_dir/${output_name}.icu_${icu_flavor.name}_${icu_flavor.commit_id}"
    dest = "bin/${original_output_name}"
    source_deps = [ ":${_original_target}" ]
  }
}

# An ICU-aware executable.
#
# Args:
#
#   - icu_deps: list(label): the target labels that need to be fixed up for
#     ICU product assembly.  Otherwise the same as deps.
#   - icu_public_deps: list(label): Same as above, but for public_deps
#
# All other args are forwarded verbatim from the invoker.
template("icu_executable") {
  foreach(flavor, icu_flavors) {
    _common("${target_name}.icu_${flavor.name}_${flavor.commit_id}") {
      forward_variables_from(invoker, "*")
      icu_flavor = flavor
    }
  }

  executable(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "testonly",
                             "visibility",
                             "icu_deps",
                             "icu_public_deps",
                           ])
    forward_variables_from(invoker,
                           [
                             "testonly",
                             "visibility",
                           ])

    if (defined(invoker.icu_deps)) {
      if (!defined(deps)) {
        deps = []
      }
      deps += invoker.icu_deps
    }
    if (defined(invoker.icu_public_deps)) {
      if (!defined(public_deps)) {
        public_deps = []
      }
      public_deps += invoker.icu_public_deps
    }
  }
}
