# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# This template declares a bundle_data target that references an asset
# catalog so that it is compiled to the asset catalog of the generated
# bundle.
#
# The create_bundle target requires that all asset catalogs are part of an
# .xcasset bundle. This requirement comes from actool that only receives
# the path to the .xcasset bundle directory and not to the individual
# .imageset directories.
#
# The requirement is a bit problematic as it prevents compiling only a
# subset of the asset catakig that are contained in a .xcasset. This template
# fixes that by instead copying the content of the asset catalog to temporary
# .xcasset directory (below $root_out_dir) and defining a bundle_data
# target that refers to those copies (this is efficient as the "copy" is
# implemented by hardlinking if possible on macOS).
#
# Since the create_data target will only refer to the .xcasset directory
# and additional "action" target that runs a dummy script is defined. It
# does nothing but pretends to generate the .xcassets directory (while
# it is really created as a side-effect of the "copy" step). This allows
# to workaround the check in "gn" that all inputs below $root_out_dir have
# to be outputs of another target with a public dependency path.
#
# This template also ensures that the file are only copied once when the
# build targets multiple architectures at the same time (aka "fat build").
#
# Arguments
#
#     sources:
#       required, list of strings, paths to the file contained in the
#       asset catalog directory; this must contain the Contents.json file
#       and all the image referenced by it (not enforced by the template).
#
#     asset_type:
#       required, string, type of the asset catalog, that is the extension
#       of the directory containing the images and the Contents.json file.
#
template("asset_catalog") {
  assert(defined(invoker.sources) && invoker.sources != [],
         "sources must be defined and not empty for $target_name")

  assert(defined(invoker.asset_type) && invoker.asset_type != "",
         "asset_type must be defined and not empty for $target_name")

  if (current_toolchain != default_toolchain) {
    group(target_name) {
      public_deps = [
        ":$target_name($default_toolchain)",
      ]
    }
  } else {
    _copy_target_name = target_name + "__copy"
    _data_target_name = target_name

    _sources = invoker.sources
    _outputs = []

    # The compilation of resources into Assets.car is enabled automatically
    # by the "create_bundle" target if any of the "bundle_data" sources's
    # path is in a .xcassets directory and matches one of the know asset
    # catalog type.
    _xcassets_dir = "$target_gen_dir/${target_name}.xcassets"
    _output_dir = "$_xcassets_dir/" +
                  get_path_info(get_path_info(_sources[0], "dir"), "file")

    foreach(_source, invoker.sources) {
      _dir = get_path_info(_source, "dir")
      _outputs += [ "$_output_dir/" + get_path_info(_source, "file") ]

      assert(get_path_info(_dir, "extension") == invoker.asset_type,
             "$_source dirname must have .${invoker.asset_type} extension")
    }

    action(_copy_target_name) {
      # Forward "deps", "public_deps" and "testonly" in case some of the
      # source files are generated.
      forward_variables_from(invoker,
                             [
                               "deps",
                               "public_deps",
                               "testonly",
                             ])

      script = "//build/config/ios/hardlink.py"

      visibility = [ ":$_data_target_name" ]
      sources = _sources
      outputs = _outputs + [ _xcassets_dir ]

      args = [
        rebase_path(get_path_info(_sources[0], "dir"), root_out_dir),
        rebase_path(_output_dir, root_out_dir),
      ]
    }

    bundle_data(_data_target_name) {
      forward_variables_from(invoker,
                             "*",
                             [
                               "deps",
                               "outputs",
                               "public_deps",
                               "sources",
                             ])

      sources = _outputs
      outputs = [
        "{{bundle_resources_dir}}/{{source_file_part}}",
      ]
      public_deps = [
        ":$_copy_target_name",
      ]
    }
  }
}

# Those templates are specialisation of the asset_catalog template for known
# types of asset catalog types (imageset, launchimage, appiconset).
#
# Arguments
#
#     sources:
#       required, list of strings, paths to the file contained in the
#       asset catalog directory; this must contain the Contents.json file
#       and all the image referenced by it (not enforced by the template).
#
template("appiconset") {
  asset_catalog(target_name) {
    forward_variables_from(invoker, "*", [ "asset_type" ])
    asset_type = "appiconset"
  }
}
template("imageset") {
  asset_catalog(target_name) {
    forward_variables_from(invoker, "*", [ "asset_type" ])
    asset_type = "imageset"
  }
}
template("launchimage") {
  asset_catalog(target_name) {
    forward_variables_from(invoker, "*", [ "asset_type" ])
    asset_type = "launchimage"
  }
}
