# 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
import re

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'

# Intel bots cannot run macOS 26, which newer Xcodes require, so any Xcode
# requested on Intel is replaced by 17c52 (Xcode 26.2), the newest Xcode that
# runs there. See https://github.com/flutter/flutter/issues/192754.
_INTEL_MAX_XCODE_VERSION = '17c52'

# Matches simulator runtime disk image UDIDs as printed by `simctl runtime`,
# e.g. `D: 73EA5108-FE5E-4ADC-B6A6-D2FBE4448EA2 iOS (26.2 - 23C54) (Unusable -
# Other Failure: ... "Duplicate of 30BC4E5F-DE5F-499A-93AF-22FEF83EF916" ...)`.
_RUNTIME_UDID_RE = re.compile(
    r'\b[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\b'
)

# Substring of the `simctl runtime add` output when the added image is a
# duplicate of an already registered (possibly still deleting) image. See
# https://github.com/flutter/flutter/issues/180141.
_DUPLICATE_RUNTIME_ERROR = 'duplicate of'


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.macos_26_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()
      # The `!=` check only avoids a no-op step when 17c52 is already requested.
      if ('intel' in self.m.platform.arch and
          self._sdk_version != _INTEL_MAX_XCODE_VERSION):
        self.m.step.empty(
            'Pinning Xcode to %s on Intel' % _INTEL_MAX_XCODE_VERSION,
            step_text=(
                'Requested Xcode %s, but Intel bots cannot run macOS 26. See '
                'https://github.com/flutter/flutter/issues/192754.'
                % self._sdk_version
            ),
        )
        self._sdk_version = _INTEL_MAX_XCODE_VERSION

    self.macos_13_or_later = current_os >= self.m.version.parse('13.0.0')
    self.macos_26_or_later = current_os >= self.m.version.parse('26.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(add_output_log=True)
        ).stdout.splitlines()
        if self._missing_runtime(runtime_simulators[1:]) or self._unavailable_runtime(runtime_simulators):
          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 _unavailable_runtime(self, runtime_simulators):
    """Check if any runtime is unavailable due to architecture mismatch.

    On Intel Macs, an ARM-only runtime may have been cached. When this happens,
    `simctl list runtimes` reports the runtime as unavailable with a specific
    error about liblaunch_sim.dylib.

    Args:
      runtime_simulators: (list) A list of strings from `simctl list runtimes` output.

    Returns:
      True if any runtime is unavailable due to this error, False otherwise.
    """
    unavailable_error = '(unavailable, liblaunch_sim.dylib could not be opened)'
    for runtime in runtime_simulators:
      if unavailable_error in runtime:
        return True
    return False

  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.

    On macOS 26 and later, `lsregister -kill` was removed so the reset is
    skipped, but the log check still runs so Launch Services problems are
    surfaced.

    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")

      if self.macos_26_or_later:
        # macOS 26 removed `lsregister -kill` ("The -kill option has been
        # removed because it was dangerous and no longer useful"), so the db
        # can no longer be reset from here. The log check below still runs.
        # TODO(okorohelijah): Find a replacement for resetting the Launch
        # Services database on macOS 26+. See
        # https://github.com/flutter/flutter/issues/192645.
        self.m.step.empty(
            'Skipping Launch Services reset on macOS 26+',
            step_text='`lsregister -kill` was removed in macOS 26.',
        )
      else:
        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 (before macOS 26),
      # 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
      if self.macos_26_or_later:
        display_step.step_text = 'xcodebuild reported Launch Services errors and the Launch Services db cannot be reset on macOS 26+. Please file a bug and see go/flutter-infra-macos-troubleshoot.'
      else:
        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.
          ios_runtime_build_version = self._lookup_runtime_build_version(
              runtime_version, xcode_version
          )
          if not self._is_runtime_build_listed(ios_runtime_build_version,
                                               runtime_simulators):
            self._mount_runtime(
                version, runtime_dmg_path, ios_runtime_build_version
            )

      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 and their disk
      # images are fully deleted.
      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 or if any runtime
    disk image is still being deleted. If so, raise an `InfraFailure` (which
    `retry.basic_wrap` retries; if it persists, the build is an infra failure
    rather than a test failure).

    Args:
      max_remaining_runtimes: (int) How many runtimes are allowed to remain for
      it to be considered done unmounting.
    '''
    runtime_simulators = self._list_runtimes()

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

    # `simctl list runtimes` stops listing a runtime as soon as it is unmounted,
    # but `simctl runtime delete` keeps the disk image registered (in the
    # `Deleting` state) until it has been fully removed. Re-adding the same
    # image before that finishes makes simctl register the new image as an
    # unusable "Duplicate of" the old one, which is the root cause of
    # https://github.com/flutter/flutter/issues/180141.
    self._is_runtime_deletion_complete()

  def _list_runtimes(self):
    """Runs `xcrun simctl list runtimes` and returns its output lines.

    Example output:
    [
      "== Runtimes ==",
      "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"
    ]
    """
    return self.m.step(
        'list runtimes', ['xcrun', 'simctl', 'list', 'runtimes'],
        stdout=self.m.raw_io.output_text(add_output_log=True)
    ).stdout.splitlines()

  # pylint: disable=unused-argument
  def _is_runtime_deletion_complete(self, timeout=None):
    """Check if any runtime disk image is still being deleted. If so, raise an
    `InfraFailure`.

    Uses `xcrun simctl runtime list` (not `simctl list runtimes`), which
    reports the state of each runtime disk image (e.g. `Ready`, `Deleting`,
    `Unusable`).
    """
    disk_images = self.m.step(
        'list runtime disk images', ['xcrun', 'simctl', 'runtime', 'list'],
        stdout=self.m.raw_io.output_text(add_output_log=True)
    ).stdout

    if 'Deleting' in disk_images:
      raise self.m.step.InfraFailure('Runtime disk images not deleted yet')

  def _wait_for_runtime_deletion(self):
    """Waits up to ~5 minutes until no runtime disk image is being deleted."""
    self.m.retry.basic_wrap(
        lambda timeout: self._is_runtime_deletion_complete(timeout=timeout),
        sleep=5.0,
        backoff_factor=2,
        max_attempts=7
    )

  def _mount_runtime(
      self, version, runtime_dmg_path, ios_runtime_build_version
  ):
    """Mounts an iOS runtime dmg with `simctl runtime add`.

    `simctl runtime add` fails with an `Unusable - Other Failure: ...
    "Duplicate of <UDID>"` error when an image with the same identity is still
    registered, typically because a previous `simctl runtime delete` of that
    image has not finished yet (deletion is asynchronous). The runtime may
    nevertheless be usable, so rather than failing the build outright:
      1. wait for any pending deletions to finish,
      2. re-check `simctl list runtimes`; if the runtime is now listed, the
         duplicate error was benign,
      3. otherwise delete the duplicate disk image(s) and retry the mount
         once, failing the build if that also fails.
    See https://github.com/flutter/flutter/issues/180141.

    Args:
      version: (string) The configured runtime version (e.g.
        "ios-16-4_14e300c").
      runtime_dmg_path: (string) Path to the runtime dmg to mount.
      ios_runtime_build_version: (string) The iOS runtime build (e.g.
        "20e247") used to verify whether the runtime is mounted.
    """
    step_name = 'verify and mount runtime %s' % version.lower()
    cmd = ['xcrun', 'simctl', 'runtime', 'add', runtime_dmg_path]
    result = self.m.step(
        step_name,
        cmd,
        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),
    )
    if result.retcode == 0:
      return

    output = '%s\n%s' % (result.stdout, result.stderr)
    if _DUPLICATE_RUNTIME_ERROR not in output.lower():
      result.presentation.status = self.m.step.INFRA_FAILURE
      self.m.step.empty(
          'Failed to mount runtime %s' % version.lower(),
          status=self.m.step.INFRA_FAILURE,
          step_text=output.strip(),
      )

    # The presentation can only be changed until the next step starts.
    result.presentation.step_text = (
        'simctl reported a "Duplicate of" error (retcode %d); see the "handle '
        'duplicate runtime %s" step.' % (result.retcode, version.lower())
    )

    with self.m.step.nest('handle duplicate runtime %s' %
                          version.lower()) as display_step:
      self._wait_for_runtime_deletion()

      if self._is_runtime_build_listed(ios_runtime_build_version,
                                       self._list_runtimes()):
        display_step.step_text = (
            'Runtime %s (%s) is already mounted; ignoring benign "Duplicate '
            'of" error from simctl.' % (version, ios_runtime_build_version)
        )
        return

      # The runtime is not usable, so the unusable duplicate (and the image it
      # duplicates, which is not usable either since it is not listed) must be
      # removed before the dmg can be added again.
      for udid in self._parse_runtime_udids(output):
        self.m.step(
            'delete runtime disk image %s' % udid,
            ['xcrun', 'simctl', 'runtime', 'delete', udid],
            ok_ret='any',
        )
      self._wait_for_runtime_deletion()

      self.m.step('%s (retry)' % step_name, cmd)

  def _parse_runtime_udids(self, output):
    """Returns the unique runtime disk image UDIDs found in `output`, in order.

    Args:
      output: (string) Output of a `simctl runtime` command.
    """
    udids = []
    for udid in _RUNTIME_UDID_RE.findall(output.upper()):
      if udid not in udids:
        udids.append(udid)
    return udids

  def _lookup_runtime_build_version(self, runtime_version, xcode_version):
    """Looks up the iOS runtime build version from CIPD.

    Args:
      runtime_version: (string) The iOS version (e.g. "ios-16-4").
      xcode_version: (string) The Xcode version (e.g. "14e300c").
    Returns:
      A string of the iOS runtime build version (e.g. "20e247").

    Raises:
      InfraFailure if the build version could not be determined.
    """

    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

    return ios_runtime_build_version

  def _is_runtime_build_listed(
      self, ios_runtime_build_version, runtime_simulators
  ):
    """Determine if an iOS runtime build is listed as usable by
    `simctl list runtimes`.

    Args:
      ios_runtime_build_version: (string) The iOS runtime build (e.g. "20e247").
      runtime_simulators: (list) Output lines of `simctl list runtimes`.
    Returns:
      A boolean for whether or not the runtime is mounted and usable.
    """
    for runtime in runtime_simulators:
      # Example runtime: `iOS 14.3 (14.3 - 18C61) - com.apple.CoreSimulator.SimRuntime.iOS-14-3`
      runtime = runtime.lower()
      # A runtime reported as unavailable/unusable (e.g. an unusable duplicate
      # disk image) does not count as mounted; it must be (re)mounted.
      if 'unavailable' in runtime or 'unusable' in runtime:
        continue
      if ios_runtime_build_version.lower() in runtime:
        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
