# 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 builds_service as builds_service_pb2


class BisectApi(recipe_api.RecipeApi):
  REASON_SUCCESS = 'SUCCESS'

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

  def get_base_build(self):
    return self.m.properties['bisect_base_build']

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

  @property
  def is_enabled(self):  # pragma: no cover
    return self.m.properties.get('bisection_enabled', False)

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

  def _start_bisection(self, repo_url, reason, is_experimental):
    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 = builds_service_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]
    base_build = previous_build.number
    self._bisect(commits, reason, is_experimental, base_build)

  def _bisect(self, commits, reason, is_experimental, base_build):
    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
    properties = {
        'bisection_enabled': True,
        'bisect_newer': newer,
        'bisect_older': older,
        'bisect_reason': reason,
        'bisect_base_build': base_build,
    }
    schedule_experimental = (
        True if is_experimental else self.m.buildbucket.INHERIT)
    request = self.m.buildbucket.schedule_request(
        builder=builder.builder,
        project=builder.project,
        bucket=builder.bucket,
        properties=properties,
        gitiles_commit=middle_commit,
        inherit_buildsets=False,
        experimental=schedule_experimental,
    )
    self.m.buildbucket.schedule([request],
                                step_name='schedule bisect (%s)' % middle)

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

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