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

"""The `osx_sdk` module provides safe functions to access a semi-hermetic
XCode installation.

Available only to Google-run bots."""

from contextlib import contextmanager

from recipe_engine import recipe_api
from datetime import datetime, timedelta

_RUNTIMESPATH = (
    'Contents/Developer/Platforms/iPhoneOS.platform/Library/'
    'Developer/CoreSimulator/Profiles/Runtimes'
)

# This CIPD source contains Xcode and iOS runtimes create and maintained by the
# Flutter team.
_FLUTTER_XCODE_CIPD = 'flutter_internal/ios/xcode'

# This CIPD source contains Xcode and iOS runtimes created and maintained by the
# Chrome team.
_INFRA_XCODE_CIPD = 'infra_internal/ios/xcode'


class OSXSDKApi(recipe_api.RecipeApi):
  """API for using OS X SDK distributed via CIPD."""

  def __init__(self, sdk_properties, *args, **kwargs):
    super(OSXSDKApi, self).__init__(*args, **kwargs)
    self._sdk_properties = sdk_properties
    self._sdk_version = None
    self._runtime_versions = None
    self._tool_pkg = 'infra/tools/mac_toolchain/${platform}'
    self._tool_ver = 'latest'
    self._cleanup_cache = False
    self.macos_13_or_later = False
    self._xcode_cipd_package_source = None
    self._skip = False

  def initialize(self):
    """Initializes xcode, and ios versions.

    Versions are usually passed as recipe properties but if not then defaults
    are used.
    """
    if not self.m.platform.is_mac:
      return

    if 'skip_xcode_install' in self._sdk_properties:
      self._skip = self._sdk_properties['skip_xcode_install']

    if 'cleanup_cache' in self._sdk_properties:
      self._cleanup_cache = self._sdk_properties['cleanup_cache']

    if 'arm' in self.m.platform.arch and 'toolchain_ver_arm' in self._sdk_properties:
      self._tool_ver = self._sdk_properties['toolchain_ver_arm']
    elif 'intel' in self.m.platform.arch and 'toolchain_ver_intel' in self._sdk_properties:
      self._tool_ver = self._sdk_properties['toolchain_ver_intel']

    if 'runtime_versions' in self._sdk_properties:
      # Sorts the runtime versions to make xcode cache path deterministic, without
      # being affected by how user orders the runtime versions.
      runtime_versions = self._sdk_properties['runtime_versions']
      runtime_versions.sort(reverse=True)
      self._runtime_versions = runtime_versions

    find_os = self.m.step(
        "find macOS version",
        ["sw_vers", "-productVersion"],
        stdout=self.m.raw_io.output_text(),
        step_test_data=(
            lambda: self.m.raw_io.test_api.stream_output_text("14.4")
        ),
    )
    current_os = self.m.version.parse(find_os.stdout.strip())
    if 'sdk_version' in self._sdk_properties:
      self._sdk_version = self._sdk_properties['sdk_version'].lower()

    self.macos_13_or_later = current_os >= self.m.version.parse('13.0.0')

    if 'xcode_cipd_package_source' in self._sdk_properties:
      self._xcode_cipd_package_source = self._sdk_properties[
          'xcode_cipd_package_source']
    else:
      # TODO(vashworth): Once all bots are on macOS 13, we can remove this
      # check and always default to _INFRA_XCODE_CIPD.
      if self.macos_13_or_later:
        # Starting with macOS 13, Xcode packages that have been altered are
        # considered "damaged" and will not be usable. Since Xcode CIPD packages
        # from flutter_internal have been altered up to Xcode 15 beta 6 (15a5219j),
        # use infra_internal Xcode CIPD packages as the default on macOS 13.
        self._xcode_cipd_package_source = _INFRA_XCODE_CIPD
      else:
        self._xcode_cipd_package_source = _FLUTTER_XCODE_CIPD

  @contextmanager
  def __call__(self, kind, devicelab=False):
    """Sets up the XCode SDK environment.

    Is a no-op on non-mac platforms.

    This will deploy the helper tool and the XCode.app bundle at
    `[START_DIR]/cache/osx_sdk`.

    To avoid machines rebuilding these on every run, set up a named cache in
    your cr-buildbucket.cfg file like:

        caches: [
          {
            name: "flutter_xcode"
            path: "osx_sdk"
          }
        ]

    The Xcode app will be installed under:
        osx_sdk/xcode_<xcode-version>

    If any iOS runtime is needed, the corresponding path will be:
        osx_sdk/xcode_<xcode-version>_runtime_<runtime-version>

    These cached packages will be shared across builds/bots.

    Usage:
      with api.osx_sdk('mac'):
        # sdk with mac build bits

      with api.osx_sdk('ios'):
        # sdk with mac+iOS build bits

    Args:
      kind ('mac'|'ios'): How the SDK should be configured. iOS includes the
        base XCode distribution, as well as the iOS simulators (which can be
        quite large).
      devicelab (bool): whether this is a devicelab tasks. The xcode for devicelab
        is installed in a fixed location `/opt/flutter/xcode`.

    Raises:
        StepFailure or InfraFailure.
    """
    assert kind in ('mac', 'ios'), 'Invalid kind %r' % (kind,)
    if self._skip or not self.m.platform.is_mac:
      yield
      return

    if self._sdk_version is None:
      self.m.step.empty('Xcode version is not set. Skipping.',)
      yield
      return

    try:
      with self.m.context(infra_steps=True):
        self._diagnose_unresponsive_mac(devicelab)
        self._setup_osx_sdk(kind, devicelab)
        runtime_simulators = self.m.step(
            'list runtimes', ['xcrun', 'simctl', 'list', 'runtimes'],
            stdout=self.m.raw_io.output_text()
        ).stdout.splitlines()
        if self._missing_runtime(runtime_simulators[1:]):
          self._cleanup_cache = True
          self._setup_osx_sdk(kind, devicelab)
      yield
    finally:
      self.reset_xcode()

  def reset_xcode(self):
    '''Unset manually defined Xcode path for Xcode command line tools on macOS.'''
    if self._skip or not self.m.platform.is_mac:
      return
    with self.m.context(infra_steps=True):
      self.m.step('reset XCode', ['sudo', 'xcode-select', '--reset'])

  def _missing_runtime(self, runtime_simulators):
    """Check if there is any missing runtime.

    If no explicit `_runtime_versions` is specified, we assume `runtime_simulators`
    at least has the default runtime and should not be empty.

    If there is explicit `_runtime_versions` defined, we need to check if the number
    of installed runtime matches the number of required.

    The runtime_simulators follows:
    [
      "iOS 16.2 (16.2 - 20C52) - com.apple.CoreSimulator.SimRuntime.iOS-16-2",
      "iOS 16.4 (16.4 - 20E247) - com.apple.CoreSimulator.SimRuntime.iOS-16-4"
    ]

    The property `_runtime_versions` follows:
    [
      "ios-16-4_14e300c",
      "ios-16-2_14c18"
    ]
    """
    if not self._runtime_versions:
      return not runtime_simulators
    return len(self._runtime_versions) != len(runtime_simulators)

  def _get_xcode_base_cache_path(self, devicelab: bool):
    """Returns the base cache path for xcode.

    Args:
      devicelab - Whether or not the machine this code is running is a devicelab
        machine.
    """
    if devicelab:
      return self.m.path.cast_to_path('/opt/flutter/xcode')
    return self.m.path.cache_dir / 'osx_sdk'

  def _setup_osx_sdk(self, kind, devicelab):
    app = None
    self._clean_xcode_cache(devicelab)
    # NOTE: cleaning of the cache on devicelab will happen via salt.
    if not devicelab:
      self._micro_manage_cache(devicelab=devicelab)
    app = self._ensure_sdk(kind, devicelab)
    self.m.os_utils.kill_simulators()
    self._select_xcode(app)
    self.m.step('list simulators', ['xcrun', 'simctl', 'list'])

  def _clean_xcode_cache(self, devicelab):
    """Cleans up cache when specified or polluted.

    Cleans up only corresponding versioned xcode instead of the whole `osx_sdk`.

    If on macOS 13 or later, deletes all mounted runtimes and deletes
    corresponding cached runtime dmgs.
    """
    if not self._cleanup_cache:
      return
    if devicelab or not self.macos_13_or_later:
      self.m.file.rmtree('Cleaning up Xcode cache', self._xcode_dir(devicelab))
    else:
      # Clean up with `file.rmtree` fails on macOS 13 non-devicelab bots with an
      # "Operation not permitted" error when deleting XCode.app/Contents/_CodeSignature.
      # Use `rm -rf` instead.
      self.m.step(
          'Cleaning up Xcode cache',
          ['rm', '-rf', self._xcode_dir(devicelab)]
      )

  def _ensure_mac_toolchain(self, tool_dir):
    ef = self.m.cipd.EnsureFile()
    ef.add_package(self._tool_pkg, self._tool_ver)
    self.m.cipd.ensure(tool_dir, ef)

  def _select_xcode(self, sdk_app):
    self.m.step('select xcode', ['sudo', 'xcode-select', '--switch', sdk_app])

  def _verify_xcode(self, sdk_app):
    """If Xcode is already downloaded, verify that it's not damaged.

    Args:
    sdk_app: (Path) Path to installed Xcode app bundle.
    """
    if not self.m.path.exists(sdk_app):
      return

    with self.m.step.nest('verify xcode %s' % sdk_app):
      version_check_failed = False
      try:
        self._select_xcode(sdk_app)

        # This step is expected to timeout if Xcode is damaged.
        self.m.step(
            'check xcode version',
            [
                'xcrun',
                'xcodebuild',
                '-version',
            ],
            timeout=60 * 5,  # 5 minutes
        )
      except self.m.step.StepFailure:
        version_check_failed = True
        raise
      finally:
        self.reset_xcode()
        self._dimiss_damaged_notification()

        if version_check_failed:
          self._diagnose_codesign_failure(sdk_app)

  def _diagnose_codesign_failure(self, sdk_app):
    """Check if Xcode verification may have failed due to code not matching
    original signed code. Used to help debug issues.
    """
    self.m.step(
        'verify codesign',
        [
            'codesign',
            '-vv',
            sdk_app,
        ],
        ok_ret='any',
    )

  def _dimiss_damaged_notification(self):
    """If Xcode is damaged, it may show a notification that can cause
    Xcode processes to hang until it's closed. Kill `CoreServicesUIAgent`
    to close it.
    """
    self.m.step(
        'dismiss damaged notification',
        ['killall', '-9', 'CoreServicesUIAgent'],
        ok_ret='any',
    )

  def _try_install_xcode(self, tool_dir, kind, app_dir, sdk_app, devicelab):
    """Installs xcode using mac_toolchain. If install fails, clear the cache and try again.

    Args:
      devicelab: (bool) Whether this is a devicelab tasks. Don't install
        explicit runtimes for devicelab tasks.
      app_dir: (Path) Path to Xcode cache directory.
      tool_dir: (Path) Path to mac_toolchain cache directory.
      sdk_app: (Path) Path to installed Xcode app bundle.
      kind ('mac'|'ios'): How the SDK should be configured.
    """
    with self.m.step.nest('install xcode'):
      try:
        self._install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)
      except self.m.step.StepFailure:
        self._install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab, True)

  def _install_xcode(
      self, tool_dir, kind, app_dir, sdk_app, devicelab, retry=False
  ):
    """Installs xcode using mac_toolchain.

    Args:
      devicelab: (bool) Whether this is a devicelab tasks. Don't install
        explicit runtimes for devicelab tasks.
      app_dir: (Path) Path to Xcode cache directory.
      tool_dir: (Path) Path to mac_toolchain cache directory.
      sdk_app: (Path) Path to installed Xcode app bundle.
      kind ('mac'|'ios'): How the SDK should be configured.
      retry: (bool) Whether this is the second attempt to install Xcode.
    """

    install_path = sdk_app

    # On retry, install Xcode to a different path and later move it to the
    # original path. Although unproven, there is a theory that re-installing
    # Xcode to the same path as a previously damaged version may cause the new
    # version to also be considered damaged.
    if retry:
      uuid = self.m.uuid.random()
      install_path = app_dir / f'temp_{uuid}_xcode.app'

    try:
      # Verify that existing Xcode is not damaged. If it's damaged, the
      # 'install xcode from cipd' step may get stuck until it times out.
      self._verify_xcode(install_path)
    except self.m.step.StepFailure:
      self._cleanup_cache = True
      self._clean_xcode_cache(devicelab)

    try:
      self._ensure_mac_toolchain(tool_dir)
      if self.macos_13_or_later:
        # TODO(vashworth): Remove macOS 13 specific install steps once
        # https://github.com/flutter/flutter/issues/138238 is resolved.
        self.m.step('Show tool_dir cache', ['ls', '-al', tool_dir])
      self.m.step(
          'install xcode from cipd',
          [
              tool_dir / 'mac_toolchain',
              'install',
              '-kind',
              kind,
              '-xcode-version',
              self._sdk_version,
              '-output-dir',
              install_path,
              '-cipd-package-prefix',
              self._xcode_cipd_package_source,
              '-with-runtime=%s' % (not bool(self._runtime_versions)),
              '-with-metal-toolchain=True',
              '-verbose',
          ],
          timeout=60 * 30  # 30 minutes
      )
      if retry:
        self.m.step(
            'move to final destination',
            [
                'mv',
                install_path,
                sdk_app,
            ],
        )
    except self.m.step.StepFailure:
      if self.macos_13_or_later:
        # TODO(vashworth): Remove macOS 13 specific install steps once
        # https://github.com/flutter/flutter/issues/138238 is resolved.
        self.m.step('Show tool_dir cache', ['ls', '-al', tool_dir])
        self.m.step('Show app_dir cache', ['ls', '-al', app_dir], ok_ret='any')
      self._dimiss_damaged_notification()
      self._diagnose_codesign_failure(sdk_app)
      self._cleanup_cache = True
      self._clean_xcode_cache(devicelab)
      self.m.step.empty(
          'Failed to install Xcode',
          status=self.m.step.INFRA_FAILURE,
      )
    finally:
      if retry:
        self.m.step(
            'clean temporary install path',
            [
                'rm',
                '-rf',
                install_path,
            ],
            ok_ret='any',
        )

  def _diagnose_unresponsive_mac(self, devicelab):
    """To prevent mac tests from hanging due to unresponsive host, kill Setup
    Assistant and reset the Launch Services database.

    Also, check if `xcodebuild` commands may have potentially hung due to Launch
    Services issues. If so, add entry to Launch Services reset log and print a warning.

    Args:
      devicelab: (bool) tells the module which path we should be working with.
    """
    if devicelab:
      return

    # Try to kill setup assistant
    self._kill_setup_assistant()

    with self.m.step.nest('verify launch services') as display_step:
      start_time = self.now().strftime("%Y-%m-%d %H:%M:%S")

      self.m.step(
          'Reset and rescan Launch Services db',
          [
              '/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister',
              '-kill',
              '-r',
              '-domain',
              'local',
              '-domain',
              'system',
              '-domain',
              'user',
          ],
      )

      launch_services_reset_log = self._get_xcode_base_cache_path(
          devicelab
      ) / 'launch_services_reset_log.txt'

      reset_logs = ''
      last_entry_time = None
      if self.m.path.exists(launch_services_reset_log):
        reset_logs = self.m.file.read_text(
            'Check if Launch Services db has been reset recently',
            launch_services_reset_log,
        )
        try:
          # Get last entry in log.
          last_entry = reset_logs.splitlines()[-1].rstrip()
          last_entry_time = datetime.strptime(last_entry, "%Y-%m-%d %H:%M:%S")
        except:
          # If there was an invalid date, reset the log file.
          reset_logs = ''

      # If last log entry was within 24 hours, only search logs since that time
      # (with a 30 minute buffer). Otherwise search the last 24 hours
      if last_entry_time and (self.now() - last_entry_time).days <= 1:
        search_time = (last_entry_time +
                       timedelta(minutes=30)).strftime("%Y-%m-%d %H:%M:%S")
        time_parameters = [
            '--start',
            search_time,
        ]
      else:
        time_parameters = [
            '--last',
            '24h',
        ]

      # Check if xcodebuild commands have potentially been slowed by Launch
      # Services.
      xcodebuild_logs = self.m.step(
          'Check if xcodebuild impacted by Launch Services',
          [
              'log',
              'show',
              *time_parameters,
              '--style',
              'compact',
              '--predicate',
              'logType == "error" AND process == "xcodebuild" AND '
              'subsystem == "com.apple.launchservices" AND composedMessage '
              'CONTAINS "disconnect event interruption received for service"',
          ],
          stdout=self.m.raw_io.output_text(add_output_log=True),
      )

      # Remove first line, which is headers.
      xcodebuild_logs_stdout = xcodebuild_logs.stdout.splitlines()[1:]

      # Since Launch Services resets on every build, xcodebuild should not
      # continue to fail. If there are still errors here, print a warning and
      # update the reset log.
      if len(xcodebuild_logs_stdout) == 0:
        return

      display_step.status = self.m.step.INFRA_FAILURE
      display_step.step_text = 'Launch Services has already been reset recently. Please file a bug and see go/flutter-infra-macos-troubleshoot.'

      self.m.file.write_text(
          'Update Launch Services reset log',
          launch_services_reset_log,
          '%s\n%s' % (reset_logs, start_time),
      )

  def _kill_setup_assistant(self):
    """Tries to kill Setup Assistant. Sometimes on macOS, tests will be blocked
    by a Setup Assistant window. This appears to be a bug with macOS
    (see b/343978626). To workaround, kill Setup Assistant."""

    pgrep_result = self.m.step(
        'check for Setup Assistant',
        [
            'pgrep',
            'Setup Assistant',
        ],
        ok_ret='any',
        stdout=self.m.raw_io.output_text(add_output_log=True),
    )

    if pgrep_result.stdout != '':
      self.m.step(
          'Kill Setup Assistant',
          [
              'pkill',
              '-9',
              'Setup Assistant',
          ],
          ok_ret='any',
      )

  def now(self):
    """Provide a deterministic date when running tests."""
    return datetime.now()  # pragma: nocover

  def _ensure_sdk(self, kind, devicelab):
    """Ensures the mac_toolchain tool and OSX SDK packages are installed.

    Returns Path to the installed sdk app bundle."""
    app_dir = self._xcode_dir(devicelab)
    tool_dir = self.m.path.mkdtemp() / 'osx_sdk' if devicelab else app_dir
    sdk_app = app_dir / 'XCode.app'
    self._try_install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)

    self._cleanup_runtimes_cache(sdk_app)

    self._install_runtimes(devicelab, app_dir, tool_dir, sdk_app, kind)

    return sdk_app

  def _micro_manage_cache(self, devicelab: bool):
    """Tracks the age of packages in the target cache. If older than a
    specific date then delete them.

    Params:
      devicelab: (bool) tells the module which path we should be working with.
    """
    cache_path = self._get_xcode_base_cache_path(devicelab)
    app_dir = self._xcode_dir(devicelab)
    self.m.step("show app_dir", ['echo', app_dir])
    self._show_xcode_cache(cache_path)
    self.m.cache_micro_manager.run(cache_path, [app_dir])
    self._show_xcode_cache(cache_path)

  def _show_xcode_cache(self, cache_path):
    self.m.step(
        'Show xcode cache',
        ['ls', '-al', cache_path],
        ok_ret='any',
    )

  def _install_runtimes(self, devicelab, app_dir, tool_dir, sdk_app, kind):
    """Ensure runtimes are installed.

    For macOS lower than 13, this involves downloading the runtime and copying
    it into the Xcode app bundle.

    For macOS 13 and higher, this involved downloading the runtime dmg and
    running a `simctl` command to verify and mount it. This is required because
    copying files into Xcode on macOS 13 may damage it and prevent it from
    being usable.

    Args:
      devicelab: (bool) Whether this is a devicelab tasks. Don't install
        explicit runtimes for devicelab tasks.
      app_dir: (Path) Path to Xcode cache directory.
      tool_dir: (Path) Path to mac_toolchain cache directory.
      sdk_app: (Path) Path to installed Xcode app bundle.
      kind ('mac'|'ios'): How the SDK should be configured.
    """

    if not self._runtime_versions:
      # On macOS 13, when cleanup_cache is True, we first clear the Xcode cache,
      # install Xcode, and then clean up the runtimes cache. It happens in this
      # order because removing runtimes requires Xcode developer tools so Xcode
      # must be installed first. However, when no explicit runtimes are defined,
      # the runtime is also installed in the `_try_install_xcode` function. So after
      # cleaning the runtimes, the runtime that was installed may have been
      # removed. So re-call `_try_install_xcode` to reinstall the removed runtime.
      if self.macos_13_or_later and self._cleanup_cache:
        with self.m.step.nest('install runtimes'):
          self._try_install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)
      return

    if devicelab:
      return

    with self.m.step.nest('install runtimes'):
      if self.macos_13_or_later:
        self._select_xcode(sdk_app)
        runtime_simulators = self.m.step(
            'list runtimes', ['xcrun', 'simctl', 'list', 'runtimes'],
            stdout=self.m.raw_io.output_text(add_output_log=True)
        ).stdout.splitlines()

        for version in self._runtime_versions:
          runtime_version_parts = version.split('_')
          if len(runtime_version_parts) != 2:
            self.m.step.empty(
                'Invalid runtime version %s' % version,
                status=self.m.step.INFRA_FAILURE,
            )
          runtime_version = runtime_version_parts[0]
          xcode_version = runtime_version_parts[1]
          # we can assume devicelab False and build this with base path.
          runtime_dmg_cache_dir = self._runtime_dmg_dir_cache_path(version)

          self.m.step(
              'install xcode runtime %s' % version.lower(),
              [
                  app_dir / '/mac_toolchain',
                  'install-runtime-dmg',
                  '-cipd-package-prefix',
                  self._xcode_cipd_package_source,
                  '-runtime-version',
                  runtime_version,
                  '-xcode-version',
                  xcode_version,
                  '-output-dir',
                  runtime_dmg_cache_dir,
              ],
          )
          downloaded_runtime_files = self.m.file.listdir(
              'list xcode runtime dmg %s' % version.lower(),
              runtime_dmg_cache_dir
          )

          # The runtime dmg may not be named consistently so search for the dmg file.
          runtime_dmg_path = None
          for file_path in downloaded_runtime_files:
            if '.dmg' in str(file_path):
              runtime_dmg_path = str(file_path)

          if runtime_dmg_path is None:
            self.m.step.empty(
                'Failed to find runtime dmg',
                status=self.m.step.INFRA_FAILURE,
            )

          # Skip adding the runtime if it's already mounted
          if not self._is_runtime_mounted(runtime_version, xcode_version,
                                          runtime_simulators):
            self.m.step(
                'verify and mount runtime %s' % version.lower(),
                [
                    'xcrun',
                    'simctl',
                    'runtime',
                    'add',
                    runtime_dmg_path,
                ],
            )

      else:
        # Skips runtime installation if it already exists. Otherwise,
        # installs each runtime version under `osx_sdk` for cache sharing,
        # and then copies over to the destination.

        self.m.file.ensure_directory(
            'Ensuring runtimes directory', sdk_app / _RUNTIMESPATH
        )
        for version in self._runtime_versions:
          runtime_name = 'iOS %s.simruntime' % version.lower(
          ).replace('ios-', '').replace('-', '.')
          dest = sdk_app / _RUNTIMESPATH / runtime_name
          if not self.m.path.exists(dest):
            cache_base_path = self._get_xcode_base_cache_path(False)
            runtime_cache_dir = (
                cache_base_path / ('xcode_runtime_%s' % version.lower())
            )
            self.m.step(
                'install xcode runtime %s' % version.lower(),
                [
                    app_dir / 'mac_toolchain',
                    'install-runtime',
                    '-cipd-package-prefix',
                    _FLUTTER_XCODE_CIPD,
                    '-runtime-version',
                    version.lower(),
                    '-output-dir',
                    runtime_cache_dir,
                ],
            )
            # Move the runtimes
            path_with_version = runtime_cache_dir / runtime_name
            # If the runtime was the default for xcode the cipd bundle contains a directory called iOS.simruntime otherwise
            # it contains a folder called "iOS <version>.simruntime".
            source = path_with_version if self.m.path.exists(
                path_with_version
            ) else runtime_cache_dir / 'iOS.simruntime'
            self.m.file.copytree(
                'Copy runtime to %s' % dest, source, dest, symlinks=True
            )

  def _xcode_dir(self, devicelab):
    """Returns the location of the xcode app in the cache dir.

    For a devicelab task, the path is prefixed at `/opt/flutter/xcode`.

    For a host only task without runtime, the path looks like
            xcode_<xcode-version>

    a host only task with runtimes, the path looks like
        xcode_<xcode-version>_runtime1_<runtime1-version>_..._runtimeN_<runtimeN-version>
    """

    xcode_cache_base_path = self._get_xcode_base_cache_path(devicelab)
    if devicelab:
      return xcode_cache_base_path / self._sdk_version
    runtime_version = None
    sdk_version = f"xcode_{self._sdk_version}"
    if not self.macos_13_or_later and self._runtime_versions:
      runtime_version = "_".join(self._runtime_versions)
      sdk_version = f"{sdk_version}_runtime_{runtime_version}"
    return xcode_cache_base_path / sdk_version

  def _runtime_dmg_dir_cache_path(self, version):
    cache_base_path = self._get_xcode_base_cache_path(False)
    # this method seems to be only used for non-devicelab cache path.
    return cache_base_path / ('xcode_runtime_dmg_%s' % version.lower())

  def _cleanup_runtimes_cache(self, sdk_app):
    """Deletes all mounted runtimes and deletes corresponding cached runtime dmgs.

    This is only used for macOS 13+ since runtimes are installed and mounted separately.
    """

    if not self._cleanup_cache or not self.macos_13_or_later:
      return

    with self.m.step.nest('Cleaning up runtimes cache'):
      self._select_xcode(sdk_app)

      simulator_cleanup_result = self.m.step(
          'Cleaning up mounted simulator runtimes',
          [
              'xcrun',
              'simctl',
              'runtime',
              'delete',
              'all',
          ],
          raise_on_failure=False,
          ok_ret='any',
          stdout=self.m.raw_io.output_text(add_output_log=True),
          stderr=self.m.raw_io.output_text(add_output_log=True),
      )

      simulator_cleanup_stdout = simulator_cleanup_result.stdout.rstrip()
      simulator_cleanup_stderr = simulator_cleanup_result.stderr.rstrip()
      if simulator_cleanup_stdout and 'No matching images found to delete' not in simulator_cleanup_stdout:
        self.m.step.empty(
            'Failed to delete runtimes',
            status=self.m.step.INFRA_FAILURE,
            step_text=simulator_cleanup_stdout,
        )
      if simulator_cleanup_stderr and 'No matching images found to delete' not in simulator_cleanup_stderr:
        self.m.step.empty(
            'Failed to delete runtimes',
            status=self.m.step.INFRA_FAILURE,
            step_text=simulator_cleanup_stderr,
        )

      # Determine how many runtimes can remain to consider them unmounted. For
      # Xcode versions 15 or greater, 0 are allowed to remain. Otherwise 1 is
      # allowed. This is because in older versions of Xcode, the runtime is
      # included in Xcode, which means it won't be unmounted.
      max_remaining_runtimes = 1
      xcode_version = self.m.step(
          'check xcode version',
          [
              'xcrun',
              'xcodebuild',
              '-version',
          ],
          stdout=self.m.raw_io.output_text(add_output_log=True),
      ).stdout.splitlines()
      if len(xcode_version) > 0:
        xcode_version = xcode_version[0].replace("Xcode", "").strip()
        parsed_xcode_version = self.m.version.parse(xcode_version)
        if parsed_xcode_version >= self.m.version.parse('15.0.0'):
          max_remaining_runtimes = 0

      # Wait up to ~5 minutes until runtimes are unmounted.
      self.m.retry.basic_wrap(
          lambda timeout: self._is_runtimes_unmounted(
              max_remaining_runtimes,
              timeout=timeout,
          ),
          step_name='Wait for runtimes to unmount',
          sleep=5.0,
          backoff_factor=2,
          max_attempts=7
      )

      if not self._runtime_versions:
        return

      for version in self._runtime_versions:
        runtime_dmg_cache_dir = self._runtime_dmg_dir_cache_path(version)

        self.m.file.rmtree(
            'Cleaning up runtime cache %s' % version.lower(),
            runtime_dmg_cache_dir
        )

  # pylint: disable=unused-argument
  def _is_runtimes_unmounted(self, max_remaining_runtimes, timeout=None):
    '''Check if more than one runtime is currently mounted. If more than one
    is mounted, raise a `StepFailure`.

    Args:
      max_remaining_runtimes: (int) How many runtimes are allowed to remain for
      it to be considered done unmounting.
    '''
    runtime_simulators = self.m.step(
        'list runtimes', ['xcrun', 'simctl', 'list', 'runtimes'],
        stdout=self.m.raw_io.output_text(add_output_log=True)
    ).stdout.splitlines()

    if len(runtime_simulators[1:]) > max_remaining_runtimes:
      raise self.m.step.StepFailure('Runtimes not unmounted yet')

  def _is_runtime_mounted(
      self, runtime_version, xcode_version, runtime_simulators
  ):
    """Determine if iOS runtime version is already mounted.

    Args:
      runtime_version: (string) The iOS version (e.g. "ios-16-4").
      xcode_version: (string) The Xcode version (e.g. "14e300c").
      runtime_simulators: (list) A list of strings of runtime versions.
    Returns:
      A boolean for whether or not the runtime is already mounted.
    """

    with self.m.step.nest('cipd describe %s_%s' %
                          (runtime_version, xcode_version)) as display_step:
      # First try to get the iOS runtime build version by the Xcode version
      ios_runtime_build_version = self._get_ios_runtime_build_version(
          runtime_version, xcode_version
      )

      # If unable to get from the Xcode version, try again by using the iOS runtime version
      if ios_runtime_build_version is None:
        ios_runtime_build_version = self._get_ios_runtime_build_version(
            runtime_version
        )

      if ios_runtime_build_version is None:
        self.m.step.empty(
            'Failed to get runtime build version',
            status=self.m.step.INFRA_FAILURE,
        )
      else:
        self.m.step.empty(
            'runtime build version', step_text=ios_runtime_build_version
        )
        display_step.status = self.m.step.SUCCESS

    # Check if runtime is already mounted
    for runtime in runtime_simulators:
      # Example runtime: `iOS 14.3 (14.3 - 18C61) - com.apple.CoreSimulator.SimRuntime.iOS-14-3`
      if ios_runtime_build_version.lower() in runtime.lower():
        return True

    return False

  def _get_ios_runtime_build_version(self, runtime_version, xcode_version=None):
    """Gets the iOS runtime build version from CIPD.

    If `xcode_version` is provided, it will use it to search for the CIPD package.
    If not provided, the `runtime_version` will be used. In both cases, it ensures
    the found package matches the `runtime_version`.

    Args:
      runtime_version: (string) An iOS version used to find and match the CIPD package (e.g. "ios-16-4")
      xcode_version: (string) A version of Xcode to use to find CIPD package (e.g. "14e300c").
    Returns:
      A string of the build version or None if unable to get the build version.
    """

    search_ref = runtime_version
    if xcode_version is not None:
      search_ref = xcode_version

    try:
      description = self.m.cipd.describe(
          '%s/ios_runtime_dmg' % self._xcode_cipd_package_source,
          search_ref,
      )
      runtime_tag = None
      build_tag = None
      for tag in description.tags:
        if 'ios_runtime_version' in tag.tag:
          runtime_tag = self._parse_cipd_description_tag(tag.tag)
        if 'ios_runtime_build' in tag.tag:
          build_tag = self._parse_cipd_description_tag(tag.tag)

      if runtime_tag == runtime_version:
        return build_tag

      self.m.step.empty(
          'mismatching runtimes',
          step_text='Found %s, expected %s' % (runtime_tag, runtime_version),
          status=self.m.step.INFRA_FAILURE,
      )

    except self.m.step.StepFailure:
      pass

    return None

  def _parse_cipd_description_tag(self, tag):
    """Parse a colon separated CIPD description tag.

    Args:
      tag: (string) A colon separated string describing a CIPD tag.
        (e.g "ios_runtime_build:21A5303d" or "ios_runtime_version:ios-17-0")
    Returns:
      A string of the value following the colon or None if unable to parse.
    """
    tag_parts = tag.split(':')
    if len(tag_parts) == 2:
      return tag_parts[1]
    return None
