# 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.

REPOS = {
    'cocoon': 'https://flutter.googlesource.com/mirrors/cocoon',
    'engine': 'https://flutter.googlesource.com/mirrors/engine',
    'flutter': 'https://flutter.googlesource.com/mirrors/flutter',
    'flaux': 'https://flutter.googlesource.com/mirrors/flaux',
    'infra': 'https://flutter.googlesource.com/infra',
    'mirrors/engine': 'https://flutter.googlesource.com/mirrors/engine',
    'mirrors/flutter': 'https://flutter.googlesource.com/mirrors/flutter',
    'monorepo': 'https://dart.googlesource.com/monorepo',
    'openpay': 'https://dash-internal.googlesource.com/openpay',
    'packages': 'https://flutter.googlesource.com/mirrors/packages',
}

# TODO(keyonghan): deprecate when all repos are migrated to main.
REPO_BRANCHES = {
    'cocoon': 'main',
    'engine': 'main',
    'flutter': 'master',
    'flaux': 'master',
    'infra': 'main',
    'mirrors/engine': 'main',
    'mirrors/flutter': 'main',
    'mirrors/flaux': 'master',
    'monorepo': 'main',
    'openpay': 'main',
    'packages': 'main',
}

import re
from recipe_engine import recipe_api

# Buildbucket bucket for official builds.
OFFICIAL_BUILD_BUCKET = 'flutter'


class RepoUtilApi(recipe_api.RecipeApi):
  """Provides utilities to work with flutter repos."""

  def _setup_win_toolchain(self, env):
    """Setups local win toolchain if available."""
    if self.m.platform.is_win:
      toolchain_metadata_src = (
          self.m.path.cache_dir / 'builder/vs_toolchain_root/data.json'
      )
      self.m.path.mock_add_paths(toolchain_metadata_src)
      if self.m.path.exists(toolchain_metadata_src):
        toolchain_metadata_dst = (
            self.m.path.cache_dir / 'builder/src/build/win_toolchain.json'
        )
        self.m.file.copy(
            'copy win_toolchain_metadata', toolchain_metadata_src,
            toolchain_metadata_dst
        )
        data_file = (
            self.m.path.cache_dir / 'builder/vs_toolchain_root/data.json'
        )
        metadata = self.m.file.read_json(
            'read win toolchain metadata',
            data_file,
            test_data={'version': '2022'}
        )
        env['GYP_MSVS_VERSION'] = metadata['version']

  def _clobber_cache(self, checkout_path):
    """Deletes bot caches to provide a clean build environment."""
    # Ensure depot tools is in the path to prevent problems with vpython not
    # being found after a failure.
    with self.m.depot_tools.on_path():
      if self.m.path.exists(checkout_path):
        self.m.file.rmcontents('Clobber cache', checkout_path)
      git_cache_path = self.m.path.cache_dir / 'git'
      self.m.path.mock_add_directory(git_cache_path)
      if self.m.path.exists(git_cache_path):
        self.m.file.rmtree('Clobber git cache', git_cache_path)
      self.m.file.ensure_directory('Ensure checkout cache', checkout_path)

  def engine_checkout(
      self, checkout_path, env, env_prefixes, gclient_variables=None
  ):
    """Checkout code using gclient.

    Args:
      checkout_path(Path): The path to checkout source code and dependencies.
      env(dict): A dictionary with the environment variables to set.
      env_prefixes(dict): A dictionary with the paths to be added to environment variables.
      gclient_variables(dict): A dictionary with custom gclient variables.
    """
    # Set vs_toolchain env to cache it.
    if self.m.platform.is_win:
      # Set win toolchain root to a directory inside cache/builder to cache it.
      env['DEPOT_TOOLS_WIN_TOOLCHAIN_ROOT'] = (
          self.m.path.cache_dir / 'builder/vs_toolchain_root'
      )
      env['DEPOT_TOOLS_WIN_TOOLCHAIN'] = 1

    bucket = self.m.buildbucket.build.builder.bucket
    # Calculate if we need to clean the source code cache.
    clobber = self.m.properties.get('clobber', False)

    # Calculate if we need to mount the cache and mount it if required.
    mount_git = self.m.cache.should_force_mount(self.m.path.cache_dir / 'git')
    mount_builder = self.m.cache.should_force_mount(
        self.m.path.cache_dir / 'builder'
    )
    if (not clobber) and (bucket != OFFICIAL_BUILD_BUCKET):
      self.m.cache.mount_cache('builder', force=True)
      self._setup_win_toolchain(env)
    # Grab any gclient custom variables passed as properties.
    if not gclient_variables:
      gclient_variables = self.m.properties.get('gclient_variables', {})
    local_custom_vars = self.m.shard_util.unfreeze_dict(gclient_variables)
    # Pass a special gclient variable to identify release candidate branch checkouts. This
    # is required to prevent trying to download experimental dependencies on release candidate
    # branches.
    branch = self.m.properties.get('git_branch',
                                   '') or self.get_branch(checkout_path)
    if branch.startswith('flutter-') or branch in [
        'beta', 'stable'
    ] or bucket == OFFICIAL_BUILD_BUCKET:
      local_custom_vars['release_candidate'] = True

      # Try doing a git clean of every repository.
      # This is an experiment that may serve as a faster alternative to
      # clobbering the entire cache for release branch builds.
      with self.m.step.nest('Clean the builder cache'), self.m.context(
          cwd=checkout_path):
        try:
          self.m.gclient(
              'git clean all repos', ['recurse', 'git', 'clean', '-fdx']
          )
        except self.m.step.StepFailure:
          # Fall back to clobbering if the cache is not in a state where it can
          # run a gclient command.
          self.m.step.empty('Falling back to clobbering the cache')
          clobber = True

    engine_repo = 'flutter'
    git_url = REPOS[engine_repo]
    git_id = self.m.buildbucket.gitiles_commit.id
    git_ref = self.m.buildbucket.gitiles_commit.ref
    if 'git_url' in self.m.properties and 'git_ref' in self.m.properties:
      git_url = self.m.properties['git_url']
      git_id = self.m.properties['git_ref']
      git_ref = self.m.properties['git_ref']

    repo_path = '.'
    default_branch = REPO_BRANCHES['flutter']

    # Inner function to execute code a second time in case of failure.
    # pylint: disable=unused-argument
    def _InnerCheckout(timeout=None):
      with self.m.step.nest('Checkout source code'):
        if clobber:
          self._clobber_cache(checkout_path)
        with self.m.context(env=env, env_prefixes=env_prefixes,
                            cwd=checkout_path), self.m.depot_tools.on_path():
          try:
            src_cfg = self.m.gclient.make_config()
            soln = src_cfg.solutions.add()
            soln.name = repo_path
            soln.url = git_url
            soln.revision = git_id
            soln.managed = False
            soln.custom_vars = local_custom_vars
            src_cfg.parent_got_revision_mapping['parent_got_revision'
                                               ] = 'got_revision'
            src_cfg.repo_path_map[git_url] = (
                repo_path, git_ref or 'refs/heads/%s' % default_branch
            )
            self.m.gclient.c = src_cfg
            self.m.gclient.c.got_revision_mapping[repo_path
                                                 ] = 'got_engine_revision'
            # Timeout the checkout at 45 mins to fail fast in slow checkouts so we can
            # retry.
            TIMEOUT_SECS = 45 * 60  # 45 mins.
            step_result = self.m.bot_update.ensure_checkout(
                timeout=TIMEOUT_SECS
            )
            if ('got_revision' in step_result.properties and
                step_result.properties['got_revision']
                == 'BOT_UPDATE_NO_REV_FOUND'):
              raise self.m.step.StepFailure('BOT_UPDATE_NO_REV_FOUND')
            self.m.gclient.runhooks()
            # if win copy toolchain metadata to the expected location.
            self._setup_win_toolchain(env)
          except:
            # On any exception, clean up the cache and raise
            self._clobber_cache(checkout_path)
            raise

    # Some outlier GoB mirror jobs can take >250secs.
    self.m.retry.basic_wrap(
        _InnerCheckout,
        step_name='Checkout source',
        sleep=2.0,
        backoff_factor=5,
        max_attempts=2
    )

  def monorepo_checkout(self, checkout_path, env, env_prefixes):
    """Checkout code using gclient.

    Args:
      checkout_path(Path): The path to checkout source code and dependencies.
      env(dict): A dictionary with the environment variables to set.
      env_prefixes(dict): A dictionary with the paths to be added to environment variables.
    """
    # Calculate if we need to clean the source code cache.
    clobber = self.m.properties.get('clobber', False)

    # Pass a special gclient variable to identify release candidate branch checkouts. This
    # is required to prevent trying to download experimental dependencies on release candidate
    # branches.
    local_custom_vars = self.m.shard_util.unfreeze_dict(
        self.m.properties.get('gclient_variables', {})
    )
    if (self.m.properties.get('git_branch', '').startswith('flutter-') or
        self.m.properties.get('git_branch', '') in ['beta', 'stable']):
      local_custom_vars['release_candidate'] = True
    git_url = REPOS['monorepo']
    commit = self.m.buildbucket.gitiles_commit
    # Commit will have empty fields if this is a try build.
    git_id = commit.id or 'refs/heads/main'
    git_ref = commit.ref or 'refs/heads/main'
    if commit.project and (commit.host != 'dart.googlesource.com' or
                           commit.project != 'monorepo'):
      raise ValueError(
          'Input reference is not on dart.googlesource.com/monorepo'
      )

    # Inner function to execute code a second time in case of failure.
    # pylint: disable=unused-argument
    def _InnerCheckout(timeout=None):
      with self.m.step.nest('Checkout source code'):
        if clobber:
          self._clobber_cache(checkout_path)
        with self.m.context(env=env, env_prefixes=env_prefixes,
                            cwd=checkout_path), self.m.depot_tools.on_path():
          try:
            src_cfg = self.m.gclient.make_config()
            soln = src_cfg.solutions.add()
            soln.name = 'monorepo'
            soln.url = git_url
            soln.revision = git_id
            soln.managed = False
            soln.custom_vars = local_custom_vars
            #src_cfg.parent_got_revision_mapping['parent_got_revision'
            #] = 'got_revision'
            src_cfg.repo_path_map[git_url] = ('monorepo', git_ref)
            self.m.gclient.c = src_cfg
            self.m.gclient.c.got_revision_mapping['monorepo'
                                                 ] = 'got_monorepo_revision'
            self.m.gclient.c.got_revision_mapping['engine/src'
                                                 ] = 'got_buildroot_revision'
            self.m.gclient.c.got_revision_mapping['engine/src/flutter'
                                                 ] = 'got_engine_revision'
            self.m.gclient.c.got_revision_mapping['engine/src/third_party/dart'
                                                 ] = 'got_dart_revision'
            self.m.gclient.c.got_revision_mapping['flutter'
                                                 ] = 'got_flutter_revision'
            self.m.bot_update.ensure_checkout()
            self.m.gclient.runhooks()
          except:
            # On any exception, clean up the cache and raise
            self._clobber_cache(checkout_path)
            raise

    # Some outlier GoB mirror jobs can take >250secs.
    self.m.retry.basic_wrap(
        _InnerCheckout,
        step_name='Checkout source',
        sleep=2.0,
        backoff_factor=5,
        max_attempts=2
    )

  def checkout(
      self, name, checkout_path, url=None, ref=None, override_sha=False
  ):
    """Checks out a repo and returns sha1 of checked out revision.

    The supported repository names and their urls are defined in the global
    REPOS variable.

    Args:
      name (str): name of the supported repository.
      checkout_path (Path): directory to clone into.
      url (str): optional url overwrite of the remote repo.
      ref (str): optional ref overwrite to fetch and check out.
      override_sha (bool): flag to override the commit sha and used the passed in ref.
    """
    if name not in REPOS:
      raise ValueError('Unsupported repo: %s' % name)
    with self.m.step.nest('Checkout flutter/%s' % name):
      git_url = url or REPOS[name]
      # gitiles_commit.id is more specific than gitiles_commit.ref, which is
      # branch
      # if this a release build, self.m.buildbucket.gitiles_commit.id should have more priority than
      # ref since it is more specific, and we don't want to default to refs/heads/<REPO_BRANCHES[name]>
      if ref in ['refs/heads/beta', 'refs/heads/stable']:
        # When we currently perform a checkout of cocoon and flutter we get the cocoon sha from the
        # build. We checkout that version of cocoon and then when we go to checkout flutter we end
        # up using that sha so then the flutter checkout fails since that commit in cocoon is not in
        # the flutter repo. This just allows us to override that and use the original ref which for
        # the coming change is just the tot master branch.
        git_ref = ref if override_sha else (
            self.m.buildbucket.gitiles_commit.id or
            self.m.buildbucket.gitiles_commit.ref or ref
        )
      else:
        git_ref = (
            ref or self.m.buildbucket.gitiles_commit.id or
            self.m.buildbucket.gitiles_commit.ref or
            'refs/heads/%s' % REPO_BRANCHES[name]
        )

      def do_checkout():
        return self.m.git.checkout(
            git_url,
            dir_path=checkout_path,
            ref=git_ref,
            recursive=True,
            set_got_revision=True,
            tags=True
        )

      # Some outlier GoB mirror jobs can take >250secs.
      return self.m.utils.retry(
          do_checkout, sleep=10.0, backoff_factor=5, max_attempts=4
      )

  def in_release_and_main(self, checkout_path):
    """Determine if a commit was already tested on main branch.

    This is used to skip build in release branches to avoid consuming all the capacity
    testing commits in release branches that were already tested on main.
    """
    if self.m.properties.get('git_branch', '') in ['beta', 'stable']:
      branches = self.current_commit_branches(checkout_path)
      return len(branches) > 1
    # We assume the commit is not duplicated if it is not comming from beta or stable.
    return False

  def get_commit(self, checkout_path, git_ref='HEAD'):
    with self.m.context(cwd=checkout_path):
      step_test_data = lambda: self.m.raw_io.test_api.stream_output_text(
          '12345abcde12345abcde12345abcde12345abcde\n'
      )
      commit = self.m.git(
          'rev-parse',
          git_ref,
          stdout=self.m.raw_io.output_text(),
          step_test_data=step_test_data
      ).stdout.strip()
      return commit

  def get_env_ref(self):
    '''Get the ref of the current build from env.'''
    gitiles_commit = self.m.buildbucket.gitiles_commit.id
    if gitiles_commit:
      return gitiles_commit
    return self.m.properties.get('git_ref', 'led')

  def current_commit_branches(self, checkout_path):
    """Gets the list of branches for the current commit."""
    with self.m.step.nest('Identify branches'):
      with self.m.context(cwd=checkout_path):
        commit = self.get_commit(checkout_path)
        branches = self.m.git(
            'branch',
            '-a',
            '--contains',
            commit,
            stdout=self.m.raw_io.output_text()
        ).stdout.splitlines()
        # Discard local branches as we are interested only in remote branches.
        branches = [
            b.strip()
            for b in branches
            if b.strip().startswith('remotes/origin/')
        ]
        return [b.replace('remotes/origin/', '') for b in branches] or []

  def get_branch(self, checkout_path):
    """Get git branch for beta and stable channels.

    Post submit tests for release candidate branches pass the channel stable|beta in
    the git_branch property. As the commits are being tested before they are publised
    is not possible to use the channels to checkout the correct versions of dependencies
    from other repositories, furthermore the channels are only applicable to
    flutter/flutter repository. For tests with dependencies on other repositories we are
    using the release candidate branch to check out the equivalent to the commit under test.
    E.g. if the current commit comes from flutter@flutter-2.8-candiddate.16 then we checkout
    plugins@flutter-2.8-candiddate.16.

    To guess the branch name we get the current commit from the checkout and then we find
    all the different branches the commit exist on, if there is a branch that starts with
    flutter- then we assume that's the release candidate branch under test.
    """
    if self.m.properties.get('git_branch', '') in ['beta', 'stable']:
      branches = self.current_commit_branches(checkout_path)
      branches = [b for b in branches if b.startswith('flutter')]
      return branches[0] if len(branches) > 0 else self.m.properties.get(
          'git_branch', ''
      )
    return self.m.properties.get('git_branch', '')

  def flutter_environment(self, checkout_path, clear_features=True):
    """Returns env and env_prefixes of an flutter/dart command environment."""
    dart_bin = checkout_path / 'bin/cache/dart-sdk/bin'
    flutter_bin = checkout_path / 'bin'
    # Fail if flutter bin folder does not exist. dart-sdk/bin folder will be
    # available only after running "flutter doctor" and it needs to be run as
    # the first command on the context using the environment.
    if not self.m.path.exists(flutter_bin):
      msg = (
          'flutter bin folders do not exist,'
          'did you forget to checkout flutter repo?'
      )
      self.m.step.empty(
          'Flutter Environment', status=self.m.step.FAILURE, step_text=msg
      )
    git_ref = self.m.properties.get('git_ref', '')
    pub_cache_path = self.m.path.start_dir / '.pub-cache'
    env = {
        # Setup our own pub_cache to not affect other slaves on this machine,
        # and so that the pre-populated pub cache is contained in the package.
        'PUB_CACHE':
            pub_cache_path,
        # https://github.com/flutter/flutter/wiki/Plugins-and-Packages-repository-structure#gradle-structure
        # go/artifact-hub
        'ARTIFACT_HUB_REPOSITORY':
            'artifactregistry://us-maven.pkg.dev/artifact-foundry-prod/maven-3p',
        # Windows Packaging script assumes this is set.
        'DEPOT_TOOLS':
            str(self.m.depot_tools.root),
        'SDK_CHECKOUT_PATH':
            checkout_path,
        'LUCI_CI':
            True,
        'LUCI_PR':
            re.sub('refs\/pull\/|\/head', '', git_ref),
        'LUCI_BRANCH':
            self.m.properties.get('release_ref', '').replace('refs/heads/', ''),
        'GIT_BRANCH':
            self.get_branch(checkout_path),
        'OS':
            'linux' if self.m.platform.name == 'linux' else
            ('darwin' if self.m.platform.name == 'mac' else 'win'),
        'REVISION':
            self.get_commit(checkout_path),
    }
    self.add_property_env_variables(env)

    # Cocoon signal that we want to pin the engine realm. See flutter/bin/internal/update_engine_version.sh
    flutter_realm = self.m.properties.get('flutter_realm', False)
    if flutter_realm:
      env['FLUTTER_REALM'] = flutter_realm

    # Cocoon signal that we want to pin the engine version. See flutter/bin/internal/update_engine_version.sh
    flutter_prebuilt_engine_version = self.m.properties.get(
        'flutter_prebuilt_engine_version', False
    )
    if flutter_prebuilt_engine_version:
      env['FLUTTER_PREBUILT_ENGINE_VERSION'] = flutter_prebuilt_engine_version

    if self.m.properties.get('gn_artifacts', False):
      env['FLUTTER_STORAGE_BASE_URL'
         ] = 'https://storage.googleapis.com/flutter_archives_v2'
    env_prefixes = {'PATH': ['%s' % str(flutter_bin), '%s' % str(dart_bin)]}
    flutter_exe = 'flutter.bat' if self.m.platform.is_win else 'flutter'
    # If setting environment from engine_v2 do not clear features.
    if clear_features and not self.m.monorepo.is_monorepo:
      with self.m.context(env=env, env_prefixes=env_prefixes):
        self.m.step(
            'flutter config --clear-features',
            [flutter_bin / flutter_exe, 'config', '--clear-features'],
        )
    return env, env_prefixes

  def add_property_env_variables(self, env):
    """Populate env_variables defined in properties to Env.

    The env_variables is in a dict format with String values.
    """
    env_variables = self.m.properties.get('env_variables', {})
    for key in env_variables.keys():
      env[key] = env_variables[key]

  def engine_environment(self, checkout_path):
    """Returns env and env_prefixes of an flutter/dart command environment."""
    engine_path = checkout_path / 'engine'
    dart_bin = (
        engine_path / 'src/flutter/third_party/dart/tools/sdks/dart-sdk/bin'
    )
    git_ref = self.m.properties.get('git_ref', '')
    android_home = engine_path / 'src/third_party/android_tools/sdk'
    android_tmp = self.m.path.mkdtemp()
    env = {
        # Windows Packaging script assumes this is set.
        'DEPOT_TOOLS':
            str(self.m.depot_tools.root),
        'ENGINE_CHECKOUT_PATH':
            engine_path,
        'ENGINE_PATH':
            engine_path,
        'LUCI_CI':
            True,
        'LUCI_PR':
            re.sub('refs\/pull\/|\/head', '', git_ref),
        'LUCI_BRANCH':
            self.m.properties.get('release_ref', '').replace('refs/heads/', ''),
        'GIT_BRANCH':
            self.get_branch(checkout_path / 'flutter'),
        'OS':
            'linux' if self.m.platform.name == 'linux' else
            ('darwin' if self.m.platform.name == 'mac' else 'win'),
        'ANDROID_HOME':
            str(android_home),
        'ANDROID_SDK_HOME':
            str(android_tmp),
        'ANDROID_USER_HOME':
            str(android_tmp / '.android'),
        'LUCI_WORKDIR':
            str(self.m.path.start_dir),
        'LUCI_CLEANUP':
            str(self.m.path.cleanup_dir),
        'REVISION':
            self.m.buildbucket.gitiles_commit.id or '',
        'CLANG_CRASH_DIAGNOSTICS_DIR':
            self.m.path.mkdtemp(),
        'CLANG_MODULE_CACHE_PATH':
            '',
    }
    env_prefixes = {'PATH': ['%s' % str(dart_bin)]}
    return env, env_prefixes

  def monorepo_environment(self, checkout_path):
    """Returns env and env_prefixes of a monorepo command environment."""
    engine_path = checkout_path / 'flutter/engine'
    dart_bin = (
        engine_path / 'src/flutter/third_party/dart/tools/sdks/dart-sdk/bin'
    )
    git_ref = self.m.properties.get('git_ref', '')
    android_home = engine_path / 'src/third_party/android_tools/sdk'
    android_tmp = self.m.path.mkdtemp()
    env = {
        # Windows Packaging script assumes this is set.
        'DEPOT_TOOLS':
            str(self.m.depot_tools.root),
        'ENGINE_CHECKOUT_PATH':
            engine_path,
        'ENGINE_PATH':
            engine_path,
        'LUCI_CI':
            True,
        'LUCI_PR':
            re.sub('refs\/pull\/|\/head', '', git_ref),
        'LUCI_BRANCH':
            self.m.properties.get('release_ref', '').replace('refs/heads/', ''),
        'GIT_BRANCH':
            self.get_branch(checkout_path / 'flutter'),
        'OS':
            'linux' if self.m.platform.name == 'linux' else
            ('darwin' if self.m.platform.name == 'mac' else 'win'),
        'ANDROID_HOME':
            str(android_home),
        'ANDROID_SDK_HOME':
            str(android_tmp),
        'ANDROID_USER_HOME':
            str(android_tmp / '.android'),
        'LUCI_WORKDIR':
            str(self.m.path.start_dir),
        'REVISION':
            self.m.buildbucket.gitiles_commit.id or '',
        'CLANG_CRASH_DIAGNOSTICS_DIR':
            self.m.path.mkdtemp(),
    }
    env_prefixes = {'PATH': ['%s' % str(dart_bin)]}
    return env, env_prefixes

  def sdk_checkout_path(self):
    """Returns the checkoout path of the current flutter_environment.

    Returns(Path): A path object with the current checkout path.
    """
    checkout_path = self.m.context.env.get('SDK_CHECKOUT_PATH')
    assert checkout_path, 'Outside of a flutter_environment?'
    return self.m.path.abs_to_path(checkout_path)

  def get_build(self, checkout):
    """Returns build config of the target.

    If there exists a `build` property, then return it. This is the case when triggered
    from an orchestrator.

    If these doesn't exist a `build` property, then checkout the Engine repo and return
    the `build` by reading the checked config file. This is the case when a standalone
    target is scheduled.
    """
    if self.m.monorepo.is_monorepo_ci_build or self.m.monorepo.is_monorepo_try_build:
      project = 'monorepo'
    else:
      project = 'flutter'
    build = self.m.properties.get('build', None)
    if not build:
      self.checkout(
          project,
          checkout_path=checkout / 'flutter',
          url=self.m.properties.get('git_url'),
          ref=self.m.properties.get('git_ref')
      )
      build = self.ReadBuildConfig(checkout)
    return build

  def ReadBuildConfig(self, checkout_path):
    """Reads an standalone build configuration."""
    config_name = self.m.properties.get('config_name')
    config_path = (
        checkout_path /
        f'flutter/engine/src/flutter/ci/builders/standalone/{config_name}.json'
    )
    config = self.m.file.read_json(
        'Read build config file',
        config_path,
        test_data={
            "name": "flutter/build",
        }
    )
    return config

  def content_hash(self):
    """Returns the content hash if present, or None

       The content hash is a source-derived value that fingerprints the artifacts
       with the engine source that produced it. By moving to a content hash, we
       build less copies of the same engine source code and speed up CI.

       See: https://github.com/flutter/flutter/blob/master/bin/internal/content_aware_hash.sh
    """
    return self.m.properties.get('content_hash', None)

  def get_content_hash_url(self, api, remote_url, content_hash):
    """Optionally upload artifacts to content_hash

      Args:
          api: Object point to all the imported modules of this build.
          remote_url: Original target url to upload local_path to.
          content_hash: Derived-from-source hash to substitute into remote_url.
      """
    # Flutter is the only uploader of content_hash builds
    if api.monorepo.is_monorepo_ci_build or api.monorepo.is_monorepo_try_build:
      return

    # Check that the path matches
    #   1.0.0-0005149dca9b248663adcde4bdd7c6c915a76584/
    #   0005149dca9b248663adcde4bdd7c6c915a76584/
    match = re.search(r'([0-9a-fA-F]{40})/', remote_url)
    if match is None:
      raise AssertionError(
          'Content hash not found in remote_url: %s' % remote_url
      )

    # Substitute **all** <sha1> for content_hash
    content_hash_remote = re.sub(
        r'[0-9a-fA-F]{40}', f'{content_hash}', remote_url
    )
    return content_hash_remote
