# Copyright 2022 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 attr
import re

from recipe_engine import recipe_api


@attr.s
class ArchivePaths(object):
  """Paths for an archive config."""
  local = attr.ib(type=str)
  remote = attr.ib(type=str)


ANDROID_ARTIFACTS_BUCKET = 'download.flutter.io'

# Monorepo constant.
MONOREPO = 'monorepo'
MONOREPO_TRY_BUCKET = 'monorepo-try-bucket'

# Used for mock paths
DIRECTORY = 'DIRECTORY'

# Relative paths used to mock paths for testing.
MOCK_JAR_PATH = (
    'io/flutter/x86_debug/'
    '1.0.0-0005149dca9b248663adcde4bdd7c6c915a76584/'
    'x86_debug-1.0.0-0005149dca9b248663adcde4bdd7c6c915a76584.jar'
)
MOCK_POM_PATH = (
    'io/flutter/x86_debug/'
    '1.0.0-0005149dca9b248663adcde4bdd7c6c915a76584/'
    'x86_debug-1.0.0-0005149dca9b248663adcde4bdd7c6c915a76584.pom'
)

# Bucket + initial prefix for artifact destination.
LUCI_TO_GCS_PREFIX = {
    'flutter_EXPERIMENTAL': ('flutter_infra_release', ''),
    'flutter_PRODUCTION': ('flutter_infra_release', ''),
    '%s_EXPERIMENTAL' % MONOREPO:
        ('flutter_archives_v2/monorepo', 'flutter_infra_release'),
    '%s_PRODUCTION' % MONOREPO:
        ('flutter_archives_v2/monorepo', 'flutter_infra_release'),
    '%s_EXPERIMENTAL' % MONOREPO_TRY_BUCKET:
        ('flutter_archives_v2/monorepo_try', 'flutter_infra_release'),
    '%s_PRODUCTION' % MONOREPO_TRY_BUCKET:
        ('flutter_archives_v2/monorepo_try', 'flutter_infra_release'),
    'prod_PRODUCTION': ('flutter_infra_release', ''),
    'prod_EXPERIMENTAL': ('flutter_archives_v2', 'flutter_infra_release'),
    'staging_PRODUCTION': ('flutter_archives_v2', 'flutter_infra_release'),
    'staging_EXPERIMENTAL': ('flutter_archives_v2', 'flutter_infra_release'),
    'try_PRODUCTION': ('flutter_archives_v2', 'flutter_infra_release'),
    'try_EXPERIMENTAL': ('flutter_archives_v2', 'flutter_infra_release'),
    'try.shadow_PRODUCTION': ('flutter_archives_v2', 'flutter_infra_release'),
    'try.shadow_EXPERIMENTAL': ('flutter_archives_v2', 'flutter_infra_release'),
    'staging.shadow_PRODUCTION':
        ('flutter_archives_v2', 'flutter_infra_release'),
    'staging.shadow_EXPERIMENTAL':
        ('flutter_archives_v2', 'flutter_infra_release'),
    'prod.shadow_PRODUCTION': ('flutter_archives_v2', 'flutter_infra_release'),
    'prod.shadow_EXPERIMENTAL':
        ('flutter_archives_v2', 'flutter_infra_release')
}

# Bucket + initial prefix for artifact destination.
LUCI_TO_ANDROID_GCS_PREFIX = {
    'flutter_EXPERIMENTAL': '',
    'flutter_PRODUCTION': '',
    '%s_EXPERIMENTAL' % MONOREPO: 'flutter_archives_v2/monorepo',
    '%s_PRODUCTION' % MONOREPO: 'flutter_archives_v2/monorepo',
    '%s_EXPERIMENTAL' % MONOREPO_TRY_BUCKET: 'flutter_archives_v2/monorepo_try',
    '%s_PRODUCTION' % MONOREPO_TRY_BUCKET: 'flutter_archives_v2/monorepo_try',
    'prod_EXPERIMENTAL': 'flutter_archives_v2',
    'prod_PRODUCTION': '',
    'staging_EXPERIMENTAL': 'flutter_archives_v2',
    'staging_PRODUCTION': 'flutter_archives_v2',
    'try_EXPERIMENTAL': 'flutter_archives_v2',
    'try_PRODUCTION': 'flutter_archives_v2',
    'try.shadow_EXPERIMENTAL': 'flutter_archives_v2',
    'try.shadow_PRODUCTION': 'flutter_archives_v2',
    'staging.shadow_EXPERIMENTAL': 'flutter_archives_v2',
    'staging.shadow_PRODUCTION': 'flutter_archives_v2',
    'prod.shadow_EXPERIMENTAL': 'flutter_archives_v2',
    'prod.shadow_PRODUCTION': 'flutter_archives_v2'
}

# Subpath for realms. A realm is used to separate file destinations
# within the same configuration. E.g. production environment with
# an experimental realm and production environment with a production realm.
REALM_TO_PATH = {'production': '', 'experimental': 'experimental'}


class ArchivesApi(recipe_api.RecipeApi):
  """Api to handle archives from engine_v2 recipes."""

  def _full_path_list(self, checkout, archive_config):
    """Calculates the local paths using an archive_config.

    Args:
      checkout: (Path) the checkout path of the engine repository.
      archive_config: (dict) a dictionary with the archive files generated by
        a given build.

    Returns:
      A list of strings with the expected local files as described
      by the archive configuration.
    """
    results = []
    self.m.path.mock_add_directory(
        self.m.path.start_dir /
        'out/android_profile/zip_archives/download.flutter.io'
    )
    for include_path in archive_config.get('include_paths', []):
      full_include_path = self.m.path.abspath(checkout / include_path)
      if self.m.path.isdir(full_include_path):
        test_data = []
        paths = self.m.file.listdir(
            'Expand directory',
            checkout / include_path,
            recursive=True,
            test_data=(MOCK_JAR_PATH, MOCK_POM_PATH)
        )
        paths = [self.m.path.abspath(p) for p in paths]
        results.extend(paths)
      else:
        results.append(full_include_path)
    return results

  def _split_dst_parts(self, dst):
    """Splits gsutil uri into a bucket and path sections.

    Args:
      dst: (str) a gcs path like gs://bucket/a/b/c.

    Returns:
      A tuple with the bucket as the first item and the path to the
      object as the second parameter.
    """

    matches = re.match('gs://([\w.]+)/(.+)', dst)
    return (matches.group(1), matches.group(2))

  def upload_artifact(self, src, dst, metadata=None):
    """Uploads a local object to a gcs destination.

    This method also ensures the directoy structure is recreated in the
    destination.

    Args:
      src: (str) a string with the object local path.
      dst: (str) a string with the destination path in gcs.
      metadata: (dict) a dictionary with the header as key and its content as value.
    """
    bucket, path = self._split_dst_parts(dst)
    dir_part = self.m.path.dirname(path)
    archive_dir = self.m.path.mkdtemp()
    local_dst_tree = archive_dir.joinpath(*dir_part.split('/'))
    self.m.file.ensure_directory('Ensure %s' % dir_part, local_dst_tree)
    self.m.file.copy('Copy %s to tmp location' % src, src, local_dst_tree)
    self.m.gsutil.upload(
        name='Upload %s to %s' % (src, dst),
        source='%s/*' % archive_dir,
        bucket=bucket,
        dest='',
        args=['-r'],
        metadata=metadata,
    )

  def download(self, src, dst):
    """Downloads a file from GCS.

    Args:
      src: A string with gcs uri to download.
      dst: A string with the local destination for the file.
    """
    bucket, path = self._split_dst_parts(src)
    self.m.gsutil.download(bucket, path, dst, name="download %s" % src)

  def engine_v2_gcs_paths(self, checkout, archive_config):
    """Calculates engine v2 GCS paths from an archive config.

    Args:
      checkout: (Path) the engine repository checkout folder.
      archive_config: (dict) the archive configuration for a recipes v2 build.

    Returns:
      A list of ArchivePaths with expected local and remote locations for the
      generated artifacts.
    """
    results = []
    build_id = ''
    realm = archive_config.get('realm', 'experimental').upper()
    # Whether to include build_id as part of the namespace or not.
    include_build_id = False
    file_list = self._full_path_list(checkout, archive_config)
    if self.m.monorepo.is_monorepo_try_build:
      commit = self.m.monorepo.get_build_identifier()
      bucket = MONOREPO_TRY_BUCKET
      include_build_id = True
    elif self.m.monorepo.is_monorepo_ci_build:
      commit = self.m.repo_util.get_commit(checkout / '../../../monorepo')
      bucket = MONOREPO
      include_build_id = True
    else:
      commit = self.m.repo_util.get_commit(checkout / 'flutter')
      bucket = self.m.buildbucket.build.builder.bucket
      include_build_id = False
    build_id = self.m.monorepo.get_build_identifier() if include_build_id else ''
    bucket_plus_realm = '_'.join(filter(None, (bucket, realm)))
    for include_path in file_list:
      is_android_artifact = ANDROID_ARTIFACTS_BUCKET in include_path
      dir_part = self.m.path.dirname(include_path)
      full_base_path = self.m.path.abspath(
          checkout / archive_config.get('base_path', '')
      )
      rel_path = self.m.path.relpath(dir_part, full_base_path)
      rel_path = '' if rel_path == '.' else rel_path
      base_name = self.m.path.basename(include_path)

      if is_android_artifact:
        # We are not using a slash in the first parameter becase artifact_prefix
        # already includes the slash.
        artifact_path = '%s/%s' % (rel_path, base_name)
        # Replace ANDROID_ARTIFACTS_BUCKET to include the realm.
        old_location = '/'.join([ANDROID_ARTIFACTS_BUCKET, 'io', 'flutter'])
        new_location = '/'.join(
            filter(bool, [ANDROID_ARTIFACTS_BUCKET, 'io', 'flutter'])
        )
        artifact_path = artifact_path.replace(old_location, new_location)
        bucket_and_prefix = LUCI_TO_ANDROID_GCS_PREFIX.get(bucket_plus_realm)
        artifact_path = '/'.join(
            filter(bool, [bucket_and_prefix, build_id, artifact_path])
        )
      else:
        gcs_bucket, bucket_postfix = LUCI_TO_GCS_PREFIX.get(bucket_plus_realm)
        artifact_path = '/'.join(
            filter(
                bool, [
                    gcs_bucket, build_id, bucket_postfix, 'flutter', commit,
                    rel_path, base_name
                ]
            )
        )

      results.append(ArchivePaths(include_path, 'gs://%s' % artifact_path))
    return results

  def global_generator_paths(self, checkout, archives):
    """Calculates the global generator paths for an archive config.

    Args:
      checkout: (Path) the engine repository checkout folder.
      archives: (list) list of dictionaries source and destination path
        of files relative to the gclient checkout.

    Returns:
      A list of ArchivePaths with expected local and remote locations for the
      generated artifacts.
    """
    results = []
    build_id = ''
    include_build_id = False

    # Calculate prefix and commit.
    if self.m.monorepo.is_monorepo_try_build:
      commit = self.m.monorepo.get_build_identifier()
      bucket = MONOREPO_TRY_BUCKET
      include_build_id = True
    elif self.m.monorepo.is_monorepo_ci_build:
      commit = self.m.repo_util.get_commit(checkout / '../../../monorepo')
      bucket = MONOREPO
      include_build_id = True
    else:
      commit = self.m.repo_util.get_commit(checkout / 'flutter')
      bucket = self.m.buildbucket.build.builder.bucket
      include_build_id = False

    for archive in archives:
      realm = archive.get('realm', 'experimental').upper()
      bucket_plus_realm = '_'.join(filter(None, (bucket, realm)))
      build_id = self.m.monorepo.get_build_identifier() if include_build_id else ''
      gcs_bucket, bucket_postfix = LUCI_TO_GCS_PREFIX.get(bucket_plus_realm)
      source = checkout / archive.get('source')
      artifact_path = '/'.join(
          filter(
              bool, [
                  gcs_bucket, build_id, bucket_postfix, 'flutter', commit,
                  archive.get('destination')
              ]
          )
      )
      dst = 'gs://%s' % artifact_path
      results.append(ArchivePaths(self.m.path.abspath(source), dst))
    return results
