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

# An ICU-aware rustc_staticlib.
#
# Args:
#
#   - icu_deps: list(label): the target labels that need to be fixed up for
#     ICU product assembly.  Otherwise the same as deps.
#   - icu_non_rust_deps: list(label): Same as above, but for non_rust_deps.
#   - icu_test_deps: list(label): Same as above, but for test_deps.
#   - icu_data_deps: list(label): Same as above, but for data_deps.
#   - All other args are forwarded verbatim from the invoker.
#
# 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("icu_rustc_staticlib") {
  foreach(icu_flavor, icu_flavors) {
    # While we could make do with shorter target labels, we're using a per-ICU
    # commit ID so that we could possibly use targets from different builds.
    rustc_staticlib(
        "${target_name}.icu_${icu_flavor.name}_${icu_flavor.commit_id}") {
      # Do not forward variables which the template does not support. In addition,
      # treat "visibility" and "testonly" as special.
      forward_variables_from(invoker,
                             "*",
                             [
                               "icu_data_deps",
                               "icu_deps",
                               "icu_non_rust_deps",
                               "icu_public_deps",
                               "icu_test_deps",
                               "testonly",
                               "visibility",
                             ])
      forward_variables_from(invoker,
                             [
                               "visibility",
                               "testonly",
                             ])

      # If the invoker redefines the target output name, we need to append
      # flavor identification to ensure all targets get separately-named
      # subtargets.
      if (defined(invoker.output_name)) {
        output_name =
            "${invoker.output_name}_${icu_flavor.name}_${icu_flavor.commit_id}"
      } else if (defined(invoker.name)) {
        name = "${invoker.name}_${icu_flavor.name}_${icu_flavor.commit_id}"
      }

      _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([
                   "icu_flavor",
                   "_flavored_icu_deps",
                 ])

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

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

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

        foreach(icu_dep, invoker.icu_public_deps) {
          _relabel = get_label_info(icu_dep, "label_no_toolchain")
          public_deps += [ "${_relabel}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
        }
      }

      if (defined(invoker.icu_test_deps)) {
        if (!defined(test_deps)) {
          test_deps = []
        }

        foreach(icu_dep, invoker.icu_test_deps) {
          _relabel = get_label_info(icu_dep, "label_no_toolchain")
          test_deps += [ "${_relabel}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
        }
      }

      if (defined(invoker.icu_data_deps)) {
        if (!defined(data_deps)) {
          data_deps = []
        }

        foreach(icu_dep, invoker.icu_data_deps) {
          _relabel = get_label_info(icu_dep, "label_no_toolchain")
          data_deps += [ "${_relabel}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
        }
      }

      if (defined(configs)) {
        configs += [
          "//src/lib/icu:version",
          "//src/lib/icu:version_${icu_flavor.name}",
        ]
        configs -= [ "//src/lib/icu:version" ]
      }

      if (!defined(non_rust_deps)) {
        non_rust_deps = []
      }
      non_rust_deps += icu_fixup_deps + _flavored_icu_deps
      non_rust_deps -= icu_fixup_deps

      if (defined(invoker.icu_non_rust_deps)) {
        foreach(icu_dep, invoker.icu_non_rust_deps) {
          _relabel = get_label_info(icu_dep, "label_no_toolchain")
          non_rust_deps += [ "${_relabel}.icu_${icu_flavor.name}_${icu_flavor.commit_id}(${current_toolchain})" ]
        }
      }
    }
  }

  rustc_staticlib(target_name) {
    forward_variables_from(invoker,
                           "*",
                           [
                             "visibility",
                             "testonly",
                             "icu_deps",
                             "icu_public_deps",
                             "icu_non_rust_deps",
                             "icu_test_deps",
                             "icu_data_deps",
                           ])
    forward_variables_from(invoker,
                           [
                             "visibility",
                             "testonly",
                           ])

    # See icu_rustc_binary.gni for detailed comments.
    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
    }

    if (defined(invoker.icu_test_deps)) {
      if (!defined(test_deps)) {
        test_deps = []
      }
      test_deps += invoker.icu_test_deps
    }

    if (defined(invoker.icu_data_deps)) {
      if (!defined(data_deps)) {
        data_deps = []
      }
      data_deps += invoker.icu_data_deps
    }

    if (!defined(non_rust_deps)) {
      non_rust_deps = []
    }
    non_rust_deps += icu_fixup_deps_no_testonly
    if (defined(invoker.icu_non_rust_deps)) {
      non_rust_deps += invoker.icu_non_rust_deps
    }
  }
}
