# Copyright (c) 2020, the Dart project 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 recipe_api

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.go.chromium.org.luci.buildbucket.proto import rpc as rpc_pb2


class BisectApi(recipe_api.RecipeApi):

  def _get_reason(self):
    return self.m.properties['bisect_reason']

  def is_bisecting(self):
    return 'bisect_reason' in self.m.properties

  def schedule(self, repo_url, reason):
    if self.is_bisecting():
      bisect_reason = self._get_reason()
      if bisect_reason == reason:
        self._bisect_older(bisect_reason)
      else:
        self._bisect_newer(bisect_reason)
        # The build failed for a different reason, fan out to find the root
        # cause of that failure as well.
        self._bisect_older(reason)
    else:
      self._start_bisection(repo_url, reason)

  def _start_bisection(self, repo_url, reason):
    current_rev = self.m.buildbucket.gitiles_commit.id
    if not current_rev:
      return

    # Search for previous builds created by the Luci scheduler (to exclude
    # bisection builds). The TimeRange includes all builds from start_time
    # (defaults to 0) to end_time (exclusive). Because builds are ordered by
    # create_time, the first result will be the previous build.
    create_time = common_pb2.TimeRange(
        end_time=self.m.buildbucket.build.create_time)
    builder = self.m.buildbucket.build.builder
    search_predicate = rpc_pb2.BuildPredicate(
        builder=builder,
        create_time=create_time,
        tags=[common_pb2.StringPair(key='user_agent', value='luci-scheduler')])
    result = self.m.buildbucket.search(
        search_predicate, limit=1, step_name='fetch previous build')
    if not result or len(result) == 0:
      # There is no previous build: do not bisect on new builders.
      return
    previous_build = result[0]
    if previous_build.status == common_pb2.FAILURE:
      # Do not bisect if the previous build failed.
      # TODO(athom): Check if the failure reason is the same by adding
      #              'builds.*.summaryMarkdown' to the field mask.
      return
    previous_rev = previous_build.input.gitiles_commit.id
    # We're intentionally not paging through the log to avoid bisecting an
    # excessive number of commits.
    commits, _ = self.m.gitiles.log(
        url=repo_url, ref='%s..%s' % (previous_rev, current_rev))
    commits = commits[1:]  # The first commit is the current_rev
    commits = [commit['commit'] for commit in commits]
    self._bisect(commits, reason)

  def _bisect(self, commits, reason):
    if len(commits) == 0:
      # Nothing more to bisect.
      return

    middle_index = len(commits) // 2
    newer = commits[:middle_index]
    middle = commits[middle_index]
    older = commits[middle_index + 1:]

    commit = self.m.buildbucket.gitiles_commit
    middle_commit = common_pb2.GitilesCommit()
    middle_commit.CopyFrom(commit)
    middle_commit.id = middle
    builder = self.m.buildbucket.build.builder
    request = self.m.buildbucket.schedule_request(
        builder=builder.builder,
        project=builder.project,
        bucket=builder.bucket,
        properties={
            'bisect_newer': newer,
            'bisect_older': older,
            'bisect_reason': reason
        },
        gitiles_commit=middle_commit,
        inherit_buildsets=False,
    )
    self.m.buildbucket.schedule([request],
                                step_name='schedule bisect (%s)' % middle)

  def _bisect_newer(self, reason):
    self._bisect(list(self.m.properties.get('bisect_newer', [])), reason)

  def _bisect_older(self, reason):
    self._bisect(list(self.m.properties.get('bisect_older', [])), reason)
