# 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
