#!/usr/bin/env python2

# Copyright 2018 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 binary search wrapper."""

from __future__ import print_function

import argparse
import contextlib
import errno
import math
import os
import pickle
import re
import shutil
import sys
import tempfile
import time

# Adds cros_utils to PYTHONPATH
import common

# Now we do import from cros_utils
from cros_utils import command_executer
from cros_utils import logger

import binary_search_perforce
import pass_mapping

GOOD_SET_VAR = 'BISECT_GOOD_SET'
BAD_SET_VAR = 'BISECT_BAD_SET'

STATE_FILE = '%s.state' % sys.argv[0]
HIDDEN_STATE_FILE = os.path.join(
    os.path.dirname(STATE_FILE), '.%s' % os.path.basename(STATE_FILE))


class Error(Exception):
  """The general binary search tool error class."""
  pass


@contextlib.contextmanager
def SetFile(env_var, items):
  """Generate set files that can be used by switch/test scripts.

  Generate temporary set file (good/bad) holding contents of good/bad items for
  the current binary search iteration. Store the name of each file as an
  environment variable so all child processes can access it.

  This function is a contextmanager, meaning it's meant to be used with the
  "with" statement in Python. This is so cleanup and setup happens automatically
  and cleanly. Execution of the outer "with" statement happens at the "yield"
  statement.

  Args:
    env_var: What environment variable to store the file name in.
    items: What items are in this set.
  """
  with tempfile.NamedTemporaryFile() as f:
    os.environ[env_var] = f.name
    f.write('\n'.join(items))
    f.flush()
    yield


class BinarySearchState(object):
  """The binary search state class."""

  def __init__(self, get_initial_items, switch_to_good, switch_to_bad,
               test_setup_script, test_script, incremental, prune, pass_bisect,
               ir_diff, iterations, prune_iterations, verify, file_args,
               verbose):
    """BinarySearchState constructor, see Run for full args documentation."""
    self.get_initial_items = get_initial_items
    self.switch_to_good = switch_to_good
    self.switch_to_bad = switch_to_bad
    self.test_setup_script = test_setup_script
    self.test_script = test_script
    self.incremental = incremental
    self.prune = prune
    self.pass_bisect = pass_bisect
    self.ir_diff = ir_diff
    self.iterations = iterations
    self.prune_iterations = prune_iterations
    self.verify = verify
    self.file_args = file_args
    self.verbose = verbose

    self.l = logger.GetLogger()
    self.ce = command_executer.GetCommandExecuter()

    self.resumed = False
    self.prune_cycles = 0
    self.search_cycles = 0
    self.binary_search = None
    self.all_items = None
    self.cmd_script = None
    self.mode = None
    self.PopulateItemsUsingCommand(self.get_initial_items)
    self.currently_good_items = set([])
    self.currently_bad_items = set([])
    self.found_items = set([])
    self.known_good = set([])

    self.start_time = time.time()

  def SwitchToGood(self, item_list):
    """Switch given items to "good" set."""
    if self.incremental:
      self.l.LogOutput(
          'Incremental set. Wanted to switch %s to good' % str(item_list),
          print_to_console=self.verbose)
      incremental_items = [
          item for item in item_list if item not in self.currently_good_items
      ]
      item_list = incremental_items
      self.l.LogOutput(
          'Incremental set. Actually switching %s to good' % str(item_list),
          print_to_console=self.verbose)

    if not item_list:
      return

    self.l.LogOutput(
        'Switching %s to good' % str(item_list), print_to_console=self.verbose)
    self.RunSwitchScript(self.switch_to_good, item_list)
    self.currently_good_items = self.currently_good_items.union(set(item_list))
    self.currently_bad_items.difference_update(set(item_list))

  def SwitchToBad(self, item_list):
    """Switch given items to "bad" set."""
    if self.incremental:
      self.l.LogOutput(
          'Incremental set. Wanted to switch %s to bad' % str(item_list),
          print_to_console=self.verbose)
      incremental_items = [
          item for item in item_list if item not in self.currently_bad_items
      ]
      item_list = incremental_items
      self.l.LogOutput(
          'Incremental set. Actually switching %s to bad' % str(item_list),
          print_to_console=self.verbose)

    if not item_list:
      return

    self.l.LogOutput(
        'Switching %s to bad' % str(item_list), print_to_console=self.verbose)
    self.RunSwitchScript(self.switch_to_bad, item_list)
    self.currently_bad_items = self.currently_bad_items.union(set(item_list))
    self.currently_good_items.difference_update(set(item_list))

  def RunSwitchScript(self, switch_script, item_list):
    """Pass given items to switch script.

    Args:
      switch_script: path to switch script
      item_list: list of all items to be switched
    """
    if self.file_args:
      with tempfile.NamedTemporaryFile() as f:
        f.write('\n'.join(item_list))
        f.flush()
        command = '%s %s' % (switch_script, f.name)
        ret, _, _ = self.ce.RunCommandWExceptionCleanup(
            command, print_to_console=self.verbose)
    else:
      command = '%s %s' % (switch_script, ' '.join(item_list))
      try:
        ret, _, _ = self.ce.RunCommandWExceptionCleanup(
            command, print_to_console=self.verbose)
      except OSError as e:
        if e.errno == errno.E2BIG:
          raise Error('Too many arguments for switch script! Use --file_args')
        else:
          raise
    assert ret == 0, 'Switch script %s returned %d' % (switch_script, ret)

  def TestScript(self):
    """Run test script and return exit code from script."""
    command = self.test_script
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(command)
    return ret

  def TestSetupScript(self):
    """Run test setup script and return exit code from script."""
    if not self.test_setup_script:
      return 0

    command = self.test_setup_script
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(command)
    return ret

  def GenerateBadCommandScript(self, bad_items):
    """Generate command line script for building bad item."""
    assert not self.prune, 'Prune must be false if pass_bisect is set.'
    assert len(bad_items) == 1, 'Pruning is off, but number of bad ' \
                                       'items found was not 1.'
    item = list(bad_items)[0]
    command = '%s %s' % (self.pass_bisect, item)
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(
        command, print_to_console=self.verbose)
    return ret

  def DoVerify(self):
    """Verify correctness of test environment.

    Verify that a "good" set of items produces a "good" result and that a "bad"
    set of items produces a "bad" result. To be run directly before running
    DoSearch. If verify is False this step is skipped.
    """
    if not self.verify:
      return

    self.l.LogOutput('VERIFICATION')
    self.l.LogOutput('Beginning tests to verify good/bad sets\n')

    self._OutputProgress('Verifying items from GOOD set\n')
    with SetFile(GOOD_SET_VAR, self.all_items), SetFile(BAD_SET_VAR, []):
      self.l.LogOutput('Resetting all items to good to verify.')
      self.SwitchToGood(self.all_items)
      status = self.TestSetupScript()
      assert status == 0, 'When reset_to_good, test setup should succeed.'
      status = self.TestScript()
      assert status == 0, 'When reset_to_good, status should be 0.'

    self._OutputProgress('Verifying items from BAD set\n')
    with SetFile(GOOD_SET_VAR, []), SetFile(BAD_SET_VAR, self.all_items):
      self.l.LogOutput('Resetting all items to bad to verify.')
      self.SwitchToBad(self.all_items)
      status = self.TestSetupScript()
      # The following assumption is not true; a bad image might not
      # successfully push onto a device.
      # assert status == 0, 'When reset_to_bad, test setup should succeed.'
      if status == 0:
        status = self.TestScript()
      assert status == 1, 'When reset_to_bad, status should be 1.'

  def DoSearchBadItems(self):
    """Perform full search for bad items.

    Perform full search until prune_iterations number of bad items are found.
    """
    while (True and len(self.all_items) > 1 and
           self.prune_cycles < self.prune_iterations):
      terminated = self.DoBinarySearchBadItems()
      self.prune_cycles += 1
      if not terminated:
        break
      # Prune is set.
      prune_index = self.binary_search.current

      # If found item is last item, no new items can be found
      if prune_index == len(self.all_items) - 1:
        self.l.LogOutput('First bad item is the last item. Breaking.')
        self.l.LogOutput('Bad items are: %s' % self.all_items[-1])
        self.found_items.add(self.all_items[-1])
        break

      # If already seen item we have no new bad items to find, finish up
      if self.all_items[prune_index] in self.found_items:
        self.l.LogOutput(
            'Found item already found before: %s.' %
            self.all_items[prune_index],
            print_to_console=self.verbose)
        self.l.LogOutput('No more bad items remaining. Done searching.')
        self.l.LogOutput('Bad items are: %s' % ' '.join(self.found_items))
        break

      new_all_items = list(self.all_items)
      # Move prune item to the end of the list.
      new_all_items.append(new_all_items.pop(prune_index))
      self.found_items.add(new_all_items[-1])

      # Everything below newly found bad item is now known to be a good item.
      # Take these good items out of the equation to save time on the next
      # search. We save these known good items so they are still sent to the
      # switch_to_good script.
      if prune_index:
        self.known_good.update(new_all_items[:prune_index])
        new_all_items = new_all_items[prune_index:]

      self.l.LogOutput(
          'Old list: %s. New list: %s' % (str(self.all_items),
                                          str(new_all_items)),
          print_to_console=self.verbose)

      if not self.prune:
        self.l.LogOutput('Not continuning further, --prune is not set')
        break
      # FIXME: Do we need to Convert the currently good items to bad
      self.PopulateItemsUsingList(new_all_items)

    # If pass level bisecting is set, generate a script which contains command
    # line options to rebuild bad item.
    if self.pass_bisect:
      status = self.GenerateBadCommandScript(self.found_items)
      if status == 0:
        self.cmd_script = os.path.join(
            os.path.dirname(self.pass_bisect), 'cmd_script.sh')
        self.l.LogOutput('Command script generated at %s.' % self.cmd_script)
      else:
        raise RuntimeError('Error while generating command script.')

  def DoBinarySearchBadItems(self):
    """Perform single iteration of binary search."""
    # If in resume mode don't reset search_cycles
    if not self.resumed:
      self.search_cycles = 0
    else:
      self.resumed = False

    terminated = False
    while self.search_cycles < self.iterations and not terminated:
      self.SaveState()
      self.OutputIterationProgressBadItem()

      self.search_cycles += 1
      [bad_items, good_items] = self.GetNextItems()

      with SetFile(GOOD_SET_VAR, good_items), SetFile(BAD_SET_VAR, bad_items):
        # TODO: bad_items should come first.
        self.SwitchToGood(good_items)
        self.SwitchToBad(bad_items)
        status = self.TestSetupScript()
        if status == 0:
          status = self.TestScript()
        terminated = self.binary_search.SetStatus(status)

      if terminated:
        self.l.LogOutput('Terminated!', print_to_console=self.verbose)
    if not terminated:
      self.l.LogOutput('Ran out of iterations searching...')
    self.l.LogOutput(str(self), print_to_console=self.verbose)
    return terminated

  def CollectPassName(self, pass_info):
    """Mapping opt-bisect output of pass info to debugcounter name."""
    self.l.LogOutput('Pass info: %s' % pass_info, print_to_console=self.verbose)

    for desc in pass_mapping.pass_name:
      if desc in pass_info:
        return pass_mapping.pass_name[desc]

    # If pass not found, return None
    return None

  def BuildWithPassLimit(self, limit, generate_ir=False):
    """ Rebuild bad item with pass level bisect limit

    Run command line script generated by GenerateBadCommandScript(), with
    pass level limit flags.

    Return:
      pass_num: current number of the pass, or total number of passes if
                limit set to -1.
      pass_name: The debugcounter name of current limit pass.
    """
    os.environ['LIMIT_FLAGS'] = '-mllvm -opt-bisect-limit=' + str(limit)
    if generate_ir:
      os.environ['LIMIT_FLAGS'] += ' -S -emit-llvm'
    self.l.LogOutput(
        'Limit flags: %s' % os.environ['LIMIT_FLAGS'],
        print_to_console=self.verbose)
    command = self.cmd_script
    _, _, msg = self.ce.RunCommandWOutput(command, print_to_console=False)

    # Massages we get will be like this:
    #   BISECT: running pass (9) <Pass Description> on <function> (<file>)
    #   BISECT: running pass (10) <Pass Description> on <module> (<file>)
    #   BISECT: NOT running pass (11) <Pass Description> on <SCG> (<file>)
    #   BISECT: NOT running pass (12) <Pass Description> on <SCG> (<file>)
    # We want to get the pass description of last running pass, to have
    # transformation level bisect on it.
    if 'BISECT: ' not in msg:
      raise RuntimeError('No bisect info printed, OptBisect may not be '
                         'supported by the compiler.')

    lines = msg.split('\n')
    pass_num = 0
    last_pass = ''
    for l in lines:
      if 'running pass' in l:
        # For situation of limit==-1, we want the total number of passes
        if limit != -1 and 'BISECT: NOT ' in l:
          break
        pass_num += 1
        last_pass = l
    if limit != -1 and pass_num != limit:
      raise ValueError('[Error] While building, limit number does not match.')
    return pass_num, self.CollectPassName(last_pass)

  def BuildWithTransformLimit(self,
                              limit,
                              pass_name=None,
                              pass_limit=-1,
                              generate_ir=False):
    """ Rebuild bad item with transformation level bisect limit

    Run command line script generated by GenerateBadCommandScript(), with
    pass level limit flags and transformation level limit flags.

    Args:
      limit: transformation level limit for bad item
      pass_name: name of bad pass debugcounter from pass level bisect result
      pass_limit: pass level limit from pass level bisect result
    Return: Total number of transformations if limit set to -1, else return 0.
    """
    counter_name = pass_name

    os.environ['LIMIT_FLAGS'] = '-mllvm -opt-bisect-limit=' + \
                                str(pass_limit) + \
                                ' -mllvm -debug-counter=' + counter_name + \
                                '-count=' + str(limit) + \
                                ' -mllvm -print-debug-counter'
    if generate_ir:
      os.environ['LIMIT_FLAGS'] += ' -S -emit-llvm'
    self.l.LogOutput(
        'Limit flags: %s' % os.environ['LIMIT_FLAGS'],
        print_to_console=self.verbose)
    command = self.cmd_script
    _, _, msg = self.ce.RunCommandWOutput(command, print_to_console=False)

    if 'Counters and values:' not in msg:
      # Print pass level IR diff only if transformation level bisection does
      # not work.
      if self.ir_diff:
        self.PrintIRDiff(pass_limit)
      raise RuntimeError('No bisect info printed, DebugCounter may not be '
                         'supported by the compiler.')

    # With debugcounter enabled, there will be DebugCounter counting info in
    # the output.
    lines = msg.split('\n')
    for l in lines:
      if pass_name in l:
        # Output of debugcounter will be like:
        #   instcombine-visit: {10, 0, 20}
        #   dce-transform: {1, 0, -1}
        # which indicates {Count, Skip, StopAfter}.
        # The last number should be the limit we set.
        # We want the first number as the total transformation count.
        # Split each line by ,|{|} and we can get l_list as:
        #   ['instcombine: ', '10', '0', '20', '']
        # and we will need the second item in it.
        l_list = re.split(',|{|}', l)
        count = int(l_list[1])
        if limit == -1:
          return count
    # The returned value is only useful when limit == -1, which shows total
    # transformation count.
    return 0

  def PrintIRDiff(self, pass_index, pass_name=None, trans_index=-1):
    bad_item = list(self.found_items)[0]
    self.l.LogOutput(
        'IR difference before and after bad pass/transformation:',
        print_to_console=self.verbose)

    if trans_index == -1:
      # Pass level IR diff
      self.BuildWithPassLimit(pass_index, self.ir_diff)
      good_ir = os.path.join(tempfile.tempdir, 'good.s')
      shutil.copyfile(bad_item, good_ir)
      pass_index += 1
      self.BuildWithPassLimit(pass_index, self.ir_diff)
    else:
      # Transformation level IR diff
      self.BuildWithTransformLimit(trans_index, pass_name, pass_index,
                                   self.ir_diff)
      good_ir = os.path.join(tempfile.tempdir, 'good.s')
      shutil.copyfile(bad_item, good_ir)
      trans_index += 1
      self.BuildWithTransformLimit(trans_index, pass_name, pass_index,
                                   self.ir_diff)

    bad_ir = os.path.join(tempfile.tempdir, 'bad.s')
    shutil.copyfile(bad_item, bad_ir)

    command = 'diff %s %s' % (good_ir, bad_ir)
    _, _, _ = self.ce.RunCommandWOutput(command, print_to_console=self.verbose)

  def DoSearchBadPass(self):
    """Perform full search for bad pass of bad item."""
    logger.GetLogger().LogOutput('Starting to bisect bad pass for bad item.')

    # Pass level bisection
    self.mode = 'pass'
    self.binary_search = binary_search_perforce.BinarySearcherForPass(
        logger_to_set=self.l)
    self.binary_search.total, _ = self.BuildWithPassLimit(-1)
    logger.GetLogger().LogOutput(
        'Total %s number: %d' % (self.mode, self.binary_search.total))

    pass_index, pass_name = self.DoBinarySearchBadPass()

    if (not pass_name and pass_index == 0):
      raise ValueError('Bisecting passes cannot reproduce good result.')
    logger.GetLogger().LogOutput('Bad pass found: %s.' % pass_name)

    # Transformation level bisection.
    logger.GetLogger().LogOutput('Starting to bisect at transformation level.')

    self.mode = 'transform'
    self.binary_search = binary_search_perforce.BinarySearcherForPass(
        logger_to_set=self.l)
    self.binary_search.total = self.BuildWithTransformLimit(
        -1, pass_name, pass_index)
    logger.GetLogger().LogOutput(
        'Total %s number: %d' % (self.mode, self.binary_search.total))

    trans_index, _ = self.DoBinarySearchBadPass(pass_index, pass_name)
    if (trans_index == 0):
      raise ValueError('Bisecting %s cannot reproduce good result.' % pass_name)

    if self.ir_diff:
      self.PrintIRDiff(pass_index, pass_name, trans_index)

    logger.GetLogger().LogOutput(
        'Bisection result for bad item %s:\n'
        'Bad pass: %s at number %d\n'
        'Bad transformation number: %d' % (self.found_items, pass_name,
                                           pass_index, trans_index))

  def DoBinarySearchBadPass(self, pass_index=-1, pass_name=None):
    """Perform single iteration of binary search at pass level

    Args:
      pass_index: Works for transformation level bisection, indicates the limit
        number of pass from pass level bisecting result.
      pass_name: Works for transformation level bisection, indicates
        DebugCounter name of the bad pass from pass level bisecting result.
    Return:
      index: Index of problematic pass/transformation.
      pass_name: Works for pass level bisection, returns DebugCounter name for
        bad pass.
    """
    # If in resume mode don't reset search_cycles
    if not self.resumed:
      self.search_cycles = 0
    else:
      self.resumed = False

    terminated = False
    index = 0
    while self.search_cycles < self.iterations and not terminated:
      self.SaveState()
      self.OutputIterationProgressBadPass()

      self.search_cycles += 1
      current = self.binary_search.GetNext()

      if self.mode == 'pass':
        index, pass_name = self.BuildWithPassLimit(current)
      else:
        self.BuildWithTransformLimit(current, pass_name, pass_index)
        index = current

      # TODO: Newly generated object should not directly replace original
      # one, need to put it somewhere and symbol link original one to it.
      # Will update cmd_script to do it.

      status = self.TestSetupScript()
      assert status == 0, 'Test setup should succeed.'
      status = self.TestScript()
      terminated = self.binary_search.SetStatus(status)

      if terminated:
        self.l.LogOutput('Terminated!', print_to_console=self.verbose)
    if not terminated:
      self.l.LogOutput('Ran out of iterations searching...')
    self.l.LogOutput(str(self), print_to_console=self.verbose)
    return index, pass_name

  def PopulateItemsUsingCommand(self, command):
    """Update all_items and binary search logic from executable.

    This method is mainly required for enumerating the initial list of items
    from the get_initial_items script.

    Args:
      command: path to executable that will enumerate items.
    """
    ce = command_executer.GetCommandExecuter()
    _, out, _ = ce.RunCommandWExceptionCleanup(
        command, return_output=True, print_to_console=self.verbose)
    all_items = out.split()
    self.PopulateItemsUsingList(all_items)

  def PopulateItemsUsingList(self, all_items):
    """Update all_items and binary searching logic from list.

    Args:
      all_items: new list of all_items
    """
    self.all_items = all_items
    self.binary_search = binary_search_perforce.BinarySearcher(
        logger_to_set=self.l)
    self.binary_search.SetSortedList(self.all_items)

  def SaveState(self):
    """Save state to STATE_FILE.

    SaveState will create a new unique, hidden state file to hold data from
    object. Then atomically overwrite the STATE_FILE symlink to point to the
    new data.

    Raises:
      Error if STATE_FILE already exists but is not a symlink.
    """
    ce, l = self.ce, self.l
    self.ce, self.l, self.binary_search.logger = None, None, None
    old_state = None

    _, path = tempfile.mkstemp(prefix=HIDDEN_STATE_FILE, dir='.')
    with open(path, 'wb') as f:
      pickle.dump(self, f)

    if os.path.exists(STATE_FILE):
      if os.path.islink(STATE_FILE):
        old_state = os.readlink(STATE_FILE)
      else:
        raise Error(('%s already exists and is not a symlink!\n'
                     'State file saved to %s' % (STATE_FILE, path)))

    # Create new link and atomically overwrite old link
    temp_link = '%s.link' % HIDDEN_STATE_FILE
    os.symlink(path, temp_link)
    os.rename(temp_link, STATE_FILE)

    if old_state:
      os.remove(old_state)

    self.ce, self.l, self.binary_search.logger = ce, l, l

  @classmethod
  def LoadState(cls):
    """Create BinarySearchState object from STATE_FILE."""
    if not os.path.isfile(STATE_FILE):
      return None
    try:
      bss = pickle.load(file(STATE_FILE))
      bss.l = logger.GetLogger()
      bss.ce = command_executer.GetCommandExecuter()
      bss.binary_search.logger = bss.l
      bss.start_time = time.time()

      # Set resumed to be True so we can enter DoBinarySearch without the method
      # resetting our current search_cycles to 0.
      bss.resumed = True

      # Set currently_good_items and currently_bad_items to empty so that the
      # first iteration after resuming will always be non-incremental. This is
      # just in case the environment changes, the user makes manual changes, or
      # a previous switch_script corrupted the environment.
      bss.currently_good_items = set([])
      bss.currently_bad_items = set([])

      binary_search_perforce.verbose = bss.verbose
      return bss
    except StandardError:
      return None

  def RemoveState(self):
    """Remove STATE_FILE and its symlinked data from file system."""
    if os.path.exists(STATE_FILE):
      if os.path.islink(STATE_FILE):
        real_file = os.readlink(STATE_FILE)
        os.remove(real_file)
        os.remove(STATE_FILE)

  def GetNextItems(self):
    """Get next items for binary search based on result of the last test run."""
    border_item = self.binary_search.GetNext()
    index = self.all_items.index(border_item)

    next_bad_items = self.all_items[:index + 1]
    next_good_items = self.all_items[index + 1:] + list(self.known_good)

    return [next_bad_items, next_good_items]

  def ElapsedTimeString(self):
    """Return h m s format of elapsed time since execution has started."""
    diff = int(time.time() - self.start_time)
    seconds = diff % 60
    minutes = (diff / 60) % 60
    hours = diff / (60 * 60)

    seconds = str(seconds).rjust(2)
    minutes = str(minutes).rjust(2)
    hours = str(hours).rjust(2)

    return '%sh %sm %ss' % (hours, minutes, seconds)

  def _OutputProgress(self, progress_text):
    """Output current progress of binary search to console and logs.

    Args:
      progress_text: The progress to display to the user.
    """
    progress = ('\n***** PROGRESS (elapsed time: %s) *****\n'
                '%s'
                '************************************************')
    progress = progress % (self.ElapsedTimeString(), progress_text)
    self.l.LogOutput(progress)

  def OutputIterationProgressBadItem(self):
    out = ('Search %d of estimated %d.\n'
           'Prune %d of max %d.\n'
           'Current bad items found:\n'
           '%s\n')
    out = out % (self.search_cycles + 1,
                 math.ceil(math.log(len(self.all_items), 2)), self.prune_cycles
                 + 1, self.prune_iterations, ', '.join(self.found_items))
    self._OutputProgress(out)

  def OutputIterationProgressBadPass(self):
    out = ('Search %d of estimated %d.\n' 'Current limit: %s\n')
    out = out % (self.search_cycles + 1,
                 math.ceil(math.log(self.binary_search.total, 2)),
                 self.binary_search.current)
    self._OutputProgress(out)

  def __str__(self):
    ret = ''
    ret += 'all: %s\n' % str(self.all_items)
    ret += 'currently_good: %s\n' % str(self.currently_good_items)
    ret += 'currently_bad: %s\n' % str(self.currently_bad_items)
    ret += str(self.binary_search)
    return ret


class MockBinarySearchState(BinarySearchState):
  """Mock class for BinarySearchState."""

  def __init__(self, **kwargs):
    # Initialize all arguments to None
    default_kwargs = {
        'get_initial_items': 'echo "1"',
        'switch_to_good': None,
        'switch_to_bad': None,
        'test_setup_script': None,
        'test_script': None,
        'incremental': True,
        'prune': False,
        'pass_bisect': None,
        'ir_diff': False,
        'iterations': 50,
        'prune_iterations': 100,
        'verify': True,
        'file_args': False,
        'verbose': False
    }
    default_kwargs.update(kwargs)
    super(MockBinarySearchState, self).__init__(**default_kwargs)


def _CanonicalizeScript(script_name):
  """Return canonical path to script.

  Args:
    script_name: Relative or absolute path to script

  Returns:
    Canonicalized script path
  """
  script_name = os.path.expanduser(script_name)
  if not script_name.startswith('/'):
    return os.path.join('.', script_name)


def Run(get_initial_items,
        switch_to_good,
        switch_to_bad,
        test_script,
        test_setup_script=None,
        iterations=50,
        prune=False,
        pass_bisect=None,
        ir_diff=False,
        noincremental=False,
        file_args=False,
        verify=True,
        prune_iterations=100,
        verbose=False,
        resume=False):
  """Run binary search tool.

  Equivalent to running through terminal.

  Args:
    get_initial_items: Script to enumerate all items being binary searched
    switch_to_good: Script that will take items as input and switch them to good
      set
    switch_to_bad: Script that will take items as input and switch them to bad
      set
    test_script: Script that will determine if the current combination of good
      and bad items make a "good" or "bad" result.
    test_setup_script: Script to do necessary setup (building, compilation,
      etc.) for test_script.
    iterations: How many binary search iterations to run before exiting.
    prune: If False the binary search tool will stop when the first bad item is
      found. Otherwise then binary search tool will continue searching until all
      bad items are found (or prune_iterations is reached).
    pass_bisect: Script that takes single bad item from POPULATE_BAD and returns
      the compiler command used to generate the bad item. This will turn on
      pass/ transformation level bisection for the bad item. Requires that
      'prune' be set to False, and needs support of `-opt-bisect-limit`(pass)
      and `-print-debug-counter`(transformation) from LLVM.
    ir_diff: Whether to print IR differences before and after bad
      pass/transformation to verbose output. Defaults to False, only works when
      pass_bisect is enabled.
    noincremental: Whether to send "diffs" of good/bad items to switch scripts.
    file_args: If True then arguments to switch scripts will be a file name
      containing a newline separated list of the items to switch.
    verify: If True, run tests to ensure initial good/bad sets actually produce
      a good/bad result.
    prune_iterations: Max number of bad items to search for.
    verbose: If True will print extra debug information to user.
    resume: If True will resume using STATE_FILE.

  Returns:
    0 for success, error otherwise
  """
  # Notice that all the argument checks are in the Run() function rather than
  # in the Main() function. It is not common to do so but some wrappers are
  # going to call Run() directly and bypass checks in Main() function.
  if resume:
    logger.GetLogger().LogOutput('Resuming from %s' % STATE_FILE)
    bss = BinarySearchState.LoadState()
    if not bss:
      logger.GetLogger().LogOutput(
          '%s is not a valid binary_search_tool state file, cannot resume!' %
          STATE_FILE)
      return 1
    logger.GetLogger().LogOutput('Note: resuming from previous state, '
                                 'ignoring given options and loading saved '
                                 'options instead.')
  else:
    if not (get_initial_items and switch_to_good and switch_to_bad and
            test_script):
      logger.GetLogger().LogOutput('The following options are required: '
                                   '[-i, -g, -b, -t] | [-r]')
      return 1
    if pass_bisect and prune:
      logger.GetLogger().LogOutput('"--pass_bisect" only works when '
                                   '"--prune" is set to be False.')
      return 1
    if not pass_bisect and ir_diff:
      logger.GetLogger().LogOutput('"--ir_diff" only works when '
                                   '"--pass_bisect" is enabled.')

    switch_to_good = _CanonicalizeScript(switch_to_good)
    switch_to_bad = _CanonicalizeScript(switch_to_bad)
    if test_setup_script:
      test_setup_script = _CanonicalizeScript(test_setup_script)
    if pass_bisect:
      pass_bisect = _CanonicalizeScript(pass_bisect)
    test_script = _CanonicalizeScript(test_script)
    get_initial_items = _CanonicalizeScript(get_initial_items)
    incremental = not noincremental

    binary_search_perforce.verbose = verbose

    bss = BinarySearchState(get_initial_items, switch_to_good, switch_to_bad,
                            test_setup_script, test_script, incremental, prune,
                            pass_bisect, ir_diff, iterations, prune_iterations,
                            verify, file_args, verbose)
    bss.DoVerify()

  try:
    bss.DoSearchBadItems()
    if pass_bisect:
      bss.DoSearchBadPass()
    bss.RemoveState()
    logger.GetLogger().LogOutput(
        'Total execution time: %s' % bss.ElapsedTimeString())
  except Error as e:
    logger.GetLogger().LogError(e)
    return 1

  return 0


def Main(argv):
  """The main function."""
  # Common initializations

  parser = argparse.ArgumentParser()
  common.BuildArgParser(parser)
  logger.GetLogger().LogOutput(' '.join(argv))
  options = parser.parse_args(argv)

  # Get dictionary of all options
  args = vars(options)
  return Run(**args)


if __name__ == '__main__':
  sys.exit(Main(sys.argv[1:]))
