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

from recipe_engine import post_process

from PB.recipes.dart.roller.roll_to_dev import RollToDev

DEPS = [
    'depot_tools/bot_update',
    'depot_tools/gclient',
    'depot_tools/git',
    'depot_tools/gitiles',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/runtime',
    'recipe_engine/step',
    'recipe_engine/time',
]
DEV_BRANCH = 'dev'
DEV_REF = 'refs/heads/dev'
MESSAGE_TEMPLATE = '''Version %s

Merge commit '%s' into '%s'
'''
PROPERTIES = RollToDev
REPO_URL = 'https://dart.googlesource.com/sdk'
SUPPORTED_FIELDS = {
    'CHANNEL', 'MAJOR', 'MINOR', 'PATCH', 'PRERELEASE', 'PRERELEASE_PATCH'
}
VERSION_PATH = 'tools/VERSION'


def RunSteps(api, properties):
  from_ref = properties.from_ref
  assert from_ref, 'the recipe requires a from_ref'
  to_ref = DEV_REF
  commit = api.gitiles.commit_log(
      commit=from_ref,
      step_name='get commit to merge',
      url=REPO_URL,
  )
  commit_hash = commit['commit']
  assert commit_hash, 'no commit hash to merge found'

  api.git.checkout(
      REPO_URL,
      ref=to_ref,
      submodules=False,
      submodule_update_recursive=False,
  )
  with api.context(cwd=api.path['checkout']):
    api.git('config', 'user.name', 'Dart CI', name='configure user.name')
    api.git(
        'config',
        'user.email',
        'dart-luci-ci-builder@dart-ci.iam.gserviceaccount.com',
        name='configure user.email')

    api.git('checkout', DEV_BRANCH, name='checkout dev')
    api.git('fetch', 'origin', commit_hash, name='fetch %s' % commit_hash)
    result = api.git(
        'merge-base',
        '--is-ancestor',
        commit_hash,
        'HEAD',
        name='check if commit has been merged before',
        ok_ret=[0, 1],  # merge-base returns 1 if the commit is not an ancestor.
    )
    if result.exc_result.retcode == 0:
      # The commit has already been pushed before.
      return

    api.git(
        'merge',
        '--no-commit',
        '--no-ff',
        commit_hash,
        name='merge %s to dev' % commit_hash,
        ok_ret='any')
    api.git(
        'checkout',
        DEV_BRANCH,
        '--',
        VERSION_PATH,
        name='restore version file on dev')
    version, channel = _update_version_file(api, from_ref)
    message = MESSAGE_TEMPLATE % (version, commit_hash, channel)
    api.git('commit', '--all', '--message=%s' % message)
    api.git('tag', '--annotate', '--message=%s' % version, version)
    push_args = ['push', '--atomic']
    if api.runtime.is_experimental:
      push_args.append('--dry-run')
    push_args.append('https://dart.googlesource.com/sdk.git')
    tag = 'refs/tags/%s' % version
    try:
      api.git(*push_args + [to_ref, tag], name='push to %s' % to_ref)
    except api.step.InfraFailure:
      # If the step fails, it's likely because of GoB replication delay. Wait
      # 30s and then try again.
      api.time.sleep(30)
      api.git(*push_args + [to_ref, tag], name='retry push to %s' % to_ref)


def _update_version_file(api, from_ref):
  from_version_file_text = api.gitiles.download_file(
      REPO_URL,
      VERSION_PATH,
      branch=from_ref,
      step_name='download from_ref version file',
  )
  from_version = _parse_version_file(from_version_file_text)
  from_triplet = _version_triplet(from_version)

  to_version_file_text = api.file.read_text(
      'read to_ref version file', api.path['checkout'].join(VERSION_PATH))
  to_version = _parse_version_file(to_version_file_text)
  to_triplet = _version_triplet(to_version)

  if not from_triplet == to_triplet:
    # major, minor, or patch was bumped on from_ref
    assert from_triplet > to_triplet, 'version downgrade is unsupported'
    for field in ['MAJOR', 'MINOR', 'PATCH']:
      to_version[field] = from_version[field]
    # reset prerelease
    to_version['PRERELEASE'] = '0'
  else:
    _bump(to_version, 'PRERELEASE')

  # always '0' on dev
  to_version['PRERELEASE_PATCH'] = '0'

  # copy unknown fields
  for field in from_version.keys():
    if field not in SUPPORTED_FIELDS:
      to_version[field] = from_version[field]

  _write_version_file(api, from_version_file_text, to_version)
  api.git('add', VERSION_PATH)
  return _version_string(to_version), to_version['CHANNEL']


def _parse_version_file(version_file_text):
  version = {}
  for line in version_file_text.splitlines():
    if not line or line.startswith('#'):
      continue
    field, value = line.split(' ')
    version[field] = value
  return version


def _version_triplet(version):
  return (version['MAJOR'], version['MINOR'], version['PATCH'])


def _bump(version, field):
  version[field] = str(int(version[field]) + 1)


def _write_version_file(api, version_file_text, new_version):
  updated_lines = []
  for line in version_file_text.splitlines():
    if line.startswith('#'):
      updated_lines.append(line)
    else:
      field, _ = line.split(' ')
      updated_lines.append('%s %s' % (field, new_version[field]))
  api.file.write_text('write new version file',
                      api.path['checkout'].join(VERSION_PATH),
                      '\n'.join(updated_lines))


def _version_string(version):
  return '%s.%s.%s-%s.%s.%s' % (version['MAJOR'], version['MINOR'],
                                version['PATCH'], version['PRERELEASE'],
                                version['PRERELEASE_PATCH'], version['CHANNEL'])


def GenTests(api):

  assertion_error = (
      api.post_process(post_process.DoesNotRunRE, '(push|tag).*'),
      api.expect_exception('AssertionError'),
      api.post_process(post_process.StatusException),
      api.post_process(post_process.DropExpectation),
  )
  yield api.test('no-from-ref-no-push', *assertion_error)

  input_properties = api.properties(RollToDev(from_ref='refs/heads/lkgr'))
  from_ref_commit = api.step_data(
      'get commit to merge',
      api.gitiles.make_commit_test_data(
          'abcdef', 'Subject\n\nMessage\n', new_files=['foo/bar', 'baz/qux']))
  from_ref_version_file = api.step_data(
      'download from_ref version file',
      api.gitiles.make_encoded_file('''# Updated Comment
CHANNEL abc
MAJOR 4
MINOR 1
PATCH 2
PRERELEASE 0
PRERELEASE_PATCH 0
UNKNOWN_FIELD cde
'''))
  to_ref_version_file = api.step_data(
      'read to_ref version file',
      api.file.read_text('''# Comment
CHANNEL dev
MAJOR 4
MINOR 1
PATCH 2
PRERELEASE 34
PRERELEASE_PATCH 25
UNKNOWN_FIELD feg
'''))

  yield api.test(
      'no-push-if-already-merged',
      input_properties,
      from_ref_commit,
      api.post_process(post_process.DoesNotRunRE, '(push|tag).*'),
      api.post_process(post_process.StatusSuccess),
  )

  expected_version_file = api.post_process(
      post_process.LogEquals, 'write new version file', 'VERSION',
      '''# Updated Comment
CHANNEL dev
MAJOR 4
MINOR 1
PATCH 2
PRERELEASE 35
PRERELEASE_PATCH 0
UNKNOWN_FIELD cde''')
  unmerged = api.step_data('check if commit has been merged before', retcode=1)
  yield api.test(
      'push',
      input_properties,
      from_ref_commit,
      from_ref_version_file,
      to_ref_version_file,
      unmerged,
      expected_version_file,
      api.post_process(post_process.MustRun, 'push to refs/heads/dev'),
      api.post_process(post_process.StepCommandContains,
                       'push to refs/heads/dev', [
                           '--atomic',
                           'https://dart.googlesource.com/sdk.git',
                           'refs/heads/dev',
                           'refs/tags/4.1.2-35.0.dev',
                       ]),
      api.post_process(post_process.StatusSuccess),
  )
  yield api.test(
      'push-retry',
      input_properties,
      from_ref_commit,
      from_ref_version_file,
      to_ref_version_file,
      unmerged,
      expected_version_file,
      api.post_process(post_process.MustRun, 'push to refs/heads/dev'),
      api.step_data('push to refs/heads/dev', retcode=1),
      api.post_process(post_process.MustRun, 'retry push to refs/heads/dev'),
      api.post_process(post_process.StepCommandContains,
                       'retry push to refs/heads/dev', [
                           '--atomic',
                           'https://dart.googlesource.com/sdk.git',
                           'refs/heads/dev',
                           'refs/tags/4.1.2-35.0.dev',
                       ]),
      api.post_process(post_process.StatusSuccess),
      api.post_process(post_process.Filter().include_re('(retry )?push')),
  )
  yield api.test(
      'dry-run',
      api.runtime(is_experimental=True),
      input_properties,
      from_ref_commit,
      from_ref_version_file,
      to_ref_version_file,
      unmerged,
      expected_version_file,
      api.post_process(post_process.MustRun, 'push to refs/heads/dev'),
      api.post_process(post_process.StepCommandContains,
                       'push to refs/heads/dev', ['--atomic', '--dry-run']),
      api.post_process(post_process.StatusSuccess),
      api.post_process(post_process.DropExpectation),
  )

  from_ref_version_file = api.step_data(
      'download from_ref version file',
      api.gitiles.make_encoded_file('''# Updated Comment
CHANNEL abc
MAJOR 5
MINOR 2
PATCH 10
PRERELEASE 0
PRERELEASE_PATCH 0
UNKNOWN_FIELD cde
'''))
  expected_version_file = api.post_process(
      post_process.LogEquals, 'write new version file', 'VERSION',
      '''# Updated Comment
CHANNEL dev
MAJOR 5
MINOR 2
PATCH 10
PRERELEASE 0
PRERELEASE_PATCH 0
UNKNOWN_FIELD cde''')
  yield api.test(
      'push-version-mismatch',
      input_properties,
      from_ref_commit,
      from_ref_version_file,
      to_ref_version_file,
      unmerged,
      expected_version_file,
      api.post_process(post_process.MustRun, 'push to refs/heads/dev'),
      api.post_process(post_process.StepCommandContains,
                       'push to refs/heads/dev', [
                           '--atomic',
                           'https://dart.googlesource.com/sdk.git',
                           'refs/heads/dev',
                           'refs/tags/5.2.10-0.0.dev',
                       ]),
      api.post_process(post_process.StatusSuccess),
      api.post_process(post_process.DropExpectation),
  )
  from_ref_version_file = api.step_data(
      'download from_ref version file',
      api.gitiles.make_encoded_file('''# Comment
CHANNEL abc
MAJOR 4
MINOR 0
PATCH 2
PRERELEASE 0
PRERELEASE_PATCH 0
UNKNOWN_FIELD cde
'''))
  yield api.test('no-push-version-downgrade', input_properties, from_ref_commit,
                 from_ref_version_file, to_ref_version_file, unmerged,
                 *assertion_error)
