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

import os
from contextlib import contextmanager
from recipe_engine import recipe_api

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2

TIMEOUT_PROPERTY = 'ios_debug_symbol_doctor_timeout_seconds'
TCC_AUTOMATION_DB = 'TCC.db'
TCC_AUTOMATION_BACKUP_DB = 'TCC.db.backup'


class OsUtilsApi(recipe_api.RecipeApi):
  """Operating system utilities."""

  def initialize(self):
    self._mock_is_symlink = None
    if self._test_data.enabled:
      self._mock_is_symlink = self._test_data.get('is_symlink', True)

  def _kill_win(self, name, exe_name):
    """Kills all the windows processes with a given name.

    Args:
      name(str): The name of the step.
      exe_name(str): The name of the windows executable.
    """
    self.m.step(
        name,
        ['taskkill', '/f', '/im', exe_name, '/t'],
        ok_ret='any',
    )

  def replace_magic_envs(self, command, env):
    """Replaces allowed listed env variables by its value."""
    MAGIC_ENV_DICT = {
        '${FLUTTER_LOGS_DIR}': 'FLUTTER_LOGS_DIR',
        '${LUCI_WORKDIR}': 'LUCI_WORKDIR',
        '${LUCI_CLEANUP}': 'LUCI_CLEANUP',
        '${REVISION}': 'REVISION',
    }
    result = []
    for part in command:
      if part in MAGIC_ENV_DICT:
        result.append(env[MAGIC_ENV_DICT[part]])
      else:
        result.append(part)
    return result

  def is_symlink(self, path):
    """Returns if a path points to a symlink or not."""
    is_symlink = os.path.islink(self.m.path.abspath(path))
    return is_symlink if self._mock_is_symlink is None else self._mock_is_symlink

  def symlink(self, source, dest):
    """Creates a symbolic link.

    Creates a symbolic link in mac platforms.
    """
    if self.m.platform.is_mac:
      self.m.step(
          'Link %s to %s' % (dest, source),
          ['ln', '-s', source, dest],
          infra_step=True,
      )

  def clean_derived_data(self):
    """Cleans the derived data folder in mac builders.

    Derived data caches fail very frequently when different version of mac/ios
    sdks are used in the same bot. To prevent those failures we will start
    deleting the folder before every task.
    """
    derived_data_path = self.m.path['home'].join(
        'Library', 'Developer', 'Xcode', 'DerivedData'
    )
    if self.m.platform.is_mac:
      self.m.step(
          'Delete mac deriveddata',
          ['rm', '-rf', derived_data_path],
          infra_step=True,
      )

  def collect_os_info(self):
    """Collects meminfo, cpu, processes for mac"""
    if self.m.platform.is_mac:
      self.m.step(
          'OS info',
          cmd=['top', '-l', '3', '-o', 'mem'],
          infra_step=True,
      )
      # These are temporary steps to collect xattr info for triage purpose.
      # See issue: https://github.com/flutter/flutter/issues/68322#issuecomment-740264251
      self.m.step(
          'python3 xattr info',
          cmd=['xattr', '/opt/s/w/ir/cipd_bin_packages/python3'],
          ok_ret='any',
          infra_step=True,
      )
      self.m.step(
          'git xattr info',
          cmd=['xattr', '/opt/s/w/ir/cipd_bin_packages/git'],
          ok_ret='any',
          infra_step=True,
      )
    elif self.m.platform.is_linux:
      self.m.step(
          'OS info',
          cmd=['top', '-b', '-n', '3', '-o', '%MEM'],
          infra_step=True,
      )

  def kill_simulators(self):
    """Kills any open simulators.

    This is to ensure builds use xcode from a clean state.
    """
    if self.m.platform.is_mac:
      self.m.step(
          'kill dart', [
              'killall', '-9', '-v',
              'com.apple.CoreSimulator.CoreSimulatorDevice'
          ],
          ok_ret='any',
          infra_step=True
      )

  def kill_processes(self):
    """Kills processes.

    Windows uses exclusive file locking.  On LUCI, if these processes remain
    they will cause the build to fail because the builder won't be able to
    clean up.

    Linux and Mac have leaking processes after task executions, potentially
    causing the build to fail if without clean up.

    This might fail if there's not actually a process running, which is
    fine.

    If it actually fails to kill the task, the job will just fail anyway.
    """
    with self.m.step.nest('Killing Processes') as presentation:
      if self.m.platform.is_win:
        self._kill_win('stop gradle daemon', 'java.exe')
        self._kill_win('stop dart', 'dart.exe')
        self._kill_win('stop adb', 'adb.exe')
        self._kill_win('stop flutter_tester', 'flutter_tester.exe')
      elif self.m.platform.is_mac:
        self.m.step(
            'kill dart', ['killall', '-9', '-v', 'dart'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill flutter', ['killall', '-9', '-v', 'flutter'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Chrome', ['killall', '-9', '-v', 'Chrome'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Safari', ['killall', '-9', '-v', 'Safari'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill java', ['killall', '-9', '-v', 'java'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill adb', ['killall', '-9', '-v', 'adb'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Xcode', ['killall', '-9', '-v', 'Xcode'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill QuickTime', ['killall', '-9', '-v', 'QuickTime Player'],
            ok_ret='any',
            infra_step=True
        )
      else:
        self.m.step(
            'kill chrome', ['pkill', '-e', 'chrome'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill dart', ['pkill', '-e', 'dart'], ok_ret='any', infra_step=True
        )
        self.m.step(
            'kill flutter', ['pkill', '-e', 'flutter'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill java', ['pkill', '-e', 'java'], ok_ret='any', infra_step=True
        )
        self.m.step(
            'kill adb', ['pkill', '-e', 'adb'], ok_ret='any', infra_step=True
        )
      # Ensure we always pass this step as killing non existing processes
      # may create errors.
      presentation.status = 'SUCCESS'

  @contextmanager
  def make_temp_directory(self, label):
    """Makes a temporary directory that is automatically deleted.

    Args:
      label:
        (str) Part of the step name that removes the directory after is used.
    """
    temp_dir = self.m.path.mkdtemp('tmp')
    try:
      yield temp_dir
    finally:
      self.m.file.rmtree('temp dir for %s' % label, temp_dir)

  def shutdown_simulators(self):
    """It stops simulators if task is running on a devicelab bot."""
    if self.is_devicelab() and self.is_ios() and self.m.platform.is_mac:
      with self.m.step.nest('Shutdown simulators'):
        self.m.step(
            'Shutdown simulators',
            ['sudo', 'xcrun', 'simctl', 'shutdown', 'all']
        )
        self.m.step(
            'Erase simulators', ['sudo', 'xcrun', 'simctl', 'erase', 'all']
        )

  def enable_long_paths(self):
    """Enables long path support in Windows."""

    if not self.m.platform.is_win:
      # noop for non windows platforms.
      return
    with self.m.step.nest('Enable long path support'):
      resource_name = self.resource('long_paths.ps1')
      self.m.step(
          'Run long path support script',
          ['powershell.exe', resource_name],
      )

  def _get_initial_timeout(self):
    return self.m.properties.get(
        # This is not set by the builder config, but can be provided via LED
        TIMEOUT_PROPERTY,
        120,  # 2 minutes
    )

  def ios_debug_symbol_doctor(self, diagnose_first=True):
    """Call the ios_debug_symbol_doctor entrypoint of the Device Doctor.

    Args:
      diagnose_first:
        (bool) Whether diagnosis will be run initially before attempting to recover.
    """
    if not self.is_devicelab() or not self.m.platform.is_mac or not self.is_ios(
    ):
      # if no iPhone is attached, we don't need to recover ios debug symbols
      return
    with self.m.step.nest('ios_debug_symbol_doctor'):
      cocoon_path = self._checkout_cocoon()
      entrypoint = cocoon_path.join(
          'cipd_packages',
          'device_doctor',
          'bin',
          'ios_debug_symbol_doctor.dart',
      )

      timeout = self._get_initial_timeout()
      # Since we double the timeout on each retry, the last retry will have a
      # timeout of 16 minutes
      retry_count = 4
      with self.m.context(cwd=cocoon_path.join('cipd_packages',
                                               'device_doctor'),
                          infra_steps=True):
        self.m.step(
            'pub get device_doctor',
            ['dart', 'pub', 'get'],
        )
        if diagnose_first:
          clean_results = self._diagnose_debug_symbols(
              entrypoint, timeout, cocoon_path
          )
          if clean_results:
            # It doesn't appear debug symbols need to be sync'd, we are finished
            return
        for _ in range(retry_count):
          self._recover_debug_symbols(entrypoint, timeout, cocoon_path)
          result = self._diagnose_debug_symbols(
              entrypoint, timeout, cocoon_path
          )
          if result:
            # attached devices don't have errors
            return
          # Try for twice as long next time
          timeout *= 2

        message = '''
The ios_debug_symbol_doctor is detecting phones attached with errors and failed
to recover this bot with a timeout of %s seconds.

See https://github.com/flutter/flutter/issues/103511 for more context.
''' % timeout
        # raise purple
        self.m.step.empty(
            'Recovery failed after %s attempts' % retry_count,
            status=self.m.step.INFRA_FAILURE,
            step_text=message,
        )

  def prepare_ios_device(self):
    """Prepare iOS device for running tests.

    If the device is a CoreDevice (physical iOS 17+ devices), wait for the
    device to show as connected.

    Dismisses iOS and macOS dialogs to avoid problems.

    Args:
      flutter_path(Path): A path to the checkout of the flutter sdk repository.
    """
    if self.is_devicelab() and self.is_ios() and self.m.platform.is_mac:
      with self.m.step.nest('Prepare iOS device'):
        device_id = self.m.step(
            'Find device id', ['idevice_id', '-l'],
            stdout=self.m.raw_io.output_text()
        ).stdout.rstrip()

        is_core_device = self._is_core_device(device_id)

        cocoon_path = self._checkout_cocoon()

        if is_core_device:
          with self.m.step.nest('Wait for device to connect'
                               ) as wait_connect_step:
            try:
              self._is_core_device_connected(device_id)
            except self.m.step.InfraFailure:
              infra_dialog_project_path = self._infra_dialog_directory_path(
                  cocoon_path
              ).join('infra-dialog.xcodeproj')
              self.m.step(
                  'Open infra-dialog in Xcode',
                  ['open', infra_dialog_project_path],
              )
              # Open device in QuickTime to try to establish a connection.
              self._open_quick_time(device_id)

              # Wait up to ~5 minutes for device to connect.
              try:
                self.m.retry.basic_wrap(
                    lambda timeout: self._is_core_device_connected(
                        device_id,
                        timeout=timeout,
                    ),
                    step_name='Wait for device to connect',
                    sleep=10.0,
                    backoff_factor=2,
                    max_attempts=6
                )
              except self.m.step.InfraFailure:
                # If step fails, continue to "Run app to dismiss dialogs" step.
                # That step should also fail.
                wait_connect_step.status = self.m.step.INFRA_FAILURE
              finally:
                self._list_core_devices()
                self.m.step(
                    'Kill Xcode',
                    ['killall', '-9', '-v', 'Xcode'],
                    ok_ret='any',
                )

        with self.m.step.nest('Dismiss iOS dialogs'):
          resource_name = self.resource('dismiss_dialogs.sh')
          self.m.step(
              'Set execute permission',
              ['chmod', '755', resource_name],
              infra_step=True,
          )
          with self.m.context(
              cwd=self._infra_dialog_directory_path(cocoon_path),
              infra_steps=True,
          ):
            cmd = [resource_name, device_id]
            try:
              self.m.step('Run app to dismiss dialogs', cmd)
            finally:
              self._list_core_devices()
              self.m.step(
                  'Kill QuickTime',
                  ['killall', '-9', '-v', 'QuickTime Player'],
                  ok_ret='any',
              )
        with self.m.step.nest('Dismiss Xcode automation dialogs'):
          with self.m.context(infra_steps=True):
            builder_name = self.m.properties.get('buildername')
            self.m.step.empty("Get buildername", step_text=builder_name)

            # Only required for CoreDevices (physical iOS 17+ devices) or
            # "xcode_debug" tests. Builders with 'xcode_debug' in the name
            # force tests the workflow that requires this permission.
            if is_core_device or 'xcode_debug' in builder_name:
              self._dismiss_automation_dialog('Xcode', 'com.apple.dt.Xcode')

  def _infra_dialog_directory_path(self, cocoon_path):
    return cocoon_path.join(
        'cipd_packages', 'device_doctor', 'tool', 'infra-dialog'
    )

  def _open_quick_time(self, device_id):
    """Gives permissions to automate QuickTime. Then opens QuickTime with
    screen and audio to set to `device_id`.

    Opening QuickTime and switching the "Screen" to the device may help the
    device connect.

    Args:
      device_id(string): A string of the selected device's UDID.
    """
    with self.m.step.nest('Trigger device connect with QuickTime'):
      with self.m.context(infra_steps=True):
        with self.m.step.nest('Dismiss QuickTime automation dialogs'):
          self._dismiss_automation_dialog(
              'QuickTime Player', 'com.apple.QuickTimePlayerX'
          )
        self.m.step(
            'Open QuickTime',
            ['open', '-a', 'QuickTime Player'],
        )
        self.m.step(
            'Set Audio Device in QuickTime',
            [
                'defaults', 'write', 'com.apple.QuickTimePlayerX',
                'MGDeviceRecordingDocumentViewControllerAudioDeviceSelectionUniqueID',
                device_id
            ],
        )
        self.m.step(
            'Set Video Device in QuickTime',
            [
                'defaults', 'write', 'com.apple.QuickTimePlayerX',
                'MGDeviceRecordingDocumentViewControllerVideoDeviceSelectionUniqueID',
                device_id
            ],
        )
        self.m.step(
            'View defaults in QuickTime',
            ['defaults', 'read', 'com.apple.QuickTimePlayerX'],
        )

        self._apple_script_command(
            'Open QuickTime Recording',
            'QuickTime Player',
            ['new movie recording'],
            timeout=30,
        )
        # For some reason, the first time you open a QuickTime recording, the
        # device will not be selected. Close the window and try again. The
        # second time should work.
        self._apple_script_command(
            'Close QuickTime Recording',
            'QuickTime Player',
            ['close its front window'],
            timeout=30,
        )
        self._apple_script_command(
            'Open QuickTime Recording',
            'QuickTime Player',
            ['new movie recording'],
            timeout=30,
        )

  def _apple_script_command(
      self,
      title,
      app_name,
      commands,
      timeout=2,
      raise_on_failure=False,
  ):
    """Run an AppleScript command.

    Args:
      title(string): A string of step's title.
      app_name(string): The name of the app to tell the commands to.
      commands(list): A list of strings of commands to tell the app to do.
      timeout (int or float): How many seconds to wait before timing out the step.
      raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.
    """

    apple_script_to_run = []
    for command in commands:
      apple_script_to_run.append('-e')
      apple_script_to_run.append(command)
    self.m.step(
        title,
        [
            'osascript',
            '-e',
            'tell app "%s"' % app_name,
            *apple_script_to_run,
            '-e',
            'end tell',
        ],
        raise_on_failure=raise_on_failure,
        ok_ret=(0,) if raise_on_failure else 'any',
        timeout=timeout,
    )

  def _list_core_devices(self):
    """Get list of CoreDevices.
    Allow any return code and ignore failure since this command will only
    work with Xcode 15 and therefore may not work for all machines.
    """
    device_list = self.m.step(
        'List CoreDevices',
        [
            'xcrun',
            'devicectl',
            'list',
            'devices',
            '-v',
        ],
        raise_on_failure=False,
        ok_ret='any',
        stdout=self.m.raw_io.output_text(add_output_log=True),
    ).stdout.rstrip()

    return device_list

  def _is_core_device(self, device_id):
    """Check if device is a CoreDevice (physical iOS 17+ devices).

    Only CoreDevices appear in `devicectl list devices` command.

    Args:
      device_id(string): A string of the selected device's UDID.
    """
    device_list = self._list_core_devices()

    if device_id in device_list:
      return True
    return False

  # pylint: disable=unused-argument
  def _is_core_device_connected(self, device_id, timeout=None):
    """Use `devicectl` command to determine if device is connected via cable.
    Only accept if `transportType` is wired in case other devices are paired
    but not connected via cable (aka connected wirelessly).

    Args:
      device_id(string): A string of the selected device's UDID.

    Throws an InfraFailure if device is not connected.
    """
    device_list = self.m.step(
        'Find wired CoreDevices',
        [
            'xcrun',
            'devicectl',
            'list',
            'devices',
            '--filter',
            "connectionProperties.transportType CONTAINS 'wired'",
            '-v',
        ],
        stdout=self.m.raw_io.output_text(add_output_log=True),
    ).stdout.rstrip()

    if device_id not in device_list:
      raise self.m.step.InfraFailure('Device not connected.')

  def _dismiss_automation_dialog(self, app_name, app_identifer):
    """Dismiss automation permission dialog and update permission db.

    Args:
      app_name(string): Name of the application to get permission for.
      app_identifer(string): Bundle id of the application.
    """

    tcc_directory_path, db_path, backup_db_path = self._get_tcc_path()

    # Ensure db exists
    files = self.m.step(
        'Find TCC directory',
        ['ls', tcc_directory_path],
        stdout=self.m.raw_io.output_text(add_output_log=True),
    ).stdout.rstrip()

    if TCC_AUTOMATION_DB not in files:
      self.m.step.empty(
          'Failed to find TCC.db',
          status=self.m.step.INFRA_FAILURE,
      )

    # Print contents of db for potential debugging purposes.
    self._query_automation_db_step_with_retry(db_path)

    # Create backup db if there isn't one.
    # If there is already a backup, it's most likely that a previous run did
    # not complete correctly and did not get reset, so don't overwrite the backup.
    if TCC_AUTOMATION_BACKUP_DB not in files:
      self.m.step(
          'Create backup db',
          ['cp', db_path, backup_db_path],
      )

    self.m.retry.basic_wrap(
        lambda timeout: self._create_tcc_entry(
            db_path,
            app_name,
            app_identifer,
            timeout=timeout,
        ),
        step_name='Wait to add entry in TCC db',
        sleep=2.0,
        backoff_factor=2,
        max_attempts=3,
        timeout=2,
    )

    # Update TCC.db. If fails, try up to 3 times. It may fail if the db is locked.
    self.m.retry.basic_wrap(
        lambda timeout: self._update_automation_permission_db(
            db_path,
            app_identifer,
            timeout=timeout,
        ),
        step_name='Wait to update TCC db',
        sleep=2.0,
        backoff_factor=2,
        max_attempts=3
    )

    # Print contents of db for potential debugging purposes.
    self._query_automation_db_step_with_retry(db_path)

    # Try and trigger automation. If fails or times out, permission was
    # not successfully granted.
    self._trigger_and_dismiss_automation_permission(
        app_name,
        timeout=5 * 60,
        raise_on_failure=True,
    )

    # The app was opened by Applescript, so kill it.
    self.m.step(
        'Kill %s' % app_name,
        ['killall', '-9', '-v', app_name],
        ok_ret='any',
    )

  def _dismiss_automation_permission(self):
    """Kill the automation dialog. After killing the dialog, an entry for
    the client requesting control of app should automatically be added to the db.
    """

    self.m.step(
        'Dismiss dialog',
        ['killall', '-9', '-v', 'UserNotificationCenter'],
        ok_ret='any',
    )

  def _trigger_and_dismiss_automation_permission(
      self, app_name, timeout=2, raise_on_failure=False
  ):
    """Trigger automation dialog to appear and then kill the dialog.

    Args:
      app_name(string): Name of the application to get permission for.
      timeout (int or float): How many seconds to wait before timing out the
              "Trigger dialog" step.
      raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.
    """

    # Run an arbitrary AppleScript command to trigger permissions dialog.
    # The AppleScript counts how many windows of the app are open.
    # The script will hang if permission has not been given, so timeout after
    # a few seconds.
    try:
      self._apple_script_command(
          'Trigger dialog',
          app_name,
          ['launch', 'count window'],
          timeout,
          raise_on_failure,
      )
    finally:
      self._dismiss_automation_permission()

  def _create_tcc_entry(self, db_path, app_name, app_identifer, timeout=2):
    """Trigger automation dialog to appear and then kill the dialog.
    Killing the dialog will add an entry for the permission to the TCC.db.
    Raises an error if dialog fails to add entry to db.

    Args:
      app_name(string): Name of the application to get permission for.
      app_identifer(string): Bundle id of the application.
      db_path(string): A string of the path to the sqlite database.
    """

    self._trigger_and_dismiss_automation_permission(app_name, timeout=timeout)

    if app_identifer not in self._query_automation_db_step_with_retry(db_path):
      raise self.m.step.InfraFailure(
          '%s entry not found in TCC.db' % app_identifer
      )

  def _get_tcc_path(self):
    """Constructs paths to the TCC directory, TCC db, and TCC backup db.

    Returns:
        A tuple of strings representing the paths to the TCC directory, TCC db, and TCC backup db.
    """
    home_path = 'Users/fakeuser' if self._test_data.enabled else os.environ.get(
        'HOME'
    )
    tcc_directory_path = os.path.join(
        str(home_path), 'Library/Application Support/com.apple.TCC'
    )
    db_path = os.path.join(tcc_directory_path, TCC_AUTOMATION_DB)
    backup_db_path = os.path.join(tcc_directory_path, TCC_AUTOMATION_BACKUP_DB)
    return tcc_directory_path, db_path, backup_db_path

  # pylint: disable=unused-argument
  def _update_automation_permission_db(
      self, db_path, app_identifer, timeout=None
  ):
    self.m.step(
        'Update db',
        [
            'sqlite3', db_path,
            "UPDATE access SET auth_value = 2, auth_reason = 3, flags = NULL WHERE service = 'kTCCServiceAppleEvents' AND indirect_object_identifier = '%s'"
            % app_identifer
        ],
    )

  def _query_automation_db_step_with_retry(self, db_path):
    """Queries the TCC database with 3 retries. Sometimes if the database is
    locked, query will fail. So wait and try again.

    Args:
      db_path(string): A string of the path to the sqlite database.

    Returns:
      A string of the query's output.
    """

    return self.m.retry.basic_wrap(
        lambda timeout: self._query_automation_db_step(
            db_path,
            timeout=timeout,
        ),
        step_name='Wait to query TCC db',
        sleep=2.0,
        backoff_factor=1,
        max_attempts=3
    )

  # pylint: disable=unused-argument
  def _query_automation_db_step(self, db_path, timeout=None):
    """Queries the TCC database.

    Args:
      db_path(string): A string of the path to the sqlite database.

    Returns:
      A string of the query's output.
    """
    query_results = self.m.step(
        'Query TCC db',
        [
            'sqlite3', db_path,
            'SELECT service, client, client_type, auth_value, auth_reason, indirect_object_identifier_type, indirect_object_identifier, flags, last_modified FROM access WHERE service = "kTCCServiceAppleEvents"'
        ],
        stdout=self.m.raw_io.output_text(add_output_log=True),
    )

    return query_results.stdout.rstrip()

  def _checkout_cocoon(self):
    """Checkout cocoon at HEAD to the cache and return the path."""
    cocoon_path = self.m.path['cache'].join('cocoon')
    self.m.repo_util.checkout('cocoon', cocoon_path, ref='refs/heads/main')
    return cocoon_path

  def _diagnose_debug_symbols(self, entrypoint, timeout, cocoon_path):
    """Diagnose if attached phones have errors with debug symbols.

    If there are errors, a recovery will be attempted. This function is intended
    to be called in a retry loop until it returns True, or until a max retry
    count is reached.

    Returns a boolean for whether or not the initial diagnose succeeded.
    """
    try:
      self.m.step(
          'diagnose',
          ['dart', entrypoint, 'diagnose'],
      )
      return True
    except self.m.step.StepFailure as e:
      return False

  def _recover_debug_symbols(self, entrypoint, timeout, cocoon_path):
    self.m.step(
        'recover with %s second timeout' % timeout,
        [
            'dart',
            entrypoint,
            'recover',
            '--cocoon-root',
            cocoon_path,
            '--timeout',
            timeout,
        ],
    )

  def is_devicelab(self):
    return str(self.m.swarming.bot_id).startswith('flutter-devicelab') or str(
        self.m.swarming.bot_id
    ).startswith('flutter-win')

  def is_ios(self):
    device_os = self.m.properties.get('device_os', '')
    return device_os.lower().startswith('ios-')

  def is_vs_installed(self, version=None):
    if not self.m.platform.is_win:
      return False

    vswhere_path = self.m.path.join(
        os.environ.get('PROGRAMFILES(X86)'),
        'Microsoft Visual Studio',
        'Installer',
        'vswhere.exe',
    )

    # Return mocked result for testing.
    vswhereexists = self._test_data.get(
        'vswhereexists', True
    ) if self._test_data.enabled else self.m.path.exists(vswhere_path)

    # Return False if vswhere does not exist.
    if not vswhereexists:
      return False

    result = self.m.step(
        'Detect installation',
        [vswhere_path, '-legacy', '-prerelease', '-format', 'json'],
        stdout=self.m.json.output()
    )

    # If no version is provided any vs_build installed version is ok.
    if not version:
      return len(result.stdout) > 0

    # If version is provided we look for that specific version in the installations.
    for installation in result.stdout:
      if installation.get('catalog', {}).get('productLineVersion') == version:
        return True

    return False
