# -*- coding: utf-8 -*-
# Copyright 2017 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Bisect culprit commit that causes regression."""

from __future__ import print_function

import argparse

from chromite.cros_bisect import autotest_evaluator
from chromite.cros_bisect import chrome_on_cros_bisector
from chromite.cros_bisect import manual_evaluator
from chromite.cros_bisect import simple_chrome_builder
from chromite.cli import command
from chromite.lib import commandline
from chromite.lib import cros_logging as logging
from chromite.lib import remote_access


def GoodBadCommitType(value):
  """Checks if the input is legal last known good/bad string.

  Currently, the legal formats are:
  1. SHA1 (for Chromium commit)
  2. CrOS version, e.g. R60-9531.0.0 or 60.9531.0.0

  Args:
    value: string to represent last known good/bad commit/version.

  Returns:
    Normalized commit/version value.

  Raises:
    argparse.ArgumentTypeError if input is illegal.
  """
  normalized_value = (
      chrome_on_cros_bisector.ChromeOnCrosBisector.CheckCommitFormat(value))
  if not normalized_value:
    raise argparse.ArgumentTypeError(
        '%s is neither commit SHA1 or CrOS version.' % value)
  return normalized_value


@command.CommandDecorator('bisect')
class BisectCommand(command.CliCommand):
  """Bisect commits to find the culprit responsible for regression."""

  EPILOG = """
Bisects commits of the given repository within given range, builds Chromium for
CrOS, deploys to DUT (device under test) and run the verifier to decide if the
commit is good or bad to find the culprit commit. Right now, supported
repository is Chromium; supported verifier is Autotest.
Note that before starting "cros bisect" please install an OS image on the DUT
that is close to the failure point, in particular from the corresponding branch.
"""

  REPO = ('chromium', )
  BUILDER = {'chromium': simple_chrome_builder.SimpleChromeBuilder}
  EVALUATOR = {'autotest': autotest_evaluator.AutotestEvaluator,
               'manual': manual_evaluator.ManualEvaluator}

  @classmethod
  def AddParser(cls, parser):
    super(BisectCommand, cls).AddParser(parser)
    parser.add_argument(
        '-G', '--good', metavar='good_commit', required=True,
        type=GoodBadCommitType,
        help='A good revision (commit SHA) or CrOS image (e.g. R60-9531.0.0) '
             'to start bisection. Should be earlier than the bad revision.')
    parser.add_argument(
        '-B', '--bad', metavar='bad_commit', required=True,
        type=GoodBadCommitType,
        help='A bad revision (commit SHA) or CrOS image (e.g. R60-9532.0.0) '
             'to start bisection. Should be later than the good revision.')
    parser.add_argument(
        '-r', '--remote', metavar='IP address / hostname', required=True,
        type=commandline.DeviceParser(commandline.DEVICE_SCHEME_SSH),
        help='The IP address/hostname of remote device which is going to test.')
    parser.add_argument(
        '-b', '--board', metavar='board_name',
        help='The board name of the ChromeOS device under test. Obtained from '
             'DUT if not assigned.')
    parser.add_argument(
        '--repo', default='chromium', choices=cls.REPO,
        help='Repository to bisect. Now it supports chormium git repository. '
             'Later it will support catapult git repository and even ChromeOS '
             'repositories.')
    parser.add_argument(
        '--evaluator', default='autotest', choices=cls.EVALUATOR.keys(),
        help='Evaluator used to determine if a commit is good or bad. Now it '
             'supports autotest. Later it will support telemetry.')
    parser.add_argument(
        '-d', '--base-dir', required=True, type='path',
        help='Base directory to store repo and results. Existing checkout can '
             'be used, see --reuse-repo.')
    parser.add_argument(
        '--chromium-dir', type='path',
        help='If specified, use it as chromium repository. Otherwise, use '
             '"[base-dir]/chromium".')
    parser.add_argument(
        '--cros-dir', type='path',
        help='If specified, use it to enter CrOS chroot environment. '
             'Otherwise, use "[base-dir]/cros".')
    parser.add_argument(
        '--build-dir', type='path',
        help='If specified, use it to store build results. Otherwise, use '
             '"[base-dir]/build".')
    parser.add_argument(
        '--reuse-repo', action='store_true',
        help='If set, reuse repository if it exists.')
    parser.add_argument(
        '--reuse-build', action='store_true',
        help='If set, reuse build if available.')
    parser.add_argument(
        '--reuse-eval', action='store_true',
        help='If set, reuse evaluation result if available.')
    parser.add_argument(
        '--reuse', action='store_true',
        help='If set, set reuse-repo, reuse-build, reuse-eval')
    parser.add_argument(
        '--no-archive-build', dest='archive_build', default=True,
        action='store_false',
        help='If set, do not archive the build.')
    parser.add_argument(
        '--auto-threshold', action='store_true',
        help='If set, set threshold in the middle between good and bad '
             'score instead of prompting user to set it.')
    parser.add_argument(
        '--test-name', help='Test name to run against')
    parser.add_argument(
        '--metric',
        help='Metric of test result to look at. For autotest, metric name is '
             'hierarchical, divided by "/". E.g., "avg_fps_1000_fishes/summary/'
             'value" for graphics_WebGLAquarium, or "charts/Total/Score/value" '
             'for telemetry_Benchmarks.octane autotest.')
    parser.add_argument(
        '--metric-take-average', action='store_true',
        help='If set, treat metric value as a list of numbers and calculate '
             'arithmetic average of them.')
    parser.add_argument(
        '--eval-repeat', type=int, default=3,
        help='Repeat evaluate commit for N times to calculate mean and '
             'standard deviation. Default 3.')
    parser.add_argument(
        '--cros-flash-retry', type=int, default=3,
        help='Max #retry for "cros flash" command. Default 3.')
    parser.add_argument(
        '--cros-flash-sleep', type=int, default=60,
        help='Wait #seconds before retry. See cros-flash-backoff for detail.')
    parser.add_argument(
        '--cros-flash-backoff', type=float, default=1,
        help='Backoff factor for sleep between "cros flash" retry. If backoff '
             'factor is 1, sleep_duration = sleep * num_retry. Otherwise, '
             'sleep_duration = sleep * (backoff_factor) ** (num_retry - 1)')

  def ProcessOptions(self):
    """Process self.options.

    It sets reuse_repo, reuse_build and reuse_eval if self.options.reuse is set.
    It also resolves self.options.board from DUT if it is not assigned.
    """
    if self.options.reuse:
      self.options.reuse_repo = True
      self.options.reuse_build = True
      self.options.reuse_eval = True
    if not self.options.board:
      dut = remote_access.ChromiumOSDevice(self.options.remote.hostname)
      self.options.board = dut.board
      if not self.options.board:
        raise Exception('Unable to obtain board name from DUT.')
      else:
        logging.info('Obtained board name "%s" from DUT.', self.options.board)

  def Run(self):
    self.ProcessOptions()
    # Note that for the objects consuming command line options, please evaluate
    # its SanityCheckOptions() in testAddParser in cros_bisect_unittest.
    builder = self.BUILDER[self.options.repo](self.options)
    evaluator = self.EVALUATOR[self.options.evaluator](self.options)
    bisector = chrome_on_cros_bisector.ChromeOnCrosBisector(
        self.options, builder, evaluator)
    bisector.SetUp()
    bisector.Run()
