# 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.

import("//build/config/ios/ios_sdk.gni")

# 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 (is_fat_secondary_toolchain) {
    group(target_name) {
      public_deps = [ ":$target_name($primary_fat_toolchain_name)" ]
    }
  } 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_build_dir),
        rebase_path(_output_dir, root_build_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("colorset") {
  asset_catalog(target_name) {
    forward_variables_from(invoker, "*", [ "asset_type" ])
    asset_type = "colorset"
  }
}
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"
  }
}
