# 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 copy
from recipe_engine import recipe_api


class FlutterDepsApi(recipe_api.RecipeApi):
  """Utilities to install flutter build/test dependencies at runtime."""

  def flutter_engine(self, env, env_prefixes):
    """Sets the local engine related information to environment variables.

    If the drone is started to run the tests with a local engine, it will
    contain a `local_engine_cas_hash` property where we can download engine files.
    If the `local_engine` property is present, it will override the
    default build configuration name, "host_debug_unopt"

    Similarly, if the drone is started to run the tests against a local web
    sdk, it will contain a `local_web_sdk_cas_hash` property.
    If the `local_web_sdk` property is present, it will override the default
    build configuration name, "wasm_release"

    These files will be located in the build folder, whose name comes
    from the build configuration.
    Args:

      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    # No-op if `local_engine_cas_hash` property is empty
    cas_hash = self.m.properties.get('local_engine_cas_hash')
    if cas_hash:
      checkout_engine = self.m.path['cleanup'].join('builder', 'src', 'out')
      # Download built engines from CAS.
      if cas_hash:
        self.m.cas.download(
            'Download engine from CAS', cas_hash, checkout_engine
        )
      local_engine = checkout_engine.join(self.m.properties.get('local_engine'))
      local_engine_host = self.m.properties.get('local_engine_host')
      dart_bin = local_engine.join('dart-sdk', 'bin')
      paths = env_prefixes.get('PATH', [])
      paths.insert(0, dart_bin)
      env_prefixes['PATH'] = paths
      env['LOCAL_ENGINE'] = local_engine
      env['LOCAL_ENGINE_HOST'] = local_engine_host

    web_sdk_cas_hash = self.m.properties.get('local_web_sdk_cas_hash')
    local_web_sdk = self.m.properties.get('local_web_sdk')
    if web_sdk_cas_hash:
      checkout_src = self.m.path['cleanup'].join('builder', 'src')
      self.m.cas.download(
          'Download web sdk from CAS', web_sdk_cas_hash, checkout_src
      )
      local_web_sdk = checkout_src.join('out', local_web_sdk or 'wasm_release')
      dart_bin = checkout_src.join(
          'flutter', 'prebuilts', '${platform}', 'dart-sdk', 'bin'
      )
      paths = env_prefixes.get('PATH', [])
      paths.insert(0, dart_bin)
      env_prefixes['PATH'] = paths
      env['LOCAL_WEB_SDK'] = local_web_sdk

  def required_deps(self, env, env_prefixes, deps):
    """Install all the required dependencies for a given builder.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      deps(list(dict)): A list of dictionaries with dependencies as
        {'dependency': 'android_sdk', version: ''} where an empty version
        means the default.
    """
    available_deps = {
        'android_sdk': self.android_sdk,
        'android_virtual_device': self.android_virtual_device,
        'avd_cipd_version': self.avd_cipd_version,
        'apple_signing': self.apple_signing,
        'arm_tools': self.arm_tools,
        'certs': self.certs,
        'chrome_and_driver': self.chrome_and_driver,
        'clang': self.clang,
        'cmake': self.cmake,
        'codesign': self.codesign,
        'cosign': self.cosign,
        'curl': self.curl,
        'dart_sdk': self.dart_sdk,
        'dashing': self.dashing,
        'doxygen': self.doxygen,
        'firebase': self.firebase,
        'firefox': self.firefox,
        'gh_cli': self.gh_cli,
        'go_sdk': self.go_sdk,
        'goldctl': self.goldctl,
        'gradle_cache': self.gradle_cache,
        'ios_signing':
            self.
            apple_signing,  # TODO(drewroen): Remove this line once ios_signing is not being referenced
        'ktlint': self.ktlint,
        'ninja': self.ninja,
        'open_jdk': self.open_jdk,
        'ruby': self.ruby,
        'swift_format': self.swift_format,
        'vs_build': self.vs_build,
    }
    parsed_deps = []
    for dep in deps:
      dependency = dep.get('dependency')
      version = dep.get('version')
      # Ensure there are no duplicate entries
      if dependency in parsed_deps:
        msg = '''Dependency {} is duplicated
            Ensure ci.yaml contains only one entry for this target
            '''.format(dependency)
        raise ValueError(msg)
      parsed_deps.append(dependency)
      if dependency in ['xcode']:
        continue
      dep_funct = available_deps.get(dependency)
      if not dep_funct:
        msg = '''Dependency {} not available.
            Ensure ci.yaml contains one of the following supported keys:
            {}
            If this is a new dependency, update https://cs.opensource.google/flutter/recipes/+/main:recipe_modules/flutter_deps/api.py
            '''.format(dependency, available_deps.keys())
        raise ValueError(msg)
      dep_funct(env, env_prefixes, version)

  def android_virtual_device(self, env, env_prefixes, version):
    """Simply sets the version of the emulator globally as the module will download the package itself.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The android virtual device version to install.
    """
    env['USE_EMULATOR'] = True
    env['EMULATOR_VERSION'] = version

  def avd_cipd_version(self, env, env_prefixes, version):
    """Simply set the avd_cipd_version of emulator package globally.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict): current environment prefixes variables.
      version(str): the tagged version of the avd proto configs for android virtual devices.
    """
    env['AVD_CIPD_VERSION'] = version

  def open_jdk(self, env, env_prefixes, version):
    """Downloads OpenJdk CIPD package and updates environment variables.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The OpenJdk version to install.
    """
    version = version or 'version:11'
    with self.m.step.nest('OpenJDK dependency'):
      java_cache_dir = self.m.path['cache'].join('java')
      self.m.cipd.ensure(
          java_cache_dir,
          self.m.cipd.EnsureFile().add_package(
              'flutter/java/openjdk/${platform}', version
          )
      )
      java_home = java_cache_dir
      if self.m.platform.is_mac:
        java_home = java_cache_dir.join('contents', 'Home')

      env['JAVA_HOME'] = java_home
      path = env_prefixes.get('PATH', [])
      path.append(java_home.join('bin'))
      env_prefixes['PATH'] = path

  def arm_tools(self, env, env_prefixes, version=None):
    """Downloads Arm Tools CIPD package and updates environment variables.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The Arm Tools version to install.
    """
    version = version or 'last_updated:2023-02-03T15:32:01-0800'
    with self.m.step.nest('Arm Tools dependency'):
      arm_tools_cache_dir = self.m.path['cache'].join('arm-tools')
      self.m.cipd.ensure(
          self.m.path['cache'],
          self.m.cipd.EnsureFile().add_package(
              'flutter_internal/tools/arm-tools', version
          )
      )
      self.m.file.listdir('arm-tools contents', arm_tools_cache_dir)
      self.m.file.listdir(
          'arm-tools malioc contents',
          arm_tools_cache_dir.join('mali_offline_compiler')
      )
      env['ARM_TOOLS'] = arm_tools_cache_dir
      env['MALIOC_PATH'] = arm_tools_cache_dir.join(
          'mali_offline_compiler', 'malioc'
      )

  def goldctl(self, env, env_prefixes, version):
    """Downloads goldctl from CIPD and updates the environment variables.

    To roll to a new version of goldctl visit this page:

    https://chrome-infra-packages.appspot.com/p/skia/tools/goldctl

    Select linux-amd64 and click on a package marked "latest". In the "Tags"
    section find the freshest tag prefixed with `git_revision`. Copy the value
    of the tag including "git_revision:" and the SHA following it, for example:

    git_revision:somelongshacontainingnumbersandletters12

    Then replace the default value of `version` variable in this function with
    it.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The goldctl version to install.
    """
    # Noop for official builds. Skia gold service supports only main/master
    # branch.
    if self.m.flutter_bcid.is_official_build():
      return

    version = version or 'git_revision:720a542f6fe4f92922c3b8f0fdcc4d2ac6bb83cd'
    with self.m.step.nest('Download goldctl'):
      goldctl_cache_dir = self.m.path['cache'].join('gold')
      self.m.cipd.ensure(
          goldctl_cache_dir,
          self.m.cipd.EnsureFile().add_package(
              'skia/tools/goldctl/${platform}', version
          )
      )
      env['GOLDCTL'] = goldctl_cache_dir.join('goldctl')

    if self.m.properties.get('git_ref') and self.m.properties.get('gold_tryjob'
                                                                 ) == True:
      env['GOLD_TRYJOB'] = self.m.properties.get('git_ref')

  def chrome_and_driver(self, env, env_prefixes, version):
    """Downloads chrome from CIPD and updates the environment variables.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The Chrome version to install.
    """
    version = version or 'latest'
    with self.m.step.nest('Chrome and driver dependency'):
      env['CHROME_NO_SANDBOX'] = 'true'
      chrome_path = self.m.path['cache'].join('chrome', 'chrome')
      pkgs = self.m.cipd.EnsureFile()
      pkgs.add_package('flutter_internal/browsers/chrome/${platform}', version)
      self.m.cipd.ensure(chrome_path, pkgs)
      chrome_driver_path = self.m.path['cache'].join('chrome', 'drivers')
      pkgdriver = self.m.cipd.EnsureFile()
      pkgdriver.add_package(
          'flutter_internal/browser-drivers/chrome/${platform}', version
      )
      self.m.cipd.ensure(chrome_driver_path, pkgdriver)
      paths = env_prefixes.get('PATH', [])
      paths.append(chrome_path)
      paths.append(chrome_driver_path)
      env_prefixes['PATH'] = paths
      binary_name = 'chrome.exe' if self.m.platform.is_win else 'chrome'
      if self.m.platform.is_mac:
        if version.count('.') == 1:
          # This is the old mac path for vanilla Chromium, which is expressed
          # as just a major and minor version (e.g. 117.0)
          exec_path = chrome_path.join(
              'chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'
          )
        else:
          # Google Chrome For Testing path, which is usually expressed with a
          # four part version number (e.g. 117.0.5938.149)
          exec_path = chrome_path.join(
              'Google Chrome for Testing.app', 'Contents', 'MacOS',
              'Google Chrome for Testing'
          )
        env['CHROME_EXECUTABLE'] = exec_path
      else:
        env['CHROME_EXECUTABLE'] = chrome_path.join(binary_name)

  def firefox(self, env, env_prefixes, version):
    """Downloads Firefox from CIPD and updates the environment variables.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
      version(str): The Firefox version to install.
    """
    version = version or 'latest'
    with self.m.step.nest('Firefox dependency'):
      firefox_path = self.m.path['cache'].join('firefox')
      pkgs = self.m.cipd.EnsureFile()
      pkgs.add_package('flutter_internal/browsers/firefox/${platform}', version)
      self.m.cipd.ensure(firefox_path, pkgs)
      paths = env_prefixes.get('PATH', [])
      paths.append(firefox_path)
      env_prefixes['PATH'] = paths
      env['FIREFOX_EXECUTABLE'] = firefox_path.join('firefox')

  def gh_cli(self, env, env_prefixes, version):
    """Installs GitHub CLI."""
    version = version or 'latest'
    gh_path = self.m.path['cache'].join('gh-cli')
    gh_file = self.m.cipd.EnsureFile()
    gh_file.add_package('flutter_internal/tools/gh-cli/${platform}', version)
    self.m.cipd.ensure(gh_path, gh_file)
    self.m.step('check gh version', [gh_path.join('bin', 'gh'), '--version'])
    paths = env_prefixes.get('PATH', [])
    paths.append(gh_path.join('bin'))
    env_prefixes['PATH'] = paths

  def go_sdk(self, env, env_prefixes, version):
    """Installs go sdk."""
    go_path = self.m.path['cache'].join('go')
    go = self.m.cipd.EnsureFile()
    go.add_package('infra/3pp/tools/go/${platform}', version)
    self.m.cipd.ensure(go_path, go)
    paths = env_prefixes.get('PATH', [])
    paths.append(go_path.join('bin'))
    # Setup GOPATH and add to the env.
    bin_path = self.m.path['cleanup'].join('go_path')
    self.m.file.ensure_directory('Ensure go path', bin_path)
    env['GOPATH'] = bin_path
    paths.append(bin_path.join('bin'))
    env_prefixes['PATH'] = paths

  def dashing(self, env, env_prefixes, version):
    """Installs dashing."""
    version = version or '0.4.0'
    self.go_sdk(env, env_prefixes, 'version:2@1.19.3')
    with self.m.context(env=env, env_prefixes=env_prefixes):
      self.m.step(
          'Install dashing',
          ['go', 'install',
           'github.com/technosophos/dashing@%s' % version],
          infra_step=True,
      )

  def doxygen(self, _, env_prefixes, version):
    """Installs doxygen."""
    version = version or 'latest'
    doxygen_path = self.m.path.mkdtemp().join('doxygen')
    doxygen = self.m.cipd.EnsureFile()
    doxygen.add_package('flutter/doxygen/${platform}', version)
    self.m.cipd.ensure(doxygen_path, doxygen)
    paths = env_prefixes.get('PATH', [])
    paths.append(doxygen_path.join('bin'))
    env_prefixes['PATH'] = paths

  def curl(self, _, env_prefixes, version):
    """Installs curl."""
    version = version or 'latest'
    curl_path = self.m.path.mkdtemp().join('curl')
    curl = self.m.cipd.EnsureFile()
    curl.add_package('flutter_internal/tools/curl/${platform}', version)
    self.m.cipd.ensure(curl_path, curl)
    paths = env_prefixes.get('PATH', [])
    paths.append(curl_path)
    env_prefixes['PATH'] = paths

  def android_sdk(self, env, env_prefixes, version):
    """Installs android sdk."""
    version = version or 'latest'
    sdk_root = self.m.path['cache'].join('android')
    self.m.cipd.ensure(
        sdk_root,
        self.m.cipd.EnsureFile().add_package(
            'flutter/android/sdk/all/${platform}',
            version,
        ),
    )
    # Setup environment variables
    if (version == 'version:29.0'):  # Handle the legacy case
      env['ANDROID_SDK_ROOT'] = sdk_root
      env['ANDROID_HOME'] = sdk_root
      env['ANDROID_NDK_PATH'] = sdk_root.join('ndk-bundle')
    else:
      env['ANDROID_SDK_ROOT'] = sdk_root.join('sdk')
      env['ANDROID_HOME'] = sdk_root.join('sdk')
      env['ANDROID_NDK_PATH'] = sdk_root.join('ndk')
    android_tmp = self.m.path.mkdtemp()
    env['ANDROID_SDK_HOME'] = android_tmp
    env['ANDROID_USER_HOME'] = android_tmp.join('.android')
    self.gradle_cache(env, env_prefixes, version)

  def gradle_cache(self, env, env_prefixes, version):
    # Specify the location of the shared cache used by Gradle builds.
    # This cache contains dependencies downloaded from network when a Gradle task is run.
    # When a cache hit occurs, the dependency is immediately provided to the Gradle build.
    env['GRADLE_USER_HOME'] = self.m.path['cache'].join('gradle')
    # Disable the Gradle daemon. Some builders aren't ephemeral, which means that state leaks out potentially
    # leaving the bot in a bad state.
    # For more, see CI section on https://docs.gradle.org/current/userguide/gradle_daemon.html#sec:disabling_the_daemon
    env['GRADLE_OPTS'] = '-Dorg.gradle.daemon=false'
    self.m.file.listdir(
        'gradle cache', self.m.path['cache'].join('gradle'), recursive=True
    )

  def firebase(self, env, env_prefixes, version='latest'):
    """Installs firebase binary.

    This dependency is only supported in linux.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    firebase_dir = self.m.path['start_dir'].join('firebase')
    self.m.file.ensure_directory('ensure directory', firebase_dir)
    with self.m.step.nest('Install firebase'):
      self.m.step(
          'Install firebase bin',
          [
              'curl', '-Lo',
              firebase_dir.join('firebase'),
              'https://github.com/firebase/firebase-tools/releases/download/v12.9.1/firebase-tools-linux'
          ],
          infra_step=True,
      )
      self.m.step(
          'Set execute permission',
          ['chmod', '755', firebase_dir.join('firebase')],
          infra_step=True,
      )
    paths = env_prefixes.get('PATH', [])
    paths.append(firebase_dir)
    env_prefixes['PATH'] = paths

  def clang(self, env, env_prefixes, version=None):
    """Installs clang toolchain.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    version = version or 'git_revision:7e9747b50bcb1be28d4a3236571e8050835497a6'
    clang_path = self.m.path['cache'].join('clang')
    clang = self.m.cipd.EnsureFile()
    clang.add_package('fuchsia/third_party/clang/${platform}', version)
    with self.m.step.nest('Install clang'):
      self.m.cipd.ensure(clang_path, clang)
    paths = env_prefixes.get('PATH', [])
    paths.append(clang_path.join('bin'))
    env_prefixes['PATH'] = paths

  def cmake(self, env, env_prefixes, version=None):
    """Installs cmake.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    cmake_path = self.m.path['cache'].join('cmake')
    cmake = self.m.cipd.EnsureFile()
    version = version or 'build_id:8787856497187628321'
    cmake.add_package('infra/3pp/tools/cmake/${platform}', version)
    with self.m.step.nest('Install cmake'):
      self.m.cipd.ensure(cmake_path, cmake)
    paths = env_prefixes.get('PATH', [])
    paths.append(cmake_path.join('bin'))
    env_prefixes['PATH'] = paths

  def codesign(self, env, env_prefixes, version=None):
    """Installs codesign at https://chrome-infra-packages.appspot.com/p/flutter/codesign.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict): Current environment prefixes variables.
    """
    version = version or 'live'
    codesign_path = self.m.path.mkdtemp()
    codesign = self.m.cipd.EnsureFile()
    codesign.add_package('flutter/codesign/${platform}', version)
    with self.m.step.nest('Installing Mac codesign CIPD pkg'):
      self.m.cipd.ensure(codesign_path, codesign)
    paths = env_prefixes.get('PATH', [])
    paths.append(codesign_path)
    env_prefixes['PATH'] = paths
    return codesign_path.join('codesign')

  def cosign(self, env, env_prefixes, version=None):
    """Installs cosign.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict): Current environment prefixes variables.
    """
    version = version or 'latest'
    cosign_path = self.m.path['cache'].join('cosign')
    cosign = self.m.cipd.EnsureFile()
    cosign.add_package('flutter/tools/cosign/${platform}', version)
    with self.m.step.nest('Install cosign'):
      self.m.cipd.ensure(cosign_path, cosign)
    paths = env_prefixes.get('PATH', [])
    paths.append(cosign_path.join('bin'))
    env_prefixes['PATH'] = paths

  def ninja(self, env, env_prefixes, version=None):
    """Installs ninja.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    version = version or 'version:1.9.0'
    ninja_path = self.m.path['cache'].join('ninja')
    ninja = self.m.cipd.EnsureFile()
    ninja.add_package("infra/ninja/${platform}", version)
    with self.m.step.nest('Install ninja'):
      self.m.cipd.ensure(ninja_path, ninja)
    paths = env_prefixes.get('PATH', [])
    paths.append(ninja_path)
    env_prefixes['PATH'] = paths

  def dart_sdk(self, env, env_prefixes, version=None):
    """Installs dart sdk.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    version = version or 'stable'
    dart_sdk_path = self.m.path['cache'].join('dart_sdk')
    dart_sdk = self.m.cipd.EnsureFile()
    dart_sdk.add_package("dart/dart-sdk/${platform}", version)
    with self.m.step.nest('Install dart sdk'):
      self.m.cipd.ensure(dart_sdk_path, dart_sdk)
    paths = env_prefixes.get('PATH', [])
    paths.insert(0, dart_sdk_path)
    env_prefixes['PATH'] = paths

  def certs(self, env, env_prefixes, version=None):
    """Installs root certificates for windows.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    if not self.m.platform.is_win:
      # noop for non windows platforms.
      return
    version = version or 'latest'
    certs_path = self.m.path['cache'].join('certs')
    certs = self.m.cipd.EnsureFile()
    certs.add_package("flutter_internal/certs", version)
    with self.m.step.nest('Install certs'):
      self.m.cipd.ensure(certs_path, certs)
    paths = env_prefixes.get('PATH', [])
    paths.insert(0, certs_path)
    env_prefixes['PATH'] = paths
    with self.m.context(env=env, env_prefixes=env_prefixes, cwd=certs_path):
      self.m.step(
          'Install Certs',
          [
              'powershell.exe',
              certs_path.join('install.ps1'),
          ],
      )

  def swift_format(self, env, env_prefixes, version=None):
    """Installs swift-format Swift formatter and linter.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    if not self.m.platform.is_mac:
      # noop for non Mac platforms.
      return
    version = version or 'latest'
    swift_format_path = self.m.path['cache'].join('swift_format')
    sf = self.m.cipd.EnsureFile()
    sf.add_package("infra/3pp/tools/swift-format/${platform}", version)
    with self.m.step.nest('Install swift-format'):
      self.m.cipd.ensure(swift_format_path, sf)
    paths = env_prefixes.get('PATH', [])
    paths.append(swift_format_path)
    env_prefixes['PATH'] = paths

  def vs_build(self, env, env_prefixes, version=None):
    """Installs visual studio build.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    if not self.m.platform.is_win:
      # noop for non windows platforms.
      return

    version = version or 'latest'
    vs_path = self.m.path['cache'].join('vsbuild')
    vs = self.m.cipd.EnsureFile()
    vs.add_package("flutter_internal/windows/vsbuild", version)
    with self.m.step.nest('VSBuild') as presentation:
      # The vs expected version is already installed.
      if self.m.os_utils.is_vs_installed(version.replace('version:vs', '')):
        return
      self.m.cipd.ensure(vs_path, vs)
      paths = env_prefixes.get('PATH', [])
      paths.insert(0, vs_path)
      env_prefixes['PATH'] = paths
      installation_script = r"""
# Delete previous logs
Remove-Item "$env:TEMP\dd_installer_elevated_*"
Remove-Item "$env:TEMP\dd_setup_*"
Remove-Item "$env:TEMP\dd_vs_setup_*"
$process = Start-Process -FilePath vs_setup.exe -ArgumentList "--add", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", "--add", "Microsoft.VisualStudio.Component.Windows10SDK", "--add", "Microsoft.VisualStudio.Component.Windows10SDK.19041", "--add", "Microsoft.VisualStudio.Component.VC.CMake.Project", "--add", "Microsoft.VisualStudio.Workload.NativeDesktop", "--passive", "--noweb", "--wait", "--norestart" -Wait -PassThru
Write-Output $process.ExitCode
exit $process.ExitCode
"""
      install_script_path = self.m.path['cleanup'].join('install.ps1')
      self.m.file.write_text(
          'Write install script', install_script_path, installation_script
      )
      deferred = []
      with self.m.context(env=env, env_prefixes=env_prefixes, cwd=vs_path):
        deferred.append(
            self.m.defer(
                self.m.step,
                'Install', ['powershell.exe', install_script_path],
                timeout=10 * 60
            )
        )
        copy_script = r"""
$destination=$args[0]
Get-ChildItem -Path "$env:TEMP"
Copy-Item "$env:TEMP\dd_installer_elevated_*" "$destination"
Copy-Item "$env:TEMP\dd_setup_??????????????.log*" "$destination"
Copy-Item "$env:TEMP\dd_setup_*_errors.log" "$destination"
Copy-Item "$env:TEMP\dd_vs_setup_*" "$destination"
"""
        copy_script_path = self.m.path['cleanup'].join('copy.ps1')
        self.m.file.write_text(
            'Write copy script', copy_script_path, copy_script
        )
        logs_path = self.m.path.mkdtemp()
        self.m.file.ensure_directory('Ensure logs tmp folder', logs_path)
        deferred.append(
            self.m.defer(
                self.m.step,
                'Copy logs',
                ['powershell.exe', copy_script_path, logs_path],
            )
        )

        def collect_logs():
          logs = self.m.file.listdir('List logs', logs_path)
          for log in logs:
            log_name = self.m.path.basename(log)
            presentation.logs[log_name] = self.m.file.read_text(log_name, log)
          self.m.file.rmtree('Remove logs tmp folder', logs_path)

        deferred.append(self.m.defer(collect_logs))
      self.m.defer.collect(deferred)

  def apple_signing(self, env, env_prefixes, version=None):
    """Sets up mac for code signing.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    with self.m.step.nest('Prepare code signing'):
      # Unlock keychain for devicelab tasks.
      if self.m.os_utils.is_devicelab():
        self.m.step(
            'unlock login keychain',
            ['unlock_login_keychain.sh'],
            infra_step=True,
        )
      # Download and copy provisiong profile to default location for Chromium Host only bots.
      else:
        version = version or 'latest'
        mobileprovision_path = self.m.path.mkdtemp().join('mobileprovision')
        mobileprovision = self.m.cipd.EnsureFile()
        mobileprovision.add_package(
            'flutter_internal/mac/mobileprovision/${platform}', version
        )
        with self.m.step.nest('Installing Mac mobileprovision'):
          self.m.cipd.ensure(mobileprovision_path, mobileprovision)

        mobileprovision_profile = mobileprovision_path.join(
            'development.mobileprovision'
        )
        copy_script = self.resource('copy_mobileprovisioning_profile.sh')
        self.m.step('Set execute permission', ['chmod', '755', copy_script])
        self.m.step(
            'copy mobileprovisioning profile',
            [copy_script, mobileprovision_profile]
        )

      # See go/googler-flutter-signing about how to renew the Apple development
      # certificate and provisioning profile.
      env['FLUTTER_XCODE_CODE_SIGN_STYLE'] = 'Manual'
      env['FLUTTER_XCODE_DEVELOPMENT_TEAM'] = 'S8QB4VV633'
      env['FLUTTER_XCODE_PROVISIONING_PROFILE_SPECIFIER'
         ] = 'match Development *'

  # pylint: disable=unused-argument
  def ruby(self, env, env_prefixes, version=None):
    """Installs a self contained Ruby.

   Args:
     env(dict): Current environment variables.
     env_prefixes(dict):  Current environment prefixes variables.
    """
    version = version or 'latest'
    with self.m.step.nest('Install ruby'):
      ruby_path = self.m.path['cache'].join('ruby')
      ruby = self.m.cipd.EnsureFile()
      ruby.add_package('flutter/ruby/${platform}', version)
      self.m.cipd.ensure(ruby_path, ruby)
      paths = env_prefixes.get('PATH', [])
      paths.insert(0, ruby_path.join('bin'))
      env_prefixes['PATH'] = paths

  # pylint: disable=unused-argument
  def ktlint(self, env, env_prefixes, version=None):
    """Installs a dependency on ktlint.

    This dependency is only supported in linux.

    Args:
      env(dict): Current environment variables.
      env_prefixes(dict): Current environment prefixes variables.
    """
    version = version or 'latest'
    with self.m.step.nest('Install ktlint'):
      ktlint_path = self.m.path['cache'].join('ktlint')
      ktlint = self.m.cipd.EnsureFile()
      ktlint.add_package('flutter/ktlint/${platform}', version)
      self.m.cipd.ensure(ktlint_path, ktlint)
      self.m.step(
        'Set execute permission',
        ['chmod', '755', ktlint_path.join('ktlint')],
        infra_step=True,
      )
      paths = env_prefixes.get('PATH', [])
      paths.insert(0, ktlint_path)
      env_prefixes['PATH'] = paths

  def contexts(self):
    """Available contexts across recipes repository."""
    return {
        'metric_center_token': self.m.token_util.metric_center_token,
        'android_virtual_device': self.m.android_virtual_device,
        'osx_sdk': self.m.osx_sdk,
        'osx_sdk_devicelab': self.m.osx_sdk,
        'depot_tools_on_path': self.m.depot_tools.on_path,
    }

  def enter_contexts(self, exit_stack, contexts, env, env_prefixes):
    """Enter corresponding contexts to exit_stack.

    Args:
      exit_stack(ExitStack): Context manager for dynamic management of a stack of exit callbacks.
      contexts(list): List of required contexts.
      env(dict): Current environment variables.
      env_prefixes(dict):  Current environment prefixes variables.
    """
    available_contexts = self.contexts()
    params = (env, env_prefixes)
    for context in contexts:
      aux_params = params
      if context == 'osx_sdk':
        aux_params = ('ios',)
      if context == 'osx_sdk_devicelab':
        aux_params = ('ios', True)
      if context == 'android_virtual_device':
        aux_params = params + (env['EMULATOR_VERSION'],)  # pragma: nocover
      if context == 'depot_tools_on_path':
        aux_params = tuple()
      exit_stack.enter_context(available_contexts[context](*aux_params))
