#!/usr/bin/python
# -*- coding: utf-8 -*-
# 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.

"""Bridge between Xcode and Bazel for the "build" action."""

import atexit
import errno
import fcntl
import hashlib
import inspect
import io
import json
import os
import pipes
import re
import shutil
import signal
import subprocess
import sys
import textwrap
import threading
import time
import zipfile

from apfs_clone_copy import CopyOnWrite
import bazel_build_events
import bazel_build_settings
import bazel_options
from bootstrap_lldbinit import BootstrapLLDBInit
from bootstrap_lldbinit import TULSI_LLDBINIT_FILE
import tulsi_logging
from update_symbol_cache import UpdateSymbolCache


# List of frameworks that Xcode injects into test host targets that should be
# re-signed when running the tests on devices.
XCODE_INJECTED_FRAMEWORKS = [
    'libXCTestBundleInject.dylib',
    'libXCTestSwiftSupport.dylib',
    'IDEBundleInjection.framework',
    'XCTAutomationSupport.framework',
    'XCTest.framework',
]

_logger = None


def _PrintUnbuffered(msg):
  sys.stdout.write('%s\n' % msg)
  sys.stdout.flush()


def _PrintXcodeWarning(msg):
  sys.stdout.write(':: warning: %s\n' % msg)
  sys.stdout.flush()


def _PrintXcodeError(msg):
  sys.stderr.write(':: error: %s\n' % msg)
  sys.stderr.flush()


def _Fatal(msg, fatal_frame=None):
  """Print a fatal error pointing to the failure line inside the script."""
  if not fatal_frame:
    fatal_frame = inspect.currentframe().f_back
  filename, line_number, _, _, _ = inspect.getframeinfo(fatal_frame)
  _PrintUnbuffered('%s:%d: error: %s' % (os.path.abspath(filename),
                                         line_number, msg))


CLEANUP_BEP_FILE_AT_EXIT = False


# Function to be called atexit to clean up the BEP file if one is present.
# This is especially useful in cases of abnormal termination (such as what
# happens when Xcode is killed).
def _BEPFileExitCleanup(bep_file_path):
  if not CLEANUP_BEP_FILE_AT_EXIT:
    return
  try:
    os.remove(bep_file_path)
  except OSError as e:
    _PrintXcodeWarning('Failed to remove BEP file from %s. Error: %s' %
                       (bep_file_path, e.strerror))


def _InterruptHandler(signum, frame):
  """Gracefully exit on SIGINT."""
  del signum, frame  # Unused.
  _PrintUnbuffered('Caught interrupt signal. Exiting...')
  sys.exit(0)


class Timer(object):
  """Simple profiler."""

  def __init__(self, action_name, action_id):
    """Creates a new Timer object.

    Args:
      action_name: A human-readable action name, shown in the build log.
      action_id: A machine-readable action identifier, can be used for metrics.

    Returns:
      A Timer instance.

    Raises:
      RuntimeError: if Timer is created without initializing _logger.
    """
    if _logger is None:
      raise RuntimeError('Attempted to create Timer without a logger.')
    self.action_name = action_name
    self.action_id = action_id
    self._start = None

  def Start(self):
    self._start = time.time()
    return self

  def End(self, log_absolute_times=False):
    end = time.time()
    seconds = end - self._start
    if log_absolute_times:
      _logger.log_action(self.action_name, self.action_id, seconds,
                         self._start, end)
    else:
      _logger.log_action(self.action_name, self.action_id, seconds)


def _LockFileCreate():
  # This relies on this script running at the root of the bazel workspace.
  cwd = os.environ['PWD']
  cwd_hash = hashlib.sha256(cwd.encode()).hexdigest()
  return '/tmp/tulsi_bazel_build_{}.lock'.format(cwd_hash)


# Function to be called atexit to release the file lock on script termination.
def _LockFileExitCleanup(lock_file_handle):
  lock_file_handle.close()


def _LockFileAcquire(lock_path):
  """Force script to wait on file lock to serialize build target actions.

  Args:
    lock_path: Path to the lock file.
  """
  _PrintUnbuffered('Queuing Tulsi build...')
  lockfile = open(lock_path, 'w')
  # Register "fclose(...)" as early as possible, before acquiring lock.
  atexit.register(_LockFileExitCleanup, lockfile)
  while True:
    try:
      fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
      break
    except IOError as err:
      if err.errno != errno.EAGAIN:
        raise
      else:
        time.sleep(0.1)


class CodesignBundleAttributes(object):
  """Wrapper class for codesigning attributes of a signed bundle."""

  # List of codesigning attributes that this script requires.
  _ATTRIBUTES = ['Authority', 'Identifier', 'TeamIdentifier']

  def __init__(self, codesign_output):
    self.attributes = {}

    pending_attributes = list(self._ATTRIBUTES)
    for line in codesign_output.split('\n'):
      if not pending_attributes:
        break

      for attribute in pending_attributes:
        if line.startswith(attribute):
          value = line[len(attribute) + 1:]
          self.attributes[attribute] = value
          pending_attributes.remove(attribute)
          break

    for attribute in self._ATTRIBUTES:
      if attribute not in self.attributes:
        _PrintXcodeError(
            'Failed to extract %s from %s.\n' % (attribute, codesign_output))

  def Get(self, attribute):
    """Returns the value for the given attribute, or None if it wasn't found."""
    value = self.attributes.get(attribute)
    if attribute not in self._ATTRIBUTES:
      _PrintXcodeError(
          'Attribute %s not declared to be parsed. ' % attribute +
          'Available attributes are %s.\n' % self._ATTRIBUTES)
    return value


class _OptionsParser(object):
  """Handles parsing script options."""

  # List of all supported Xcode configurations.
  KNOWN_CONFIGS = ['Debug', 'Release']

  def __init__(self, build_settings, sdk_version, platform_name, arch):
    self.targets = []
    self.build_settings = build_settings
    self.common_build_options = [
        '--verbose_failures',
        '--bes_outerr_buffer_size=0',  # Don't buffer Bazel output.
    ]

    self.sdk_version = sdk_version
    self.platform_name = platform_name

    if self.platform_name.startswith('watch'):
      config_platform = 'watchos'
    elif self.platform_name.startswith('iphone'):
      config_platform = 'ios'
    elif self.platform_name.startswith('macos'):
      config_platform = 'macos'
    elif self.platform_name.startswith('appletv'):
      config_platform = 'tvos'
    else:
      self._WarnUnknownPlatform()
      config_platform = 'ios'
    self.bazel_build_config = '{}_{}'.format(config_platform, arch)
    if self.bazel_build_config not in build_settings.platformConfigFlags:
      _PrintXcodeError('Unknown active compilation target of "{}". '
                       'Please report a Tulsi bug.'
                       .format(self.bazel_build_config))
      sys.exit(1)

    self.verbose = 0
    self.bazel_bin_path = 'bazel-bin'
    self.bazel_executable = None

  @staticmethod
  def _UsageMessage():
    """Returns a usage message string."""
    usage = textwrap.dedent("""\
      Usage: %s <target> [<target2> ...] --bazel <bazel_binary_path> [options]

      Where options are:
        --verbose [-v]
            Increments the verbosity of the script by one level. This argument
            may be provided multiple times to enable additional output levels.

        --bazel_bin_path <path>
            Path at which Bazel-generated artifacts may be retrieved.
      """ % sys.argv[0])

    return usage

  def ParseOptions(self, args):
    """Parses arguments, returning (message, exit_code)."""

    bazel_executable_index = args.index('--bazel')

    self.targets = args[:bazel_executable_index]
    if not self.targets or len(args) < bazel_executable_index + 2:
      return (self._UsageMessage(), 10)
    self.bazel_executable = args[bazel_executable_index + 1]

    return self._ParseVariableOptions(args[bazel_executable_index + 2:])

  def GetBaseFlagsForTargets(self, config):
    is_debug = config == 'Debug'
    return self.build_settings.flags_for_target(
        self.targets[0],
        is_debug,
        self.bazel_build_config)

  def GetEnabledFeatures(self):
    """Returns a list of enabled Bazel features for the active target."""
    return self.build_settings.features_for_target(self.targets[0])

  def GetBazelOptions(self, config):
    """Returns the full set of build options for the given config."""
    bazel, start_up, build = self.GetBaseFlagsForTargets(config)
    all_build = []
    all_build.extend(self.common_build_options)
    all_build.extend(build)

    xcode_version_flag = self._ComputeXcodeVersionFlag()
    if xcode_version_flag:
      all_build.append('--xcode_version=%s' % xcode_version_flag)

    return bazel, start_up, all_build

  def _WarnUnknownPlatform(self):
    _PrintUnbuffered('Warning: unknown platform "%s" will be treated as '
                     'iOS' % self.platform_name)

  def _ParseVariableOptions(self, args):
    """Parses flag-based args, returning (message, exit_code)."""

    verbose_re = re.compile('-(v+)$')

    while args:
      arg = args[0]
      args = args[1:]

      if arg == '--bazel_bin_path':
        if not args:
          return ('Missing required parameter for %s' % arg, 2)
        self.bazel_bin_path = args[0]
        args = args[1:]

      elif arg == '--verbose':
        self.verbose += 1

      else:
        match = verbose_re.match(arg)
        if match:
          self.verbose += len(match.group(1))
        else:
          return ('Unknown option "%s"\n%s' % (arg, self._UsageMessage()), 1)

    return (None, 0)

  @staticmethod
  def _GetXcodeBuildVersionString():
    """Returns Xcode build version from the environment as a string."""
    return os.environ['XCODE_PRODUCT_BUILD_VERSION']

  @staticmethod
  def _GetXcodeVersionString():
    """Returns Xcode version info from the environment as a string."""
    reported_version = os.environ['XCODE_VERSION_ACTUAL']
    match = re.match(r'(\d{2})(\d)(\d)$', reported_version)
    if not match:
      _PrintUnbuffered('Warning: Failed to extract Xcode version from %s' % (
          reported_version))
      return None
    major_version = int(match.group(1))
    minor_version = int(match.group(2))
    fix_version = int(match.group(3))
    return '%d.%d.%d' % (major_version, minor_version, fix_version)

  @staticmethod
  def _ComputeXcodeVersionFlag():
    """Returns a string for the --xcode_version build flag, if any.

    The flag should be used if the active Xcode version was not the same one
    used during project generation.

    Note this a best-attempt only; this may not be accurate as Bazel itself
    caches the active DEVELOPER_DIR path and the user may have changed their
    installed Xcode version.
    """
    xcode_version = _OptionsParser._GetXcodeVersionString()
    build_version = _OptionsParser._GetXcodeBuildVersionString()

    if not xcode_version or not build_version:
      return None

    # Of the form Major.Minor.Fix.Build (new Bazel form) or Major.Min.Fix (old).
    full_bazel_version = os.environ.get('TULSI_XCODE_VERSION')
    if not full_bazel_version:  # Unexpected: Tulsi gen didn't set the flag.
      return xcode_version

    # Newer Bazel versions specify the version as Major.Minor.Fix.Build.
    if full_bazel_version.count('.') == 3:
      components = full_bazel_version.rsplit('.', 1)
      bazel_xcode_version = components[0]
      bazel_build_version = components[1]

      if (xcode_version != bazel_xcode_version
          or build_version != bazel_build_version):
        return '{}.{}'.format(xcode_version, build_version)
      else:
        return None
    else:  # Old version of Bazel. We need to use form Major.Minor.Fix.
      return xcode_version if xcode_version != full_bazel_version else None


class BazelBuildBridge(object):
  """Handles invoking Bazel and unpacking generated binaries."""

  BUILD_EVENTS_FILE = 'build_events.json'

  def __init__(self, build_settings):
    self.build_settings = build_settings
    self.verbose = 0
    self.build_path = None
    self.bazel_bin_path = None
    self.codesign_attributes = {}

    self.codesigning_folder_path = os.environ['CODESIGNING_FOLDER_PATH']

    self.xcode_action = os.environ['ACTION']  # The Xcode build action.
    # When invoked as an external build system script, Xcode will set ACTION to
    # an empty string.
    if not self.xcode_action:
      self.xcode_action = 'build'

    if int(os.environ['XCODE_VERSION_MAJOR']) < 900:
      xcode_build_version = os.environ['XCODE_PRODUCT_BUILD_VERSION']
      _PrintXcodeWarning('Tulsi officially supports Xcode 9+. You are using an '
                         'earlier Xcode, build %s.' % xcode_build_version)

    self.tulsi_version = os.environ.get('TULSI_VERSION', 'UNKNOWN')

    # TODO(b/69857078): Remove this when wrapped_clang is updated.
    self.direct_debug_prefix_map = False
    self.normalized_prefix_map = False

    self.update_symbol_cache = UpdateSymbolCache()

    # Target architecture.  Must be defined for correct setting of
    # the --cpu flag. Note that Xcode will set multiple values in
    # ARCHS when building for a Generic Device.
    archs = os.environ.get('ARCHS')
    if not archs:
      _PrintXcodeError('Tulsi requires env variable ARCHS to be '
                       'set.  Please file a bug against Tulsi.')
      sys.exit(1)
    self.arch = archs.split()[-1]

    # Path into which generated artifacts should be copied.
    self.built_products_dir = os.environ['BUILT_PRODUCTS_DIR']
    # Path where Xcode expects generated sources to be placed.
    self.derived_sources_folder_path = os.environ.get('DERIVED_SOURCES_DIR')
    # Full name of the target artifact (e.g., "MyApp.app" or "Test.xctest").
    self.full_product_name = os.environ['FULL_PRODUCT_NAME']
    # Whether to generate runfiles for this target.
    self.gen_runfiles = os.environ.get('GENERATE_RUNFILES')
    # Target SDK version.
    self.sdk_version = os.environ.get('SDK_VERSION')
    # TEST_HOST for unit tests.
    self.test_host_binary = os.environ.get('TEST_HOST')
    # Whether this target is a test or not.
    self.is_test = os.environ.get('WRAPPER_EXTENSION') == 'xctest'
    # Target platform.
    self.platform_name = os.environ['PLATFORM_NAME']
    # Type of the target artifact.
    self.product_type = os.environ['PRODUCT_TYPE']
    # Path to the parent of the xcodeproj bundle.
    self.project_dir = os.environ['PROJECT_DIR']
    # Path to the xcodeproj bundle.
    self.project_file_path = os.environ['PROJECT_FILE_PATH']
    # Path to the directory containing the WORKSPACE file.
    self.workspace_root = os.path.abspath(os.environ['TULSI_WR'])
    # Set to the name of the generated bundle for bundle-type targets, None for
    # single file targets (like static libraries).
    self.wrapper_name = os.environ.get('WRAPPER_NAME')
    self.wrapper_suffix = os.environ.get('WRAPPER_SUFFIX', '')

    # Path where Xcode expects the artifacts to be written to. This is not the
    # codesigning_path as device vs simulator builds have different signing
    # requirements, so Xcode expects different paths to be signed. This is
    # mostly apparent on XCUITests where simulator builds set the codesigning
    # path to be the .xctest bundle, but for device builds it is actually the
    # UI runner app (since it needs to be codesigned to run on the device.) The
    # FULL_PRODUCT_NAME variable is a stable path on where to put the expected
    # artifacts. For static libraries (objc_library, swift_library),
    # FULL_PRODUCT_NAME corresponds to the .a file name, which coincides with
    # the expected location for a single artifact output.
    # TODO(b/35811023): Check these paths are still valid.
    self.artifact_output_path = os.path.join(
        os.environ['TARGET_BUILD_DIR'],
        os.environ['FULL_PRODUCT_NAME'])

    # Path to where Xcode expects the binary to be placed.
    self.binary_path = os.path.join(
        os.environ['TARGET_BUILD_DIR'], os.environ['EXECUTABLE_PATH'])

    self.is_simulator = self.platform_name.endswith('simulator')
    # Check to see if code signing actions should be skipped or not.
    if self.is_simulator:
      self.codesigning_allowed = False
    else:
      self.codesigning_allowed = os.environ.get('CODE_SIGNING_ALLOWED') == 'YES'

    if self.codesigning_allowed:
      platform_prefix = 'iOS'
      if self.platform_name.startswith('macos'):
        platform_prefix = 'macOS'
      entitlements_filename = '%sXCTRunner.entitlements' % platform_prefix
      self.runner_entitlements_template = os.path.join(self.project_file_path,
                                                       '.tulsi',
                                                       'Resources',
                                                       entitlements_filename)

    self.bazel_executable = None

  def Run(self, args):
    """Executes a Bazel build based on the environment and given arguments."""
    if self.xcode_action != 'build':
      sys.stderr.write('Xcode action is %s, ignoring.' % self.xcode_action)
      return 0

    parser = _OptionsParser(self.build_settings,
                            self.sdk_version,
                            self.platform_name,
                            self.arch)
    timer = Timer('Parsing options', 'parsing_options').Start()
    message, exit_code = parser.ParseOptions(args[1:])
    timer.End()
    if exit_code:
      _PrintXcodeError('Option parsing failed: %s' % message)
      return exit_code

    self.verbose = parser.verbose
    self.bazel_bin_path = os.path.abspath(parser.bazel_bin_path)
    self.bazel_executable = parser.bazel_executable
    self.bazel_exec_root = self.build_settings.bazelExecRoot

    # Update feature flags.
    features = parser.GetEnabledFeatures()
    self.direct_debug_prefix_map = 'DirectDebugPrefixMap' in features
    self.normalized_prefix_map = 'DebugPathNormalization' in features

    self.build_path = os.path.join(self.bazel_bin_path,
                                   os.environ.get('TULSI_BUILD_PATH', ''))

    # Path to the Build Events JSON file uses pid and is removed if the
    # build is successful.
    filename = '%d_%s' % (os.getpid(), BazelBuildBridge.BUILD_EVENTS_FILE)
    self.build_events_file_path = os.path.join(
        self.project_file_path,
        '.tulsi',
        filename)

    (command, retval) = self._BuildBazelCommand(parser)
    if retval:
      return retval

    timer = Timer('Running Bazel', 'running_bazel').Start()
    exit_code, outputs = self._RunBazelAndPatchOutput(command)
    timer.End()
    if exit_code:
      _Fatal('Bazel build failed with exit code %d. Please check the build '
             'log in Report Navigator (⌘9) for more information.'
             % exit_code)
      return exit_code

    post_bazel_timer = Timer('Total Tulsi Post-Bazel time', 'total_post_bazel')
    post_bazel_timer.Start()

    if not os.path.exists(self.bazel_exec_root):
      _Fatal('No Bazel execution root was found at %r. Debugging experience '
             'will be compromised. Please report a Tulsi bug.'
             % self.bazel_exec_root)
      return 404

    # This needs to run after `bazel build`, since it depends on the Bazel
    # workspace directory
    exit_code = self._LinkTulsiWorkspace()
    if exit_code:
      return exit_code

    exit_code, outputs_data = self._ExtractAspectOutputsData(outputs)
    if exit_code:
      return exit_code

    # Generated headers are installed on a thread since we are launching
    # a separate process to do so. This gives us clean timings.
    install_thread = threading.Thread(
        target=self._InstallGeneratedHeaders, args=(outputs,))
    install_thread.start()
    timer = Timer('Installing artifacts', 'installing_artifacts').Start()
    exit_code = self._InstallArtifact(outputs_data)
    timer.End()
    install_thread.join()
    if exit_code:
      return exit_code

    exit_code, dsym_paths = self._InstallDSYMBundles(
        self.built_products_dir, outputs_data)
    if exit_code:
      return exit_code

    if not dsym_paths:
      # Clean any bundles from a previous build that can interfere with
      # debugging in LLDB.
      self._CleanExistingDSYMs()
    else:
      for path in dsym_paths:
        # Starting with Xcode 9.x, a plist based remapping exists for dSYM
        # bundles that works with Swift as well as (Obj-)C(++).
        #
        # This solution also works for Xcode 8.x for (Obj-)C(++) but not
        # for Swift.
        timer = Timer('Adding remappings as plists to dSYM',
                      'plist_dsym').Start()
        exit_code = self._PlistdSYMPaths(path)
        timer.End()
        if exit_code:
          _PrintXcodeError('Remapping dSYMs process returned %i, please '
                           'report a Tulsi bug and attach a full Xcode '
                           'build log.' % exit_code)
          return exit_code

    # Starting with Xcode 7.3, XCTests inject several supporting frameworks
    # into the test host that need to be signed with the same identity as
    # the host itself.
    if (self.is_test and not self.platform_name.startswith('macos') and
        self.codesigning_allowed):
      exit_code = self._ResignTestArtifacts()
      if exit_code:
        return exit_code

    # Starting with Xcode 8, .lldbinit files are honored during Xcode debugging
    # sessions. This allows use of the target.source-map field to remap the
    # debug symbol paths encoded in the binary to the paths expected by Xcode.
    #
    # This will not work with dSYM bundles, or a direct -fdebug-prefix-map from
    # the Bazel-built locations to Xcode-visible sources.
    timer = Timer('Updating .lldbinit', 'updating_lldbinit').Start()
    clear_source_map = dsym_paths or self.direct_debug_prefix_map
    exit_code = self._UpdateLLDBInit(clear_source_map)
    timer.End()
    if exit_code:
      _PrintXcodeWarning('Updating .lldbinit action failed with code %d' %
                         exit_code)

    post_bazel_timer.End(log_absolute_times=True)

    return 0

  def _BuildBazelCommand(self, options):
    """Builds up a commandline string suitable for running Bazel."""
    configuration = os.environ['CONFIGURATION']
    # Treat the special testrunner build config as a Debug compile.
    test_runner_config_prefix = '__TulsiTestRunner_'
    if configuration.startswith(test_runner_config_prefix):
      configuration = configuration[len(test_runner_config_prefix):]
    elif os.environ.get('TULSI_TEST_RUNNER_ONLY') == 'YES':
      _PrintXcodeError('Building test targets with configuration "%s" is not '
                       'allowed. Please use the "Test" action or "Build for" > '
                       '"Testing" instead.' % configuration)
      return (None, 1)

    if configuration not in _OptionsParser.KNOWN_CONFIGS:
      _PrintXcodeError('Unknown build configuration "%s"' % configuration)
      return (None, 1)

    bazel, start_up, build = options.GetBazelOptions(configuration)
    bazel_command = [bazel]
    bazel_command.extend(start_up)
    bazel_command.append('build')
    bazel_command.extend(build)

    bazel_command.extend([
        # The following flags are used by Tulsi to identify itself and read
        # build information from Bazel. They shold not affect Bazel anaylsis
        # caching.
        '--tool_tag=tulsi:bazel_build',
        '--build_event_json_file=%s' % self.build_events_file_path,
        '--noexperimental_build_event_json_file_path_conversion',
        '--aspects', '@tulsi//:tulsi/tulsi_aspects.bzl%tulsi_outputs_aspect'])

    if self.is_test and self.gen_runfiles:
      bazel_command.append('--output_groups=+tulsi_outputs')
    else:
      bazel_command.append('--output_groups=tulsi_outputs,default')

    bazel_command.extend(options.targets)

    extra_options = bazel_options.BazelOptions(os.environ)
    bazel_command.extend(extra_options.bazel_feature_flags())

    return (bazel_command, 0)

  def _RunBazelAndPatchOutput(self, command):
    """Runs subprocess command, patching output as it's received."""
    self._PrintVerbose('Running "%s", patching output for workspace root at '
                       '"%s" with project path at "%s".' %
                       (' '.join([pipes.quote(x) for x in command]),
                        self.workspace_root,
                        self.project_dir))
    # Xcode translates anything that looks like ""<path>:<line>:" that is not
    # followed by the word "warning" into an error. Bazel warnings and debug
    # messages do not fit this scheme and must be patched here.
    bazel_warning_line_regex = re.compile(
        r'(?:DEBUG|WARNING): ([^:]+:\d+:(?:\d+:)?)\s+(.+)')

    def PatchBazelWarningStatements(output_line):
      match = bazel_warning_line_regex.match(output_line)
      if match:
        output_line = '%s warning: %s' % (match.group(1), match.group(2))
      return output_line

    patch_xcode_parsable_line = PatchBazelWarningStatements
    if self.workspace_root != self.project_dir:
      # Match (likely) filename:line_number: lines.
      xcode_parsable_line_regex = re.compile(r'([^/][^:]+):\d+:')

      def PatchOutputLine(output_line):
        output_line = PatchBazelWarningStatements(output_line)
        if xcode_parsable_line_regex.match(output_line):
          output_line = '%s/%s' % (self.workspace_root, output_line)
        return output_line
      patch_xcode_parsable_line = PatchOutputLine

    def HandleOutput(output):
      for line in output.splitlines():
        _logger.log_bazel_message(patch_xcode_parsable_line(line))

    def WatcherUpdate(watcher):
      """Processes any new events in the given watcher.

      Args:
        watcher: a BazelBuildEventsWatcher object.

      Returns:
        A list of new tulsiout file names seen.
      """
      new_events = watcher.check_for_new_events()
      new_outputs = []
      for build_event in new_events:
        if build_event.stderr:
          HandleOutput(build_event.stderr)
        if build_event.stdout:
          HandleOutput(build_event.stdout)
        if build_event.files:
          outputs = [x for x in build_event.files if x.endswith('.tulsiouts')]
          new_outputs.extend(outputs)
      return new_outputs

    def ReaderThread(file_handle, out_buffer):
      out_buffer.append(file_handle.read())
      file_handle.close()

    # Make sure the BEP JSON file exists and is empty. We do this to prevent
    # any sort of race between the watcher, bazel, and the old file contents.
    open(self.build_events_file_path, 'w').close()

    # Capture the stderr and stdout from Bazel. We only display it if it we're
    # unable to read any BEP events.
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT,
                               bufsize=1)

    # Register atexit function to clean up BEP file.
    atexit.register(_BEPFileExitCleanup, self.build_events_file_path)
    global CLEANUP_BEP_FILE_AT_EXIT
    CLEANUP_BEP_FILE_AT_EXIT = True

    # Start capturing output from Bazel.
    reader_buffer = []
    reader_thread = threading.Thread(target=ReaderThread,
                                     args=(process.stdout, reader_buffer))
    reader_thread.daemon = True
    reader_thread.start()

    with io.open(self.build_events_file_path, 'r', -1, 'utf-8', 'ignore'
                ) as bep_file:
      watcher = bazel_build_events.BazelBuildEventsWatcher(bep_file,
                                                           _PrintXcodeWarning)
      output_locations = []
      while process.returncode is None:
        output_locations.extend(WatcherUpdate(watcher))
        time.sleep(0.1)
        process.poll()

      output_locations.extend(WatcherUpdate(watcher))

      # If BEP JSON parsing failed, we should display the raw stdout and
      # stderr from Bazel.
      reader_thread.join()
      if not watcher.has_read_events():
        HandleOutput(reader_buffer[0])

      if process.returncode == 0 and not output_locations:
        CLEANUP_BEP_FILE_AT_EXIT = False
        _PrintXcodeError('Unable to find location of the .tulsiouts file.'
                         'Please report this as a Tulsi bug, including the'
                         'contents of %s.' % self.build_events_file_path)
        return 1, output_locations
      return process.returncode, output_locations

  def _ExtractAspectOutputsData(self, output_files):
    """Converts aspect output from paths to json to a list of dictionaries.

    Args:
      output_files: A list of strings to files representing Bazel aspect output
                    in UTF-8 JSON format.

    Returns:
      return_code, [dict]: A tuple with a return code as its first argument and
                           for its second argument, a list of dictionaries for
                           each output_file that could be interpreted as valid
                           JSON, representing the returned Bazel aspect
                           information.
      return_code, None: If an error occurred while converting the list of
                         files into JSON.
    """
    outputs_data = []
    for output_file in output_files:
      try:
        output_data = json.load(open(output_file))
      except (ValueError, IOError) as e:
        _PrintXcodeError('Failed to load output map ""%s". '
                         '%s' % (output_file, e))
        return 600, None
      outputs_data.append(output_data)
    return 0, outputs_data

  def _InstallArtifact(self, outputs_data):
    """Installs Bazel-generated artifacts into the Xcode output directory."""
    xcode_artifact_path = self.artifact_output_path

    if not outputs_data:
      _PrintXcodeError('Failed to load top level output file.')
      return 600

    primary_output_data = outputs_data[0]

    if 'artifact' not in primary_output_data:
      _PrintXcodeError(
          'Failed to find an output artifact for target %s in output map %r' %
          (xcode_artifact_path, primary_output_data))
      return 601

    primary_artifact = primary_output_data['artifact']
    artifact_archive_root = primary_output_data.get('archive_root')
    bundle_name = primary_output_data.get('bundle_name')

    # The PRODUCT_NAME used by the Xcode project is not trustable as it may be
    # modified by the user and, more importantly, may have been modified by
    # Tulsi to disambiguate multiple targets with the same name.
    self.bazel_product_name = bundle_name

    # We need to handle IPAs (from {ios, tvos}_application) differently from
    # ZIPs (from the other bundled rules) because they output slightly different
    # directory structures.
    is_ipa = primary_artifact.endswith('.ipa')
    is_zip = primary_artifact.endswith('.zip')

    if is_ipa or is_zip:
      expected_bundle_name = bundle_name + self.wrapper_suffix

      # The directory structure within the IPA is then determined based on
      # Bazel's package and/or product type.
      if is_ipa:
        bundle_subpath = os.path.join('Payload', expected_bundle_name)
      else:
        # If the artifact is a ZIP, assume that the bundle is the top-level
        # directory (this is the way in which Skylark rules package artifacts
        # that are not standalone IPAs).
        bundle_subpath = expected_bundle_name

      # Prefer to copy over files from the archive root instead of unzipping the
      # ipa/zip in order to help preserve timestamps. Note that the archive root
      # is only present for local builds; for remote builds we must extract from
      # the zip file.
      if self._IsValidArtifactArchiveRoot(artifact_archive_root, bundle_name):
        source_location = os.path.join(artifact_archive_root, bundle_subpath)
        exit_code = self._RsyncBundle(os.path.basename(primary_artifact),
                                      source_location,
                                      xcode_artifact_path)
      else:
        exit_code = self._UnpackTarget(primary_artifact,
                                       xcode_artifact_path,
                                       bundle_subpath)
      if exit_code:
        return exit_code

    elif os.path.isfile(primary_artifact):
      # Remove the old artifact before copying.
      if os.path.isfile(xcode_artifact_path):
        try:
          os.remove(xcode_artifact_path)
        except OSError as e:
          _PrintXcodeError('Failed to remove stale output file ""%s". '
                           '%s' % (xcode_artifact_path, e))
          return 600
      exit_code = self._CopyFile(os.path.basename(primary_artifact),
                                 primary_artifact,
                                 xcode_artifact_path)
      if exit_code:
        return exit_code
    else:
      self._RsyncBundle(os.path.basename(primary_artifact),
                        primary_artifact,
                        xcode_artifact_path)

      # When the rules output a tree artifact, Tulsi will copy the bundle as is
      # into the expected Xcode output location. But because they're copied as
      # is from the bazel output, they come with bazel's permissions, which are
      # read only. Here we set them to write as well, so Xcode can modify the
      # bundle too (for example, for codesigning).
      chmod_timer = Timer('Modifying permissions of output bundle',
                          'bundle_chmod').Start()

      self._PrintVerbose('Spawning subprocess to add write permissions to '
                         'copied bundle...')
      process = subprocess.Popen(['chmod', '-R', 'uga+w', xcode_artifact_path])
      process.wait()
      chmod_timer.End()

    # No return code check as this is not an essential operation.
    self._InstallEmbeddedBundlesIfNecessary(primary_output_data)

    return 0

  def _IsValidArtifactArchiveRoot(self, archive_root, bundle_name):
    """Returns true if the archive root is valid for use."""
    if not archive_root or not os.path.isdir(archive_root):
      return False

    # The archive root will not be updated for any remote builds, but will be
    # valid for local builds. We detect this by using an implementation detail
    # of the rules_apple bundler: archives will always be transformed from
    # <name>.unprocessed.zip (locally or remotely) to <name>.archive-root.
    #
    # Thus if the mod time on the archive root is not greater than the mod
    # time on the on the zip, the archive root is not valid. Remote builds
    # will end up copying the <name>.unprocessed.zip but not the
    # <name>.archive-root, making this a valid temporary solution.
    #
    # In the future, it would be better to have this handled by the rules;
    # until then this should suffice as a work around to improve build times.
    unprocessed_zip = os.path.join(os.path.dirname(archive_root),
                                   '%s.unprocessed.zip' % bundle_name)
    if not os.path.isfile(unprocessed_zip):
      return False
    return os.path.getmtime(archive_root) > os.path.getmtime(unprocessed_zip)

  def _InstallEmbeddedBundlesIfNecessary(self, output_data):
    """Install embedded bundles next to the current target's output."""

    # In order to find and load symbols for the binary installed on device,
    # Instruments needs to "see" it in Spotlight index somewhere on the local
    # filesystem. This is only needed for on-device instrumentation.
    #
    # Unfortunatelly, it does not seem to be possible to detect when a build is
    # being made for profiling, thus we can't exclude this step for on-device
    # non-profiling builds.

    if self.is_simulator or ('embedded_bundles' not in output_data):
      return

    timer = Timer('Installing embedded bundles',
                  'installing_embedded_bundles').Start()

    for bundle_info in output_data['embedded_bundles']:
      bundle_name = bundle_info['bundle_name']
      bundle_extension = bundle_info['bundle_extension']
      full_name = bundle_name + bundle_extension
      output_path = os.path.join(self.built_products_dir, full_name)
      # TODO(b/68936732): See if copying just the binary (not the whole bundle)
      # is enough to make Instruments work.
      if self._IsValidArtifactArchiveRoot(bundle_info['archive_root'],
                                          bundle_name):
        source_path = os.path.join(bundle_info['archive_root'], full_name)
        self._RsyncBundle(full_name, source_path, output_path)
      else:
        # Try to find the embedded bundle within the installed main bundle.
        bundle_path = self._FindEmbeddedBundleInMain(bundle_name,
                                                     bundle_extension)
        if bundle_path:
          self._RsyncBundle(full_name, bundle_path, output_path)
        else:
          _PrintXcodeWarning('Could not find bundle %s in main bundle. ' %
                             (bundle_name + bundle_extension) +
                             'Device-level Instruments debugging will be '
                             'disabled for this bundle. Please report a '
                             'Tulsi bug and attach a full Xcode build log.')

    timer.End()

  # Maps extensions to anticipated subfolders.
  _EMBEDDED_BUNDLE_PATHS = {
      '.appex': 'PlugIns',
      '.framework': 'Frameworks'
  }

  def _FindEmbeddedBundleInMain(self, bundle_name, bundle_extension):
    """Retrieves the first embedded bundle found within our main bundle."""
    main_bundle = os.environ.get('EXECUTABLE_FOLDER_PATH')

    if not main_bundle:
      return None

    main_bundle_path = os.path.join(self.built_products_dir,
                                    main_bundle)

    return self._FindEmbeddedBundle(bundle_name,
                                    bundle_extension,
                                    main_bundle_path)

  def _FindEmbeddedBundle(self, bundle_name, bundle_extension, bundle_path):
    """Retrieves the first embedded bundle found within this bundle path."""
    embedded_subfolder = self._EMBEDDED_BUNDLE_PATHS.get(bundle_extension)

    if not embedded_subfolder:
      return None

    projected_bundle_path = os.path.join(bundle_path,
                                         embedded_subfolder,
                                         bundle_name + bundle_extension)

    if os.path.isdir(projected_bundle_path):
      return projected_bundle_path

    # For frameworks not in the main app bundle, and possibly other executable
    # bundle content in the future, we recurse through every .appex in PlugIns
    # to find those frameworks.
    #
    # This won't support frameworks that could potentially have the same name
    # but are different between the app and extensions, but we intentionally
    # choose not to handle that case. Xcode build system only supports
    # uniquely named frameworks, and we shouldn't confuse the dynamic loader
    # with frameworks that have the same image names but different content.
    appex_root_path = os.path.join(bundle_path, 'PlugIns')
    if not os.path.isdir(appex_root_path):
      return None

    # Find each directory within appex_root_path and attempt to find a bundle.
    # If one can't be found, return None.
    appex_dirs = os.listdir(appex_root_path)
    for appex_dir in appex_dirs:
      appex_path = os.path.join(appex_root_path, appex_dir)
      path = self._FindEmbeddedBundle(bundle_name,
                                      bundle_extension,
                                      appex_path)
      if path:
        return path
    return None

  def _InstallGeneratedHeaders(self, outputs):
    """Invokes install_genfiles.py to install generated Bazel files."""
    genfiles_timer = Timer('Installing generated headers',
                           'installing_generated_headers').Start()
    # Resolve the path to the install_genfiles.py script.
    # It should be in the same directory as this script.
    path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                        'install_genfiles.py')

    args = [path, self.bazel_exec_root]
    args.extend(outputs)

    self._PrintVerbose('Spawning subprocess install_genfiles.py to copy '
                       'generated files in the background...')
    process = subprocess.Popen(args)
    process.wait()
    genfiles_timer.End()

  def _InstallBundle(self, source_path, output_path):
    """Copies the bundle at source_path to output_path."""
    if not os.path.isdir(source_path):
      return 0, None

    if os.path.isdir(output_path):
      try:
        shutil.rmtree(output_path)
      except OSError as e:
        _PrintXcodeError('Failed to remove stale bundle ""%s". '
                         '%s' % (output_path, e))
        return 700, None

    exit_code = self._CopyBundle(os.path.basename(source_path),
                                 source_path,
                                 output_path)
    return exit_code, output_path

  def _RsyncBundle(self, source_path, full_source_path, output_path):
    """Rsyncs the given bundle to the given expected output path."""
    self._PrintVerbose('Rsyncing %s to %s' % (source_path, output_path))

    # rsync behavior changes based on presence of a trailing slash.
    if not full_source_path.endswith('/'):
      full_source_path += '/'

    try:
      # Use -c to check differences by checksum, -v for verbose,
      # and --delete to delete stale files.
      # The rest of the flags are the same as -a but without preserving
      # timestamps, which is done intentionally so the timestamp will
      # only change when the file is changed.
      subprocess.check_output(['rsync',
                               '-vcrlpgoD',
                               '--delete',
                               full_source_path,
                               output_path],
                              stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
      _PrintXcodeError('Rsync failed. %s' % e)
      return 650
    return 0

  def _CopyBundle(self, source_path, full_source_path, output_path):
    """Copies the given bundle to the given expected output path."""
    self._PrintVerbose('Copying %s to %s' % (source_path, output_path))
    try:
      CopyOnWrite(full_source_path, output_path, tree=True)
    except OSError as e:
      _PrintXcodeError('Copy failed. %s' % e)
      return 650
    return 0

  def _CopyFile(self, source_path, full_source_path, output_path):
    """Copies the given file to the given expected output path."""
    self._PrintVerbose('Copying %s to %s' % (source_path, output_path))
    output_path_dir = os.path.dirname(output_path)
    if not os.path.exists(output_path_dir):
      try:
        os.makedirs(output_path_dir)
      except OSError as e:
        _PrintXcodeError('Failed to create output directory "%s". '
                         '%s' % (output_path_dir, e))
        return 650
    try:
      CopyOnWrite(full_source_path, output_path)
    except OSError as e:
      _PrintXcodeError('Copy failed. %s' % e)
      return 650
    return 0

  def _UnpackTarget(self, bundle_path, output_path, bundle_subpath):
    """Unpacks generated bundle into the given expected output path."""
    self._PrintVerbose('Unpacking %s to %s' % (bundle_path, output_path))

    if not os.path.isfile(bundle_path):
      _PrintXcodeError('Generated bundle not found at "%s"' % bundle_path)
      return 670

    if os.path.isdir(output_path):
      try:
        shutil.rmtree(output_path)
      except OSError as e:
        _PrintXcodeError('Failed to remove stale output directory ""%s". '
                         '%s' % (output_path, e))
        return 600

    # We need to handle IPAs (from {ios, tvos}_application) differently from
    # ZIPs (from the other bundled rules) because they output slightly different
    # directory structures.
    is_ipa = bundle_path.endswith('.ipa')

    with zipfile.ZipFile(bundle_path, 'r') as zf:
      for item in zf.infolist():
        filename = item.filename

        # Support directories do not seem to be needed by the debugger and are
        # skipped.
        basedir = filename.split(os.sep)[0]
        if basedir.endswith('Support') or basedir.endswith('Support2'):
          continue

        if len(filename) < len(bundle_subpath):
          continue

        attributes = (item.external_attr >> 16) & 0o777
        self._PrintVerbose('Extracting %s (%o)' % (filename, attributes),
                           level=1)

        if not filename.startswith(bundle_subpath):
          _PrintXcodeWarning('Mismatched extraction path. Bundle content '
                             'at "%s" expected to have subpath of "%s"' %
                             (filename, bundle_subpath))

        dir_components = self._SplitPathComponents(filename)

        # Get the file's path, ignoring the payload components if the archive
        # is an IPA.
        if is_ipa:
          subpath = os.path.join(*dir_components[2:])
        else:
          subpath = os.path.join(*dir_components[1:])
        target_path = os.path.join(output_path, subpath)

        # Ensure the target directory exists.
        try:
          target_dir = os.path.dirname(target_path)
          if not os.path.isdir(target_dir):
            os.makedirs(target_dir)
        except OSError as e:
          _PrintXcodeError(
              'Failed to create target path "%s" during extraction. %s' % (
                  target_path, e))
          return 671

        # If the archive item looks like a file, extract it.
        if not filename.endswith(os.sep):
          with zf.open(item) as src, file(target_path, 'wb') as dst:
            shutil.copyfileobj(src, dst)

        # Patch up the extracted file's attributes to match the zip content.
        if attributes:
          os.chmod(target_path, attributes)

    return 0

  def _InstallDSYMBundles(self, output_dir, outputs_data):
    """Copies any generated dSYM bundles to the given directory."""
    # Indicates that our aspect reports a dSYM was generated for this build.
    has_dsym = outputs_data[0]['has_dsym']

    if not has_dsym:
      return 0, None

    # Start the timer now that we know we have dSYM bundles to install.
    timer = Timer('Installing DSYM bundles', 'installing_dsym').Start()

    # Declares the Xcode-generated name of our main target's dSYM.
    # This environment variable is always set, for any possible Xcode output
    # that could generate a dSYM bundle.
    target_dsym = os.environ.get('DWARF_DSYM_FILE_NAME')
    if target_dsym:
      dsym_to_process = set([(self.build_path, target_dsym)])

    # Collect additional dSYM bundles generated by the dependencies of this
    # build such as extensions or frameworks.
    child_dsyms = set()
    for data in outputs_data:
      for bundle_info in data.get('embedded_bundles', []):
        if not bundle_info['has_dsym']:
          continue
        # Uses the parent of archive_root to find dSYM bundles associated with
        # app/extension/df bundles. Currently hinges on implementation of the
        # build rules.
        dsym_path = os.path.dirname(bundle_info['archive_root'])
        bundle_full_name = (bundle_info['bundle_name'] +
                            bundle_info['bundle_extension'])
        dsym_filename = '%s.dSYM' % bundle_full_name
        child_dsyms.add((dsym_path, dsym_filename))
    dsym_to_process.update(child_dsyms)

    dsyms_found = []
    for dsym_path, dsym_filename in dsym_to_process:
      input_dsym_full_path = os.path.join(dsym_path, dsym_filename)
      output_full_path = os.path.join(output_dir, dsym_filename)
      exit_code, path = self._InstallBundle(input_dsym_full_path,
                                            output_full_path)
      if exit_code:
        _PrintXcodeWarning('Failed to install dSYM "%s" (%s)'
                           % (dsym_filename, exit_code))
      elif path is None:
        _PrintXcodeWarning('Could not find a dSYM bundle named "%s"'
                           % dsym_filename)
      else:
        dsyms_found.append(path)

    timer.End()
    return 0, dsyms_found

  def _ResignBundle(self, bundle_path, signing_identity, entitlements=None):
    """Re-signs the bundle with the given signing identity and entitlements."""
    if not self.codesigning_allowed:
      return 0

    timer = Timer('\tSigning ' + bundle_path, 'signing_bundle').Start()
    command = [
        'xcrun',
        'codesign',
        '-f',
        '--timestamp=none',
        '-s',
        signing_identity,
    ]

    if entitlements:
      command.extend(['--entitlements', entitlements])
    else:
      command.append('--preserve-metadata=entitlements')

    command.append(bundle_path)

    returncode, output = self._RunSubprocess(command)
    timer.End()
    if returncode:
      _PrintXcodeError('Re-sign command %r failed. %s' % (command, output))
      return 800 + returncode
    return 0

  def _ResignTestArtifacts(self):
    """Resign test related artifacts that Xcode injected into the outputs."""
    if not self.is_test:
      return 0
    # Extract the signing identity from the bundle at the expected output path
    # since that's where the signed bundle from bazel was placed.
    signing_identity = self._ExtractSigningIdentity(self.artifact_output_path)
    if not signing_identity:
      return 800

    exit_code = 0
    timer = Timer('Re-signing injected test host artifacts',
                  'resigning_test_host').Start()

    if self.test_host_binary:
      # For Unit tests, we need to resign the frameworks that Xcode injected
      # into the test host bundle.
      test_host_bundle = os.path.dirname(self.test_host_binary)
      exit_code = self._ResignXcodeTestFrameworks(
          test_host_bundle, signing_identity)
    else:
      # For UI tests, we need to resign the UI test runner app and the
      # frameworks that Xcode injected into the runner app. The UI Runner app
      # also needs to be signed with entitlements.
      exit_code = self._ResignXcodeTestFrameworks(
          self.codesigning_folder_path, signing_identity)
      if exit_code == 0:
        entitlements_path = self._InstantiateUIRunnerEntitlements()
        if entitlements_path:
          exit_code = self._ResignBundle(
              self.codesigning_folder_path,
              signing_identity,
              entitlements_path)
        else:
          _PrintXcodeError('Could not instantiate UI runner entitlements.')
          exit_code = 800

    timer.End()
    return exit_code

  def _ResignXcodeTestFrameworks(self, bundle, signing_identity):
    """Re-signs the support frameworks injected by Xcode in the given bundle."""
    if not self.codesigning_allowed:
      return 0

    for framework in XCODE_INJECTED_FRAMEWORKS:
      framework_path = os.path.join(
          bundle, 'Frameworks', framework)
      if os.path.isdir(framework_path) or os.path.isfile(framework_path):
        exit_code = self._ResignBundle(framework_path, signing_identity)
        if exit_code != 0:
          return exit_code
    return 0

  def _InstantiateUIRunnerEntitlements(self):
    """Substitute team and bundle identifiers into UI runner entitlements.

    This method throws an IOError exception if the template wasn't found in
    its expected location, or an OSError if the expected output folder could
    not be created.

    Returns:
      The path to where the entitlements file was generated.
    """
    if not self.codesigning_allowed:
      return None
    if not os.path.exists(self.derived_sources_folder_path):
      os.makedirs(self.derived_sources_folder_path)

    output_file = os.path.join(
        self.derived_sources_folder_path,
        self.bazel_product_name + '_UIRunner.entitlements')
    if os.path.exists(output_file):
      os.remove(output_file)

    with open(self.runner_entitlements_template, 'r') as template:
      contents = template.read()
      contents = contents.replace(
          '$(TeamIdentifier)',
          self._ExtractSigningTeamIdentifier(self.artifact_output_path))
      contents = contents.replace(
          '$(BundleIdentifier)',
          self._ExtractSigningBundleIdentifier(self.artifact_output_path))
      with open(output_file, 'w') as output:
        output.write(contents)
    return output_file

  def _ExtractSigningIdentity(self, signed_bundle):
    """Returns the identity used to sign the given bundle path."""
    return self._ExtractSigningAttribute(signed_bundle, 'Authority')

  def _ExtractSigningTeamIdentifier(self, signed_bundle):
    """Returns the team identifier used to sign the given bundle path."""
    return self._ExtractSigningAttribute(signed_bundle, 'TeamIdentifier')

  def _ExtractSigningBundleIdentifier(self, signed_bundle):
    """Returns the bundle identifier used to sign the given bundle path."""
    return self._ExtractSigningAttribute(signed_bundle, 'Identifier')

  def _ExtractSigningAttribute(self, signed_bundle, attribute):
    """Returns the attribute used to sign the given bundle path."""
    if not self.codesigning_allowed:
      return '<CODE_SIGNING_ALLOWED=NO>'

    cached = self.codesign_attributes.get(signed_bundle)
    if cached:
      return cached.Get(attribute)

    timer = Timer('\tExtracting signature for ' + signed_bundle,
                  'extracting_signature').Start()
    output = subprocess.check_output(['xcrun',
                                      'codesign',
                                      '-dvv',
                                      signed_bundle],
                                     stderr=subprocess.STDOUT)
    timer.End()

    bundle_attributes = CodesignBundleAttributes(output)
    self.codesign_attributes[signed_bundle] = bundle_attributes
    return bundle_attributes.Get(attribute)

  def _UpdateLLDBInit(self, clear_source_map=False):
    """Updates ~/.lldbinit-tulsiproj to enable debugging of Bazel binaries."""

    # Make sure a reference to ~/.lldbinit-tulsiproj exists in ~/.lldbinit or
    # ~/.lldbinit-Xcode. Priority is given to ~/.lldbinit-Xcode if it exists,
    # otherwise the bootstrapping will be written to ~/.lldbinit.
    BootstrapLLDBInit()

    with open(TULSI_LLDBINIT_FILE, 'w') as out:
      out.write('# This file is autogenerated by Tulsi and should not be '
                'edited.\n')

      if clear_source_map:
        out.write('settings clear target.source-map\n')
        return 0

      if self.normalized_prefix_map:
        source_map = ('./', self._NormalizePath(self.workspace_root))
        out.write('# This maps the normalized root to that used by '
                  '%r.\n' % os.path.basename(self.project_file_path))
      else:
        # NOTE: settings target.source-map is different from
        # DBGSourcePathRemapping; the former is an LLDB target-level
        # remapping API that rewrites breakpoints, the latter is an LLDB
        # module-level remapping API that changes DWARF debug info in memory.
        #
        # If we had multiple remappings, it would not make sense for the
        # two APIs to share the same mappings. They have very different
        # side-effects in how they individually handle debug information.
        source_map = self._ExtractTargetSourceMap()
        out.write('# This maps Bazel\'s execution root to that used by '
                  '%r.\n' % os.path.basename(self.project_file_path))

      out.write('settings set target.source-map "%s" "%s"\n' % source_map)

    return 0

  def _DWARFdSYMBinaries(self, dsym_bundle_path):
    """Returns an array of abs paths to DWARF binaries in the dSYM bundle.

    Args:
      dsym_bundle_path: absolute path to the dSYM bundle.

    Returns:
      str[]: a list of strings representing the absolute paths to each binary
             found within the dSYM bundle.
    """
    dwarf_dir = os.path.join(dsym_bundle_path,
                             'Contents',
                             'Resources',
                             'DWARF')

    dsym_binaries = []

    for f in os.listdir(dwarf_dir):
      # Ignore hidden files, such as .DS_Store files.
      if not f.startswith('.'):
        # Append full path info.
        dsym_binary = os.path.join(dwarf_dir, f)
        dsym_binaries.append(dsym_binary)

    return dsym_binaries

  def _UUIDInfoForBinary(self, source_binary_path):
    """Returns exit code of dwarfdump along with every UUID + arch found.

    Args:
      source_binary_path: absolute path to the binary file.

    Returns:
      (Int, str[(str, str)]): a tuple containing the return code of dwarfdump
                              as its first element, and a list of strings
                              representing each UUID found for each given
                              binary slice found within the binary with its
                              given architecture, if no error has occcured.
    """

    returncode, output = self._RunSubprocess([
        'xcrun',
        'dwarfdump',
        '--uuid',
        source_binary_path
    ])
    if returncode:
      _PrintXcodeWarning('dwarfdump returned %d while finding the UUID for %s'
                         % (returncode, source_binary_path))
      return (returncode, [])

    # All UUIDs for binary slices will be returned as the second from left,
    # from output; "UUID: D4DE5AA2-79EE-36FE-980C-755AED318308 (x86_64)
    # /Applications/Calendar.app/Contents/MacOS/Calendar"

    uuids_found = []
    for dwarfdump_output in output.split('\n'):
      if not dwarfdump_output:
        continue
      found_output = re.match(r'^(?:UUID: )([^ ]+) \(([^)]+)', dwarfdump_output)
      if not found_output:
        continue
      found_uuid = found_output.group(1)
      if not found_uuid:
        continue
      found_arch = found_output.group(2)
      if not found_arch:
        continue
      uuids_found.append((found_uuid, found_arch))

    return (0, uuids_found)

  def _CreateUUIDPlist(self, dsym_bundle_path, uuid, arch, source_maps):
    """Creates a UUID.plist in a dSYM bundle to redirect sources.

    Args:
      dsym_bundle_path: absolute path to the dSYM bundle.
      uuid: string representing the UUID of the binary slice with paths to
            remap in the dSYM bundle.
      arch: the architecture of the binary slice.
      source_maps:  list of tuples representing all absolute paths to source
                    files compiled by Bazel as strings ($0) associated with the
                    paths to Xcode-visible sources used for the purposes of
                    Tulsi debugging as strings ($1).

    Returns:
      Bool: True if no error was found, or False, representing a failure to
            write when creating the plist.
    """

    # Create a UUID plist at (dsym_bundle_path)/Contents/Resources/.
    remap_plist = os.path.join(dsym_bundle_path,
                               'Contents',
                               'Resources',
                               '%s.plist' % uuid)

    # Via an XML plist, add the mappings from  _ExtractTargetSourceMap().
    try:
      with open(remap_plist, 'w') as out:
        out.write('<?xml version="1.0" encoding="UTF-8"?>\n'
                  '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" '
                  '"http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
                  '<plist version="1.0">\n'
                  '<dict>\n'
                  '<key>DBGSourcePathRemapping</key>\n'
                  '<dict>\n')
        for source_map in source_maps:
          # Add the mapping as a DBGSourcePathRemapping to the UUID plist here.
          out.write('<key>%s</key>\n<string>%s</string>\n' % source_map)

        # Make sure that we also set DBGVersion to 3.
        out.write('</dict>\n'
                  '<key>DBGVersion</key>\n'
                  '<string>3</string>\n'
                  '</dict>\n'
                  '</plist>\n')
    except OSError as e:
      _PrintXcodeError('Failed to write %s, received error %s' %
                       (remap_plist, e))
      return False

    # Update the dSYM symbol cache with a reference to this dSYM bundle.
    err_msg = self.update_symbol_cache.UpdateUUID(uuid,
                                                  dsym_bundle_path,
                                                  arch)
    if err_msg:
      _PrintXcodeWarning('Attempted to save (uuid, dsym_bundle_path, arch) '
                         'to DBGShellCommands\' dSYM cache, but got error '
                         '\"%s\".' % err_msg)

    return True

  def _CleanExistingDSYMs(self):
    """Clean dSYM bundles that were left over from a previous build."""

    output_dir = self.built_products_dir
    output_dir_list = os.listdir(output_dir)
    for item in output_dir_list:
      if item.endswith('.dSYM'):
        shutil.rmtree(os.path.join(output_dir, item))

  def _PlistdSYMPaths(self, dsym_bundle_path):
    """Adds Plists to a given dSYM bundle to redirect DWARF data."""

    # Retrieve the paths that we are expected to remap.

    # Always include a direct path from the execroot to Xcode-visible sources.
    source_maps = [self._ExtractTargetSourceMap()]

    # Remap relative paths from the workspace root.
    if self.normalized_prefix_map:
      # Take the normalized path and map that to Xcode-visible sources.
      source_maps.append(('./', self._NormalizePath(self.workspace_root)))

    # Find the binaries within the dSYM bundle. UUIDs will match that of the
    # binary it was based on.
    dsym_binaries = self._DWARFdSYMBinaries(dsym_bundle_path)

    if not dsym_binaries:
      _PrintXcodeWarning('Could not find the binaries that the dSYM %s was '
                         'based on to determine DWARF binary slices to patch. '
                         'Debugging will probably fail.' % (dsym_bundle_path))
      return 404

    # Find the binary slice UUIDs with dwarfdump from each binary.
    for source_binary_path in dsym_binaries:

      returncode, uuid_info_found = self._UUIDInfoForBinary(source_binary_path)
      if returncode:
        return returncode

      # Create a plist per UUID, each indicating a binary slice to remap paths.
      for uuid, arch in uuid_info_found:
        plist_created = self._CreateUUIDPlist(dsym_bundle_path,
                                              uuid,
                                              arch,
                                              source_maps)
        if not plist_created:
          return 405

    return 0

  def _NormalizePath(self, path):
    """Returns paths with a common form, normalized with a trailing slash.

    Args:
      path: a file system path given in the form of a string.

    Returns:
      str: a normalized string with a trailing slash, based on |path|.
    """
    return os.path.normpath(path) + os.sep

  def _ExtractTargetSourceMap(self, normalize=True):
    """Extracts the source path as a tuple associated with the WORKSPACE path.

    Args:
      normalize: Defines if all paths should be normalized. Preferred for APIs
                 like DBGSourcePathRemapping and target.source-map but won't
                 work for the purposes of -fdebug-prefix-map.

    Returns:
      None: if an error occurred.
      (str, str): a single tuple representing all absolute paths to source
                  files compiled by Bazel as strings ($0) associated with
                  the paths to Xcode-visible sources used for the purposes
                  of Tulsi debugging as strings ($1).
    """
    # All paths route to the "workspace root" for sources visible from Xcode.
    sm_destpath = self.workspace_root
    if normalize:
      sm_destpath = self._NormalizePath(sm_destpath)

    # Add a redirection for the Bazel execution root, the path where sources
    # are referenced by Bazel.
    sm_execroot = self.bazel_exec_root
    if normalize:
      sm_execroot = self._NormalizePath(sm_execroot)
    return (sm_execroot, sm_destpath)

  def _LinkTulsiWorkspace(self):
    """Links the Bazel Workspace to the Tulsi Workspace (`tulsi-workspace`)."""
    tulsi_workspace = os.path.join(self.project_file_path,
                                   '.tulsi',
                                   'tulsi-workspace')
    if os.path.islink(tulsi_workspace):
      os.unlink(tulsi_workspace)
    os.symlink(self.bazel_exec_root, tulsi_workspace)
    if not os.path.exists(tulsi_workspace):
      _PrintXcodeError(
          'Linking Tulsi Workspace to %s failed.' % tulsi_workspace)
      return -1

  @staticmethod
  def _SplitPathComponents(path):
    """Splits the given path into an array of all of its components."""
    components = path.split(os.sep)
    # Patch up the first component if path started with an os.sep
    if not components[0]:
      components[0] = os.sep
    return components

  def _RunSubprocess(self, cmd):
    """Runs the given command as a subprocess, returning (exit_code, output)."""
    self._PrintVerbose('%r' % cmd, 1)
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.STDOUT)
    output, _ = process.communicate()
    return (process.returncode, output)

  def _PrintVerbose(self, msg, level=0):
    if self.verbose > level:
      _PrintUnbuffered(msg)


def main(argv):
  build_settings = bazel_build_settings.BUILD_SETTINGS
  if build_settings is None:
    _Fatal('Unable to resolve build settings. Please report a Tulsi bug.')
    return 1
  return BazelBuildBridge(build_settings).Run(argv)


if __name__ == '__main__':
  _LockFileAcquire(_LockFileCreate())
  _logger = tulsi_logging.Logger()
  logger_warning = tulsi_logging.validity_check()
  if logger_warning:
    _PrintXcodeWarning(logger_warning)
  _timer = Timer('Everything', 'complete_build').Start()
  signal.signal(signal.SIGINT, _InterruptHandler)
  _exit_code = main(sys.argv)
  _timer.End()
  sys.exit(_exit_code)
