# Copyright 2016 The Tulsi Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Skylark rules supporting Tulsi.

This file provides Bazel aspects used to obtain information about a given
project and pass it back to Tulsi.
"""

load(':tulsi_aspects_paths.bzl', 'TULSI_CURRENT_XCODE_CONFIG')

# List of all of the attributes that can link from a Tulsi-supported rule to a
# Tulsi-supported dependency of that rule.
# For instance, an ios_application's "binary" attribute might link to an
# objc_binary rule which in turn might have objc_library's in its "deps"
# attribute.
_TULSI_COMPILE_DEPS = [
    'binary',
    'bundles',
    'deps',
    'extension',
    'extensions',
    'settings_bundle',
    'non_propagated_deps',
    'test_bundle',
    'test_host',
    'watch_application',
    'xctest_app',
]

# List of all attributes whose contents should resolve to "support" files; files
# that are used by Bazel to build but do not need special handling in the
# generated Xcode project. For example, Info.plist and entitlements files.
_SUPPORTING_FILE_ATTRIBUTES = [
    'app_icons',
    'entitlements',
    'infoplist',
    'infoplists',
    'resources',
    'strings',
    'structured_resources',
    'storyboards',
    'xibs',
]

# List of rules with implicit <label>.ipa IPA outputs.
# TODO(b/33050780): This is only used for the native rules and will be removed
# in the future
_IPA_GENERATING_RULES = [
    'ios_application',
    'ios_extension',
    'ios_test',
    'objc_binary',
    'tvos_application',
]

# List of rules that generate MergedInfo.plist files as part of the build.
_MERGEDINFOPLIST_GENERATING_RULES = [
    'ios_application',
    'tvos_application',
]

# List of rules whose outputs should be treated as generated sources.
_SOURCE_GENERATING_RULES = [
    'j2objc_library',
]

# List of rules whose outputs should be treated as generated sources that do not
# use ARC.
_NON_ARC_SOURCE_GENERATING_RULES = [
    'objc_proto_library',
]

def _dict_omitting_none(**kwargs):
  """Creates a dict from the args, dropping keys with None or [] values."""
  return {name: kwargs[name]
          for name in kwargs
          # Skylark doesn't support "is"; comparison is explicit for correctness.
          # pylint: disable=g-equals-none,g-explicit-bool-comparison
          if kwargs[name] != None and kwargs[name] != []
         }


def _struct_omitting_none(**kwargs):
  """Creates a struct from the args, dropping keys with None or [] values."""
  return struct(**_dict_omitting_none(**kwargs))


def _convert_outpath_to_symlink_path(path, use_tulsi_symlink=False):
  """Converts full output paths to their tulsi-symlink equivalents.

  Bazel output paths are unstable, prone to change with architecture,
  platform or flag changes. Therefore we can't rely on them to supply to Xcode.
  Instead, we will root all outputs under a stable tulsi dir,
  and the bazel_build.py script will link the artifacts into the correct
  location under it.

  Tulsi root is located at WORKSPACE/bazel-exec-root-link/tulsi-includes/x/x/.
  The two "x" directories are stubs to match the number of path components, so
  that relative paths work with the new location. Some Bazel outputs, like
  module maps, use relative paths to reference other files in the build.

  In short, when `use_tulsi_symlink` is `True`, this method will transform
    bazel-out/ios-x86_64-min7.0/genfiles/foo
  to
    tulsi-includes/x/x/foo

  When `use_tulsi_symlink` is `False`, this method will transform
    bazel-outbin/ios-x86_64-min7.0/genfiles/foo
  to
    bazel-genfiles/foo

  This flag is currently enabled for generated headers, sources, Swift modules,
  and module maps. Disabled for everything else to keep backwards compatibility.
  TODO(tulsi-team): Phase out the older bazel symlink completely and remove
  the flag.

  Args:
    path: path to transform
    use_tulsi_symlink: whether to use the new tulsi symlink, or the older bazel
      format.

  Returns:
    A string that is the original path modified according to the rules.
  """
  # The path will be of the form:
  # if use_tulsi_symlink:
  #   tulsi-includes/x/x/symlink[/.*]
  # otherwise:
  #   bazel-[whatever]/[platform-config]/symlink[/.*]
  first_dash = path.find('-')
  components = path.split('/')
  if (len(components) > 2 and
      first_dash >= 0 and
      first_dash < len(components[0])):
    if use_tulsi_symlink:
      return 'tulsi-includes/x/x/' + '/'.join(components[3:])
    else:
      return path[:first_dash + 1] + '/'.join(components[2:])
  return path

def _is_bazel_external_file(f):
  """Returns True if the given file is a Bazel external file."""
  return f.path.startswith('external/')


def _file_metadata(f, use_tulsi_symlink=False):
  """Returns metadata about a given File."""
  if not f:
    return None

  # Special case handling for Bazel external files which have a path that starts
  # with 'external/' but their short_path and root.path have no mention of being
  # external.
  out_path = f.path if _is_bazel_external_file(f) else f.short_path
  if not f.is_source:
    root_path = f.root.path
    symlink_path = _convert_outpath_to_symlink_path(
        root_path,
        use_tulsi_symlink=use_tulsi_symlink)
    if symlink_path == root_path:
      # The root path should always be bazel-out/... and thus is expected to be
      # updated.
      print('Unexpected root path "%s". Please report.' % root_path)
      root_execution_path_fragment = root_path
    else:
      root_execution_path_fragment = symlink_path
  else:
    root_execution_path_fragment = None

  # TODO(abaire): Remove once Skylark File objects can reference directories.
  # At the moment (Oct. 2016), Bazel disallows most files without extensions.
  # As a temporary hack, Tulsi treats File instances pointing at extension-less
  # paths as directories. This is extremely fragile and must be replaced with
  # logic properly homed in Bazel.
  is_dir = (f.basename.find('.') == -1)

  return _struct_omitting_none(
      path=out_path,
      src=f.is_source,
      root=root_execution_path_fragment,
      is_dir=is_dir
  )


def _file_metadata_by_replacing_path(f, new_path, new_is_dir=None):
  """Returns a copy of the f _file_metadata struct with the given path."""
  root_path = _get_opt_attr(f, 'rootPath')
  if new_is_dir == None:
    new_is_dir = f.is_dir

  return _struct_omitting_none(
      path=new_path,
      src=f.src,
      root=root_path,
      is_dir=new_is_dir
  )


def _collect_artifacts(obj, attr_path):
  """Returns a list of Artifact objects for the attr_path in obj."""
  return [f for src in _getattr_as_list(obj, attr_path)
          for f in _get_opt_attr(src, 'files')]


def _collect_files(obj, attr_path):
  """Returns a list of artifact_location's for the attr_path in obj."""
  return [_file_metadata(f) for f in _collect_artifacts(obj, attr_path)]


def _collect_first_file(obj, attr_path):
  """Returns a the first artifact_location for the attr_path in obj."""
  files = _collect_files(obj, attr_path)
  if not files:
    return None
  return files[0]


def _collect_supporting_files(rule_attr):
  """Extracts 'supporting' files from the given rule attributes."""
  all_files = []
  for attr in _SUPPORTING_FILE_ATTRIBUTES:
    all_files += _collect_files(rule_attr, attr)
  return all_files


def _collect_bundle_paths(rule_attr, bundle_attributes, bundle_ext):
  """Extracts subpaths with the given bundle_ext for the given attributes."""
  discovered_paths = depset()
  bundles = []
  if not bundle_ext.endswith('/'):
    bundle_ext += '/'
  bundle_ext_len = len(bundle_ext) - 1

  for attr in bundle_attributes:
    for f in _collect_files(rule_attr, attr):
      end = f.path.find(bundle_ext)
      if end < 0:
        continue
      end += bundle_ext_len

      path = f.path[:end]
      root_path = _get_opt_attr(f, 'rootPath')
      full_path = str(root_path) + ':' + path
      if full_path in discovered_paths:
        continue
      discovered_paths += [full_path]
      # Generally Xcode treats bundles as special files so they should not be
      # flagged as directories.
      bundles.append(_file_metadata_by_replacing_path(f, path, False))
  return bundles


def _collect_asset_catalogs(rule_attr):
  """Extracts xcassets directories from the given rule attributes."""
  attrs = ['app_asset_catalogs', 'asset_catalogs']
  bundles = _collect_bundle_paths(rule_attr, attrs, '.xcassets')
  bundles.extend(_collect_bundle_paths(rule_attr, attrs, '.xcstickers'))

  return bundles


def _collect_bundle_imports(rule_attr):
  """Extracts bundle directories from the given rule attributes."""
  return _collect_bundle_paths(rule_attr,
                               ['bundle_imports', 'settings_bundle'],
                               '.bundle')


def _collect_framework_imports(rule_attr):
  """Extracts framework directories from the given rule attributes."""
  return _collect_bundle_paths(rule_attr,
                               ['framework_imports'],
                               '.framework')


def _collect_xcdatamodeld_files(obj, attr_path):
  """Returns artifact_location's for xcdatamodeld's for attr_path in obj."""
  files = _collect_files(obj, attr_path)
  if not files:
    return []
  discovered_paths = depset()
  datamodelds = []
  for f in files:
    end = f.path.find('.xcdatamodel/')
    if end < 0:
      continue
    end += 12

    path = f.path[:end]
    root_path = _get_opt_attr(f, 'rootPath')
    full_path = str(root_path) + ':' + path
    if full_path in discovered_paths:
      continue
    discovered_paths += [full_path]
    datamodelds.append(_file_metadata_by_replacing_path(f, path, False))
  return datamodelds


def _collect_dependency_labels(rule, attr_list):
  """Collects Bazel labels for a list of dependency attributes.

  Args:
    rule: The Bazel rule whose dependencies should be collected.
    attr_list: List of attribute names potentially containing Bazel labels for
        dependencies of the given rule.

  Returns:
    A list of the Bazel labels of dependencies of the given rule.
  """
  rule_attrs = rule.attr
  deps = [dep
          for attribute in attr_list
          for dep in _getattr_as_list(rule_attrs, attribute)]
  return [dep.label for dep in deps if hasattr(dep, 'label')]


def _get_opt_attr(obj, attr_path):
  """Returns the value at attr_path on the given object if it is set."""
  attr_path = attr_path.split('.')
  for a in attr_path:
    if not obj or not hasattr(obj, a):
      return None
    obj = getattr(obj, a)
  return obj


def _get_label_attr(obj, attr_path):
  """Returns the value at attr_path as a label string if it is set."""
  label = _get_opt_attr(obj, attr_path)
  return str(label) if label else None


def _getattr_as_list(obj, attr_path):
  """Returns the value at attr_path as a list.

  This handles normalization of attributes containing a single value for use in
  methods expecting a list of values.

  Args:
    obj: The struct whose attributes should be parsed.
    attr_path: Dotted path of attributes whose value should be returned in
        list form.

  Returns:
    A list of values for obj at attr_path or [] if the struct has
    no such attribute.
  """
  val = _get_opt_attr(obj, attr_path)
  if not val:
    return []

  if type(val) == 'list':
    return val
  return [val]


def _extract_defines_from_option_list(lst):
  """Extracts preprocessor defines from a list of -D strings."""
  defines = []
  for item in lst:
    if item.startswith('-D'):
      defines.append(item[2:])
  return defines


def _extract_compiler_defines(ctx):
  """Extracts preprocessor defines from compiler fragments."""
  defines = []

  cpp_fragment = _get_opt_attr(ctx.fragments, 'cpp')
  if cpp_fragment:
    c_options = _get_opt_attr(cpp_fragment, 'c_options')
    defines += _extract_defines_from_option_list(c_options)

    compiler_options = cpp_fragment.compiler_options([])
    defines += _extract_defines_from_option_list(compiler_options)

    unfiltered = cpp_fragment.unfiltered_compiler_options([])
    defines += _extract_defines_from_option_list(unfiltered)

    cxx = cpp_fragment.cxx_options([])
    defines += _extract_defines_from_option_list(cxx)

  objc_fragment = _get_opt_attr(ctx.fragments, 'objc')
  if objc_fragment:
    objc_copts = _get_opt_attr(objc_fragment, 'copts')
    defines += _extract_defines_from_option_list(objc_copts)

  return defines


def _collect_secondary_artifacts(target, ctx):
  """Returns a list of file metadatas for implicit outputs of 'rule'."""
  artifacts = []
  rule = ctx.rule
  if rule.kind in _MERGEDINFOPLIST_GENERATING_RULES:
    bin_dir = _convert_outpath_to_symlink_path(ctx.bin_dir.path)
    package = target.label.package
    basename = target.label.name
    artifacts.append(_struct_omitting_none(
        path='%s/%s-MergedInfo.plist' % (package, basename),
        src=False,
        root=bin_dir
    ))

  return artifacts


def _extract_generated_sources(target):
  """Returns (source_metadatas, includes) generated by the given target."""
  file_metadatas = []
  objc_provider = _get_opt_attr(target, 'objc')
  if hasattr(objc_provider, 'source') and hasattr(objc_provider, 'header'):
    all_files = depset(objc_provider.source)
    all_files += objc_provider.header
    file_metadatas = [_file_metadata(f) for f in all_files]

  return file_metadatas

def _get_platform_type(ctx):
  """Return the current apple_common.platform_type as a string."""
  current_platform = (_get_opt_attr(ctx, 'rule.attr.platform_type')
                      or _get_opt_attr(ctx, 'rule.attr._platform_type'))
  if not current_platform:
    apple_frag = _get_opt_attr(ctx.fragments, 'apple')
    current_platform = str(apple_frag.single_arch_platform.platform_type)
  return current_platform

def _extract_minimum_os_for_platform(ctx, platform_type_str):
  """Extracts the minimum OS version for the given apple_common.platform."""
  min_os = _get_opt_attr(ctx, 'rule.attr.minimum_os_version')
  if min_os:
    return min_os

  platform_type = getattr(apple_common.platform_type, platform_type_str)
  min_os = (ctx.attr._tulsi_xcode_config[apple_common.XcodeVersionConfig]
            .minimum_os_for_platform_type(platform_type))

  if not min_os:
    return None

  # Convert the DottedVersion to a string suitable for inclusion in a struct.
  return str(min_os)


def _extract_swift_language_version(ctx):
  """Returns the Swift version set by the xcode_toolchain option for ctx."""
  swift_toolchain = _get_opt_attr(ctx, 'fragments.apple.xcode_toolchain')
  if swift_toolchain == 'com.apple.dt.toolchain.Swift_2_3':
    return ('2.3', swift_toolchain)
  elif swift_toolchain:
    # TODO(abaire): Adjust as necessary once versions > 3.0 come out.
    return ('3.0', swift_toolchain)

  # TODO(abaire): Remove the fallback check for swift_library once
  #               xcode_toolchain is available everywhere.
  if ctx.rule.kind == 'swift_library':
    return ('3.0', 'com.apple.dt.toolchain.XcodeDefault')

  return (None, None)


def _collect_swift_modules(target):
  """Returns a depset of Swift modules found on the given target."""
  swift_modules = depset()
  for modules in _getattr_as_list(target, 'swift.transitive_modules'):
    swift_modules += modules
  return swift_modules


def _collect_module_maps(target):
  """Returns a depset of Clang module maps found on the given target."""
  maps = depset()
  if hasattr(target, 'swift'):
    for module_maps in _getattr_as_list(target, 'objc.module_map'):
      maps += module_maps
  return maps

# TODO(b/64490743): Add these files to the Xcode project.
def _collect_swift_header(target):
  """Returns a depset of Swift generated headers found on the given target."""
  headers = depset()
  # swift_* targets put the generated header into their objc provider HEADER
  # field.
  if hasattr(target, 'swift') and hasattr(target, 'objc'):
    headers += target.objc.header
  return headers


def _tulsi_sources_aspect(target, ctx):
  """Extracts information from a given rule, emitting it as a JSON struct."""
  rule = ctx.rule
  target_kind = rule.kind
  rule_attr = _get_opt_attr(rule, 'attr')
  bundle_name = _get_opt_attr(target, 'apple_bundle.bundle_name')

  tulsi_info_files = depset()
  transitive_attributes = dict()
  for attr_name in _TULSI_COMPILE_DEPS:
    deps = _getattr_as_list(rule_attr, attr_name)
    for dep in deps:
      if hasattr(dep, 'tulsi_info_files'):
        tulsi_info_files += dep.tulsi_info_files
      if hasattr(dep, 'transitive_attributes'):
        transitive_attributes += dep.transitive_attributes

  artifacts = _get_opt_attr(target, 'files')
  if artifacts:
    # Ignore any generated Xcode projects as they are not useful to Tulsi.
    artifacts = [_file_metadata(f)
                 for f in artifacts
                 if not f.short_path.endswith('project.pbxproj')]
  else:
    # artifacts may be an empty set type, in which case it must be explicitly
    # set to None to allow Skylark's serialization to work.
    artifacts = None

  srcs = (_collect_files(rule, 'attr.srcs') +
          _collect_files(rule, 'attr.hdrs') +
          _collect_files(rule, 'attr.textual_hdrs'))
  generated_files = []
  generated_non_arc_files = []
  if target_kind in _SOURCE_GENERATING_RULES:
    generated_files = _extract_generated_sources(target)
  elif target_kind in _NON_ARC_SOURCE_GENERATING_RULES:
    generated_non_arc_files = _extract_generated_sources(target)

  swift_transitive_modules = depset(
      [_file_metadata(f, use_tulsi_symlink=True)
       for f in _collect_swift_modules(target)])

  # Collect ObjC module maps dependencies for Swift targets.
  objc_module_maps = depset(
      [_file_metadata(f, use_tulsi_symlink=True)
       for f in _collect_module_maps(target)])

  # Collect the dependencies of this rule, dropping any .jar files (which may be
  # created as artifacts of java/j2objc rules).
  dep_labels = _collect_dependency_labels(rule, _TULSI_COMPILE_DEPS)
  compile_deps = [str(d) for d in dep_labels if not d.name.endswith('.jar')]

  binary_rule = _get_opt_attr(rule_attr, 'binary')
  if binary_rule and type(binary_rule) == 'list':
    binary_rule = binary_rule[0]

  supporting_files = (_collect_supporting_files(rule_attr) +
                      _collect_asset_catalogs(rule_attr) +
                      _collect_bundle_imports(rule_attr))

  # Keys for attribute and inheritable_attributes keys must be kept in sync
  # with defines in Tulsi's RuleEntry.
  attributes = _dict_omitting_none(
      binary=_get_label_attr(binary_rule, 'label'),
      copts=_get_opt_attr(rule_attr, 'copts'),
      datamodels=_collect_xcdatamodeld_files(rule_attr, 'datamodels'),
      supporting_files=supporting_files,
      xctest=_get_opt_attr(rule_attr, 'xctest'),
      xctest_app=_get_label_attr(rule_attr, 'xctest_app.label'),
      test_host=_get_label_attr(rule_attr, 'test_host.label'),
      test_bundle=_get_label_attr(rule_attr, 'test_bundle.label'),
  )

  # Inheritable attributes are pulled up through dependencies of type 'binary'
  # to simplify handling in Tulsi (so it appears as though bridging_header is
  # defined on an ios_application rather than its associated objc_binary, for
  # example).
  inheritable_attributes = _dict_omitting_none(
      bridging_header=_collect_first_file(rule_attr, 'bridging_header'),
      compiler_defines=_extract_compiler_defines(ctx),
      enable_modules=_get_opt_attr(rule_attr, 'enable_modules'),
      launch_storyboard=_collect_first_file(rule_attr, 'launch_storyboard'),
      pch=_collect_first_file(rule_attr, 'pch'),
  )

  # Merge any attributes on the "binary" dependency into this container rule.
  binary_attributes = _get_opt_attr(binary_rule, 'inheritable_attributes')
  if binary_attributes:
    inheritable_attributes = binary_attributes + inheritable_attributes

  extensions = [str(t.label) for t in _getattr_as_list(rule_attr, 'extensions')]
  # Tulsi considers WatchOS apps and extensions as an "extension"
  if target_kind == 'watchos_application':
    watch_ext = _get_label_attr(rule_attr, 'extension.label')
    extensions.append(watch_ext)
  if target_kind == 'ios_application':
    watch_app = _get_label_attr(rule_attr, 'watch_application.label')
    if watch_app:
      extensions.append(watch_app)

  bundle_id = _get_opt_attr(rule_attr, 'bundle_id')

  # Build up any local transitive attributes and apply them.
  swift_language_version, swift_toolchain = _extract_swift_language_version(ctx)
  if swift_language_version:
    transitive_attributes['swift_language_version'] = swift_language_version
    transitive_attributes['has_swift_dependency'] = True
  if swift_toolchain:
    transitive_attributes['swift_toolchain'] = swift_toolchain
    transitive_attributes['has_swift_dependency'] = True

  # Collect Info.plist files from an extension to figure out its type.
  infoplist = None

  # Only Skylark versions of ios_extension have the 'apple_bundle' provider.
  # TODO(b/37912213): Migrate to the new-style providers.
  if target_kind == 'ios_extension' and hasattr(target, 'apple_bundle'):
    infoplist = target.apple_bundle.infoplist

  all_attributes = attributes + inheritable_attributes + transitive_attributes

  objc_provider = _get_opt_attr(target, 'objc')
  target_includes = []
  target_defines = []
  if objc_provider:
    target_includes = [_convert_outpath_to_symlink_path(x, use_tulsi_symlink=True)
                       for x in objc_provider.include]
    target_defines = objc_provider.define.to_list()

  platform_type = _get_platform_type(ctx)

  info = _struct_omitting_none(
      artifacts=artifacts,
      attr=_struct_omitting_none(**all_attributes),
      build_file=ctx.build_file_path,
      bundle_id=bundle_id,
      bundle_name=bundle_name,
      defines=target_defines,
      deps=compile_deps,
      extensions=extensions,
      framework_imports=_collect_framework_imports(rule_attr),
      generated_files=generated_files,
      generated_non_arc_files=generated_non_arc_files,
      includes=target_includes,
      os_deployment_target=_extract_minimum_os_for_platform(ctx, platform_type),
      label=str(target.label),
      non_arc_srcs=_collect_files(rule, 'attr.non_arc_srcs'),
      secondary_product_artifacts=_collect_secondary_artifacts(target, ctx),
      srcs=srcs,
      swift_transitive_modules=swift_transitive_modules.to_list(),
      objc_module_maps=list(objc_module_maps),
      type=target_kind,
      infoplist=infoplist.basename if infoplist else None,
      platform_type=platform_type,
  )

  # Create an action to write out this target's info.
  output = ctx.new_file(target.label.name + '.tulsiinfo')
  ctx.file_action(output, info.to_json())
  tulsi_info_files += depset([output])

  if infoplist:
    tulsi_info_files += [infoplist]

  return struct(
      # Matches the --output_groups on the bazel commandline.
      output_groups={
          'tulsi-info': tulsi_info_files,
      },
      # The file actions used to save this rule's info and that of all of its
      # transitive dependencies.
      tulsi_info_files=tulsi_info_files,
      # The inheritable attributes of this rule, expressed as a dict instead of
      # a struct to allow easy joining.
      inheritable_attributes=inheritable_attributes,
      # Transitive info that should be applied to every rule that depends on
      # this rule.
      transitive_attributes=transitive_attributes,
  )

def _tulsi_outputs_aspect(target, ctx):
  """Collects outputs of each build invocation."""

  rule = ctx.rule
  target_kind = rule.kind
  rule_attr = _get_opt_attr(rule, 'attr')
  tulsi_generated_files = depset()
  for attr_name in _TULSI_COMPILE_DEPS:
    deps = _getattr_as_list(rule_attr, attr_name)
    for dep in deps:
      if hasattr(dep, 'tulsi_generated_files'):
        tulsi_generated_files += dep.tulsi_generated_files

  bundle_name = _get_opt_attr(target, 'apple_bundle.bundle_name')
  # TODO(b/37912213): Migrate to the new-style providers.
  if hasattr(target, 'apple_bundle'):
    artifacts = [target.apple_bundle.archive.path]
  else:  # TODO(b/33050780): Remove this branch when native rules are deleted.
    ipa_output_name = None
    if target_kind in _IPA_GENERATING_RULES:
      ipa_output_name = target.label.name

    artifacts = [x.path for x in target.files]
    if ipa_output_name:
      # Some targets produce more than one IPA or ZIP (e.g. ios_test will
      # generate two IPAs for the test and host bundles), we want to filter only
      # exact matches to label name.
      output_ipa = '/%s.ipa' % ipa_output_name
      output_zip = '/%s.zip' % ipa_output_name

      artifacts = [x for x in artifacts if x.endswith(output_ipa)
                   or x.endswith(output_zip)]

  # Collect generated files for bazel_build.py to copy under Tulsi root.
  all_files = depset()
  if target_kind in _SOURCE_GENERATING_RULES + _NON_ARC_SOURCE_GENERATING_RULES:
    objc_provider = _get_opt_attr(target, 'objc')
    if hasattr(objc_provider, 'source') and hasattr(objc_provider, 'header'):
      all_files += objc_provider.source
      all_files += objc_provider.header

  all_files += _collect_swift_header(target)
  all_files += _collect_swift_modules(target)
  all_files += _collect_module_maps(target)
  all_files += (_collect_artifacts(rule, 'attr.srcs')
                + _collect_artifacts(rule, 'attr.hdrs')
                + _collect_artifacts(rule, 'attr.textual_hdrs'))

  tulsi_generated_files += depset(
      [x for x in all_files.to_list() if not x.is_source])

  info = _struct_omitting_none(
      artifacts=artifacts,
      generated_sources=[(x.path, x.short_path) for x in tulsi_generated_files],
      bundle_name=bundle_name)

  output = ctx.new_file(target.label.name + '.tulsiouts')
  ctx.file_action(output, info.to_json())

  return struct(
      output_groups={
          'tulsi-outputs': [output],
      },
      tulsi_generated_files=tulsi_generated_files,
  )


tulsi_sources_aspect = aspect(
    implementation=_tulsi_sources_aspect,
    attrs = {
        '_tulsi_xcode_config': attr.label(default=TULSI_CURRENT_XCODE_CONFIG) },
    attr_aspects=_TULSI_COMPILE_DEPS,
    fragments=['apple', 'cpp', 'objc'],
)


# This aspect does not propagate past the top-level target because we only need
# the top target outputs.
tulsi_outputs_aspect = aspect(
    implementation=_tulsi_outputs_aspect,
    attr_aspects=_TULSI_COMPILE_DEPS,
    fragments=['apple', 'cpp', 'objc'],
)
