# 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 print_pub_certs(self):
    """Prints pub.dev certificates."""
    cmd = (
        'gci -Recurse cert: |Where-Object {$_.Subject -like "*GTS CA 1D4*"'
        ' -or $_.FriendlyName -like "GlobalSign Root CA - R1" -or $_.Subject'
        ' -like "*GTS Root R1*"}'
    )
    if self.m.platform.is_win:
      self.m.step(
          'Print pub.dev certs',
          ['powershell.exe', cmd],
          infra_step=True,
      )

  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', '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', 'dart'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill flutter', ['killall', '-9', 'flutter'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Chrome', ['killall', '-9', 'Chrome'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Safari', ['killall', '-9', 'Safari'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill java', ['killall', '-9', 'java'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill adb', ['killall', '-9', 'adb'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill Xcode', ['killall', '-9', 'Xcode'],
            ok_ret='any',
            infra_step=True
        )
        self.m.step(
            'kill QuickTime', ['killall', '-9', 'QuickTime Player'],
            ok_ret='any',
            infra_step=True
        )
      else:
        self.m.step(
            'kill chrome', ['pkill', 'chrome'], ok_ret='any', infra_step=True
        )
        self.m.step(
            'kill dart', ['pkill', 'dart'], ok_ret='any', infra_step=True
        )
        self.m.step(
            'kill flutter', ['pkill', 'flutter'], ok_ret='any', infra_step=True
        )
        self.m.step(
            'kill java', ['pkill', 'java'], ok_ret='any', infra_step=True
        )
        self.m.step('kill adb', ['pkill', '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 fails continue to "Run app to dismiss dialogs" step. That
                # step should also fail.
                wait_connect_step.presentation.status = self.m.step.INFRA_FAILURE
              finally:
                self._list_core_devices()
                self.m.step(
                    'Kill Xcode',
                    ['killall', '-9', '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', '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', 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', '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.
    self._apple_script_command(
        'Trigger dialog',
        app_name,
        ['launch', 'count window'],
        timeout,
        raise_on_failure,
    )
    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 reset_automation_dialogs(self):
    """Reset Automation permissions."""
    if self.is_devicelab() and self.m.platform.is_mac:
      with self.m.step.nest('Reset automation dialogs'):
        tcc_directory_path, db_path, backup_db_path = self._get_tcc_path()

        self._dismiss_automation_permission()

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

        files = self.m.step(
            'Find TCC directory',
            ['ls', tcc_directory_path],
            stdout=self.m.raw_io.output_text(),
            infra_step=True,
            raise_on_failure=False,
            ok_ret='any',
        ).stdout.rstrip()

        if TCC_AUTOMATION_BACKUP_DB not in files:
          return

        self.m.step(
            'Restore from backup db',
            ['cp', backup_db_path, db_path],
        )
        self.m.step(
            'Remove backup',
            ['rm', backup_db_path],
        )

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

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

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