#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 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.

"""The unified package/object bisecting tool."""

from __future__ import print_function

import abc
import argparse
from argparse import RawTextHelpFormatter
import os
import sys

from binary_search_tool import binary_search_state
from binary_search_tool import common

from cros_utils import command_executer
from cros_utils import logger


class Bisector(object, metaclass=abc.ABCMeta):
  """The abstract base class for Bisectors."""

  def __init__(self, options, overrides=None):
    """Constructor for Bisector abstract base class

    Args:
      options: positional arguments for specific mode (board, remote, etc.)
      overrides: optional dict of overrides for argument defaults
    """
    self.options = options
    self.overrides = overrides
    if not overrides:
      self.overrides = {}
    self.logger = logger.GetLogger()
    self.ce = command_executer.GetCommandExecuter()

  def _PrettyPrintArgs(self, args, overrides):
    """Output arguments in a nice, human readable format

    Will print and log all arguments for the bisecting tool and make note of
    which arguments have been overridden.

    Example output:
      ./run_bisect.py package daisy 172.17.211.184 -I "" -t cros_pkg/my_test.sh
      Performing ChromeOS Package bisection
      Method Config:
        board : daisy
       remote : 172.17.211.184

      Bisection Config: (* = overridden)
         get_initial_items : cros_pkg/get_initial_items.sh
            switch_to_good : cros_pkg/switch_to_good.sh
             switch_to_bad : cros_pkg/switch_to_bad.sh
       * test_setup_script :
       *       test_script : cros_pkg/my_test.sh
                     prune : True
             noincremental : False
                 file_args : True

    Args:
      args: The args to be given to binary_search_state.Run. This represents
            how the bisection tool will run (with overridden arguments already
            added in).
      overrides: The dict of overriden arguments provided by the user. This is
                 provided so the user can be told which arguments were
                 overriden and with what value.
    """
    # Output method config (board, remote, etc.)
    options = vars(self.options)
    out = '\nPerforming %s bisection\n' % self.method_name
    out += 'Method Config:\n'
    max_key_len = max([len(str(x)) for x in options.keys()])
    for key in sorted(options):
      val = options[key]
      key_str = str(key).rjust(max_key_len)
      val_str = str(val)
      out += ' %s : %s\n' % (key_str, val_str)

    # Output bisection config (scripts, prune, etc.)
    out += '\nBisection Config: (* = overridden)\n'
    max_key_len = max([len(str(x)) for x in args.keys()])
    # Print args in common._ArgsDict order
    args_order = [x['dest'] for x in common.GetArgsDict().values()]
    for key in sorted(args, key=args_order.index):
      val = args[key]
      key_str = str(key).rjust(max_key_len)
      val_str = str(val)
      changed_str = '*' if key in overrides else ' '

      out += ' %s %s : %s\n' % (changed_str, key_str, val_str)

    out += '\n'
    self.logger.LogOutput(out)

  def ArgOverride(self, args, overrides, pretty_print=True):
    """Override arguments based on given overrides and provide nice output

    Args:
      args: dict of arguments to be passed to binary_search_state.Run (runs
            dict.update, causing args to be mutated).
      overrides: dict of arguments to update args with
      pretty_print: if True print out args/overrides to user in pretty format
    """
    args.update(overrides)
    if pretty_print:
      self._PrettyPrintArgs(args, overrides)

  @abc.abstractmethod
  def PreRun(self):
    pass

  @abc.abstractmethod
  def Run(self):
    pass

  @abc.abstractmethod
  def PostRun(self):
    pass


class BisectPackage(Bisector):
  """The class for package bisection steps."""

  cros_pkg_setup = 'cros_pkg/setup.sh'
  cros_pkg_cleanup = 'cros_pkg/%s_cleanup.sh'

  def __init__(self, options, overrides):
    super(BisectPackage, self).__init__(options, overrides)
    self.method_name = 'ChromeOS Package'
    self.default_kwargs = {
        'get_initial_items': 'cros_pkg/get_initial_items.sh',
        'switch_to_good': 'cros_pkg/switch_to_good.sh',
        'switch_to_bad': 'cros_pkg/switch_to_bad.sh',
        'test_setup_script': 'cros_pkg/test_setup.sh',
        'test_script': 'cros_pkg/interactive_test.sh',
        'noincremental': False,
        'prune': True,
        'file_args': True
    }
    self.setup_cmd = ('%s %s %s' % (self.cros_pkg_setup, self.options.board,
                                    self.options.remote))
    self.ArgOverride(self.default_kwargs, self.overrides)

  def PreRun(self):
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(
        self.setup_cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Package bisector setup failed w/ error %d' % ret)
      return 1
    return 0

  def Run(self):
    return binary_search_state.Run(**self.default_kwargs)

  def PostRun(self):
    cmd = self.cros_pkg_cleanup % self.options.board
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Package bisector cleanup failed w/ error %d' % ret)
      return 1

    self.logger.LogOutput(('Cleanup successful! To restore the bisection '
                           'environment run the following:\n'
                           '  cd %s; %s') % (os.getcwd(), self.setup_cmd))
    return 0


class BisectObject(Bisector):
  """The class for object bisection steps."""

  sysroot_wrapper_setup = 'sysroot_wrapper/setup.sh'
  sysroot_wrapper_cleanup = 'sysroot_wrapper/cleanup.sh'

  def __init__(self, options, overrides):
    super(BisectObject, self).__init__(options, overrides)
    self.method_name = 'ChromeOS Object'
    self.default_kwargs = {
        'get_initial_items': 'sysroot_wrapper/get_initial_items.sh',
        'switch_to_good': 'sysroot_wrapper/switch_to_good.sh',
        'switch_to_bad': 'sysroot_wrapper/switch_to_bad.sh',
        'test_setup_script': 'sysroot_wrapper/test_setup.sh',
        'test_script': 'sysroot_wrapper/interactive_test.sh',
        'noincremental': False,
        'prune': True,
        'file_args': True
    }
    self.options = options
    if options.dir:
      os.environ['BISECT_DIR'] = options.dir
    self.options.dir = os.environ.get('BISECT_DIR', '/tmp/sysroot_bisect')
    self.setup_cmd = (
        '%s %s %s %s' % (self.sysroot_wrapper_setup, self.options.board,
                         self.options.remote, self.options.package))

    self.ArgOverride(self.default_kwargs, overrides)

  def PreRun(self):
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(
        self.setup_cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Object bisector setup failed w/ error %d' % ret)
      return 1

    os.environ['BISECT_STAGE'] = 'TRIAGE'
    return 0

  def Run(self):
    return binary_search_state.Run(**self.default_kwargs)

  def PostRun(self):
    cmd = self.sysroot_wrapper_cleanup
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Object bisector cleanup failed w/ error %d' % ret)
      return 1
    self.logger.LogOutput(('Cleanup successful! To restore the bisection '
                           'environment run the following:\n'
                           '  cd %s; %s') % (os.getcwd(), self.setup_cmd))
    return 0


class BisectAndroid(Bisector):
  """The class for Android bisection steps."""

  android_setup = 'android/setup.sh'
  android_cleanup = 'android/cleanup.sh'
  default_dir = os.path.expanduser('~/ANDROID_BISECT')

  def __init__(self, options, overrides):
    super(BisectAndroid, self).__init__(options, overrides)
    self.method_name = 'Android'
    self.default_kwargs = {
        'get_initial_items': 'android/get_initial_items.sh',
        'switch_to_good': 'android/switch_to_good.sh',
        'switch_to_bad': 'android/switch_to_bad.sh',
        'test_setup_script': 'android/test_setup.sh',
        'test_script': 'android/interactive_test.sh',
        'prune': True,
        'file_args': True,
        'noincremental': False,
    }
    self.options = options
    if options.dir:
      os.environ['BISECT_DIR'] = options.dir
    self.options.dir = os.environ.get('BISECT_DIR', self.default_dir)

    num_jobs = "NUM_JOBS='%s'" % self.options.num_jobs
    device_id = ''
    if self.options.device_id:
      device_id = "ANDROID_SERIAL='%s'" % self.options.device_id

    self.setup_cmd = ('%s %s %s %s' % (num_jobs, device_id, self.android_setup,
                                       self.options.android_src))

    self.ArgOverride(self.default_kwargs, overrides)

  def PreRun(self):
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(
        self.setup_cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Android bisector setup failed w/ error %d' % ret)
      return 1

    os.environ['BISECT_STAGE'] = 'TRIAGE'
    return 0

  def Run(self):
    return binary_search_state.Run(**self.default_kwargs)

  def PostRun(self):
    cmd = self.android_cleanup
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(cmd, print_to_console=True)
    if ret:
      self.logger.LogError('Android bisector cleanup failed w/ error %d' % ret)
      return 1
    self.logger.LogOutput(('Cleanup successful! To restore the bisection '
                           'environment run the following:\n'
                           '  cd %s; %s') % (os.getcwd(), self.setup_cmd))
    return 0


def Run(bisector):
  log = logger.GetLogger()

  log.LogOutput('Setting up Bisection tool')
  ret = bisector.PreRun()
  if ret:
    return ret

  log.LogOutput('Running Bisection tool')
  ret = bisector.Run()
  if ret:
    return ret

  log.LogOutput('Cleaning up Bisection tool')
  ret = bisector.PostRun()
  if ret:
    return ret

  return 0


_HELP_EPILOG = """
Run ./run_bisect.py {method} --help for individual method help/args

------------------

See README.bisect for examples on argument overriding

See below for full override argument reference:
"""


def Main(argv):
  override_parser = argparse.ArgumentParser(
      add_help=False,
      argument_default=argparse.SUPPRESS,
      usage='run_bisect.py {mode} [options]')
  common.BuildArgParser(override_parser, override=True)

  epilog = _HELP_EPILOG + override_parser.format_help()
  parser = argparse.ArgumentParser(
      epilog=epilog, formatter_class=RawTextHelpFormatter)
  subparsers = parser.add_subparsers(
      title='Bisect mode',
      description=('Which bisection method to '
                   'use. Each method has '
                   'specific setup and '
                   'arguments. Please consult '
                   'the README for more '
                   'information.'))

  parser_package = subparsers.add_parser('package')
  parser_package.add_argument('board', help='Board to target')
  parser_package.add_argument('remote', help='Remote machine to test on')
  parser_package.set_defaults(handler=BisectPackage)

  parser_object = subparsers.add_parser('object')
  parser_object.add_argument('board', help='Board to target')
  parser_object.add_argument('remote', help='Remote machine to test on')
  parser_object.add_argument('package', help='Package to emerge and test')
  parser_object.add_argument(
      '--dir',
      help=('Bisection directory to use, sets '
            '$BISECT_DIR if provided. Defaults to '
            'current value of $BISECT_DIR (or '
            '/tmp/sysroot_bisect if $BISECT_DIR is '
            'empty).'))
  parser_object.set_defaults(handler=BisectObject)

  parser_android = subparsers.add_parser('android')
  parser_android.add_argument('android_src', help='Path to android source tree')
  parser_android.add_argument(
      '--dir',
      help=('Bisection directory to use, sets '
            '$BISECT_DIR if provided. Defaults to '
            'current value of $BISECT_DIR (or '
            '~/ANDROID_BISECT/ if $BISECT_DIR is '
            'empty).'))
  parser_android.add_argument(
      '-j',
      '--num_jobs',
      type=int,
      default=1,
      help=('Number of jobs that make and various '
            'scripts for bisector can spawn. Setting '
            'this value too high can freeze up your '
            'machine!'))
  parser_android.add_argument(
      '--device_id',
      default='',
      help=('Device id for device used for testing. '
            'Use this if you have multiple Android '
            'devices plugged into your machine.'))
  parser_android.set_defaults(handler=BisectAndroid)

  options, remaining = parser.parse_known_args(argv)
  if remaining:
    overrides = override_parser.parse_args(remaining)
    overrides = vars(overrides)
  else:
    overrides = {}

  subcmd = options.handler
  del options.handler

  bisector = subcmd(options, overrides)
  return Run(bisector)


if __name__ == '__main__':
  os.chdir(os.path.dirname(__file__))
  sys.exit(Main(sys.argv[1:]))
