# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for rolling a CIPD package which other packages depend on."""

from recipe_engine.config import List
from recipe_engine.post_process import StepSuccess
from recipe_engine.recipe_api import Property

DEPS = [
    'fuchsia/jiri',
    'fuchsia/auto_roller',
    'fuchsia/cipd_dependencies',
    'recipe_engine/archive',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/path',
    'recipe_engine/step',
]

PROPERTIES = {
    'manifests':
        Property(
            kind=List(dict),
            help=(
                'A list of dictionaries with project, manifest and remote key.'
            )),
    'package':
        Property(
            kind=str, help='The list of CIPD packages to update in $import_in'),
    'ref':
        Property(
            kind=str,
            default='latest',
            help='A common CIPD ref to resolve when rolling a set of packages'),
    'owners':
        Property(
            kind=List(str),
            default=(),
            help=('The owners responsible for watching this roller '
                  '(example: "username@google.com").')),
    'dependents':
        Property(
            kind=List(dict), default=(),
            help=('Dependent package properties.')),
    'versions_file':
        Property(
            kind=str,
            help=('A string with the path to the versions file inside '
                  'the CIPD package.'))
}

COMMIT_MESSAGE = """[roll] Roll {roller} CIPD packages:

{packages}

From: {old_version}
To: {version}

Test: CQ
CQ-Do-Not-Cancel-Tryjobs: true"""

CIPD_URL = 'https://chrome-infra-packages.appspot.com/p/{package}/+/{version}'


def RunSteps(api, manifests, ref, owners, versions_file, dependents, package):
  """Run the recipe steps."""

  with api.context(infra_steps=True):
    if owners:
      with api.step.nest('owners') as owners_presentation:
        owners_presentation.step_summary_text = ', '.join(owners)

    # Import manifests
    api.jiri.init(use_lock_file=True)
    for manifest_config in manifests:
      api.jiri.import_manifest(
          manifest=manifest_config['manifest'],
          remote=manifest_config['remote'],
          name=manifest_config['project'])
    api.jiri.update(run_hooks=False)
    api.jiri.run_hooks()

  deps_info = api.jiri.package([package])
  cipd_description = api.cipd.describe(package, ref)

  # Is there a new version to roll?
  if cipd_description.tags[0].tag == deps_info.json.output[0]['version']:
    api.step('manifest up-to-date; nothing to roll', None)
    return

  # Read main package versions file.
  main_package_version_dict = api.cipd_dependencies.get_dependencies(
      'read versions', package, cipd_description.pin.instance_id, versions_file)

  # For every dependent read version file and validate versions.
  validation_summary = []
  for dep in dependents:
    cipd_dep_desc = api.cipd.describe(dep['package'], dep['ref'])
    version_dict = api.cipd_dependencies.get_dependencies(
        'read dep versions', dep['package'], cipd_dep_desc.pin.instance_id,
        dep['versions_file'])
    summary = api.cipd_dependencies.validate_against_package(
        package=dep,
        dependencies=dep['dependencies'],
        package_versions=main_package_version_dict,
        dependent_versions=version_dict)
    if summary:
      validation_summary.append(summary)
  if validation_summary:
    msg = 'Project-dependent version mismatching: {}'.format(
        '\n'.join(validation_summary))
    # After a new version of the main package is available, dependents may still
    # need more time to build versions with it. We mark this step as successful
    # to avoid disruption to build cops looking for a solution to something that
    # is expected.
    api.step('validation_summary', cmd=None).presentation.step_text = msg
    return
  # Roll everything
  api.step('Rolling-Success', None)


def GenTests(api):

  properties = {
      'manifests': [{
          'project': 'integration',
          'manifest': 'other/dependency',
          'remote': 'sso://fuchsia/integration'
      }, {
          'project': 'integration',
          'manifest': 'fuchsia/flower',
          'remote': 'sso://fuchsia/integration'
      }],
      'package': 'flutter/fuchsia/${platform}',
      'package_dependencies': [
          'package=dart',
          'project=skia',
      ],
      'dependents': [{
          'package': 'abc/dependent',
          'ref': 'latest',
          'versions_file': 'dependent.json',
          'dependencies': ['engine_version']
      }],
      'import_in': 'fuchsia/prebuilts',
      'versions_file': 'flutter/versions.json',
      'owners': ['abc@gmail.com']
  }

  package_no_match_test_data = api.step_data(
      'cipd describe flutter/fuchsia/${platform}',
      api.cipd.example_describe(
          package_name='flutter/fuchsia',
          version='version_abc',
          test_data_tags=['git_revision:revision_abc']))
  jiri_package_test_data = [
      {
          'name': 'flutter/fuchsia',
          'path': 'flutter/fuchsia',
          'version': 'git_revision:revision_abc',
          'manifest': 'manifest1'
      },
  ]
  default_properties = api.properties(**properties)
  # Version of the cipd package is the same as the one currently in the
  # source tree.
  yield (
      api.test('nothing_to_roll') + default_properties +
      package_no_match_test_data +
      api.step_data('jiri package', api.jiri.package(jiri_package_test_data)))

  package_match_test_data = api.step_data(
      'cipd describe flutter/fuchsia/${platform}',
      api.cipd.example_describe(
          package_name='flutter/fuchsia',
          version='version_abc',
          test_data_tags=['git_revision:revision_jkl']))
  package_versions = {
      'engine_version': 'engine_version_xyz',
  }
  dependent_versions = {
      'engine_version': 'engine_version_lmn',
  }
  # Version of the cipd package is different from the one in the tree and ready
  # to get rolled but the latest dependent version does not match the versions
  # being rolled.
  yield (api.test('dependent_not_matching_versions') + default_properties +
         package_match_test_data + api.step_data(
             'jiri package', api.jiri.package(jiri_package_test_data)) +
         api.step_data('read versions',
                       api.file.read_json(json_content=package_versions)) +
         api.step_data('read dep versions',
                       api.file.read_json(json_content=dependent_versions)) +
         api.post_process(StepSuccess, 'validation_summary'))
  dependent_versions_match = {
      'engine_version': 'engine_version_xyz',
  }
  # Version of the cipd package is different from the one in the tree and ready
  # to get rolled but the dependent latest version match the versions
  # being rolled.
  yield (
      api.test('dependent_matching_versions') + default_properties +
      package_match_test_data +
      api.step_data('jiri package', api.jiri.package(jiri_package_test_data)) +
      api.step_data('read versions',
                    api.file.read_json(json_content=package_versions)) +
      api.step_data('read dep versions',
                    api.file.read_json(json_content=dependent_versions_match)) +
      api.post_process(StepSuccess, 'Rolling-Success'))
