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

import re
from urlparse import urlparse

from recipe_engine import post_process

DEPS = [
    'fuchsia/gerrit',
    'fuchsia/gitiles',
    'fuchsia/status_check',
    'recipe_engine/buildbucket',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/step',
]

# The value of this footer should be an https git repo URL.
ROLLED_REPO_FOOTER = 'Rolled-Repo'

# This footer should have values of the form "<start_commit>..<end_commit>"
# (where <start_commit> is the old pinned revision, rather than the first
# rolled commit). For example, "9c21da0..5051fd4" includes all the commits
# after 9c21da0, up to and including 5051fd4.
ROLLED_COMMITS_FOOTER = 'Rolled-Commits'


def read_footer(commit_msg, footer_name):
  footer_line_prefix = '%s: ' % footer_name
  for line in reversed(commit_msg.splitlines()):
    if line.startswith(footer_line_prefix):
      return line[len(footer_line_prefix):].strip()
  return None


def gitiles_to_gerrit_host(gitiles_url):
  gitiles_host_parts = urlparse(gitiles_url).netloc.split('.')
  gerrit_hostname = '.'.join([gitiles_host_parts[0] + '-review'] +
                             gitiles_host_parts[1:])
  return 'https://%s' % gerrit_hostname


def RunSteps(api):
  commit = api.buildbucket.build.input.gitiles_commit
  assert commit.host and commit.project and commit.id, (
      'recipe must be triggered by a gitiles commit')

  dest_repo = 'https://%s/%s' % (commit.host, commit.project)
  dest_log = api.gitiles.log(
      dest_repo, commit.id, limit=1, step_name='get commit message')
  commit_msg = dest_log[0]['message']

  source_repo = read_footer(commit_msg, ROLLED_REPO_FOOTER)
  if not source_repo:
    api.step('no "%s" footer in commit message' % ROLLED_REPO_FOOTER, None)
    return

  commit_range = read_footer(commit_msg, ROLLED_COMMITS_FOOTER)
  assert commit_range, 'found "%s" footer but no "%s" footer' % (
      ROLLED_REPO_FOOTER, ROLLED_COMMITS_FOOTER)

  source_log = api.gitiles.log(
      source_repo, commit_range, step_name='log source repo')

  api.gerrit.host = gitiles_to_gerrit_host(source_repo)
  roll_cl_url = 'http://go/roll-cl/%s' % commit.id

  with api.step.nest('comment successful roll'):
    change_id_regex = re.compile(r'^Change-Id:\s*(\w+)\s*$', re.MULTILINE)
    for rolled_commit in source_log:
      # Check for Change-Id in the commit message. If no Change-Id is in the
      # message then commenting will fail, so don't bother trying to comment.
      # We still pass revision hash into gerrit.set_review() because Change-Ids
      # are sometimes copied when cherry-picking and are less reliable than a
      # revision hash at uniquely identifying a CL.
      if not change_id_regex.search(rolled_commit['message']):
        continue

      revision = rolled_commit['id']
      try:
        api.gerrit.set_review(
            'comment on %s' % revision,
            revision,
            message='Change has been successfully rolled: %s' % roll_cl_url,
            test_data=api.json.test_api.output({}),
        )
      except api.step.StepFailure:
        # Comment failures shouldn't fail the build or prevent the roller from
        # commenting on the rest of the changes.
        pass

      cl_link = '%s/q/%s' % (api.gerrit.host, revision)
      api.step.active_result.presentation.links['gerrit link'] = cl_link


def GenTests(api):
  # yapf: disable
  yield (
      api.status_check.test('basic')
      + api.buildbucket.ci_build()
      + api.gitiles.log(
          'get commit message',
          'A',
          n=1,
          extra_footers={
              ROLLED_REPO_FOOTER: 'https://foo.googlesource.com/bar-project',
              ROLLED_COMMITS_FOOTER: '1000005..100000a',
          })
      + api.gitiles.log('log source repo', 'B', n=6, add_change_id=True)
  )

  yield (
      api.status_check.test('no_change_ids')
      + api.buildbucket.ci_build()
      + api.gitiles.log(
          'get commit message',
          'A',
          n=1,
          extra_footers={
              ROLLED_REPO_FOOTER: 'https://foo.googlesource.com/bar-project',
              ROLLED_COMMITS_FOOTER: '1000005..100000a',
          })
      + api.gitiles.log('log source repo', 'B', n=1, add_change_id=False)
  )

  yield (
      api.status_check.test('no_footers')
      + api.buildbucket.ci_build()
      + api.gitiles.log('get commit message', 'A', n=1)
  )

  # If we get a Gerrit error commenting on the first CL, we should still try
  # comment on the second one.
  yield (
      api.status_check.test('failed_comment')
      + api.buildbucket.ci_build()
      + api.gitiles.log(
          'get commit message',
          'A',
          n=1,
          extra_footers={
              ROLLED_REPO_FOOTER: 'https://foo.googlesource.com/bar-project',
              ROLLED_COMMITS_FOOTER: '100000a..100000b',
          })
      + api.step_data(
          'log source repo',
          api.json.output([
              {'id': '100000a', 'message': 'Change-Id: Iabc'},
              {'id': '100000b', 'message': 'Change-Id: Ixyz'},
          ]))
      + api.step_data('comment successful roll.comment on 100000a', retcode=1)
      + api.post_process(
          post_process.MustRun, 'comment successful roll.comment on 100000b')
  )
  # yapf: enable
