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

PYTHON_VERSION_COMPATIBILITY = "PY3"


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)
