#!/usr/bin/python2
"""The binary search wrapper."""

from __future__ import print_function

import argparse
import math
import os
import pickle
import sys
import tempfile

# Programtically adding utils python path to PYTHONPATH
if os.path.isabs(sys.argv[0]):
  utils_pythonpath = os.path.abspath('{0}/..'.format(os.path.dirname(sys.argv[
      0])))
else:
  wdir = os.getcwd()
  utils_pythonpath = os.path.abspath('{0}/{1}/..'.format(wdir, os.path.dirname(
      sys.argv[0])))
sys.path.append(utils_pythonpath)
# Now we do import from utils
from utils import command_executer
from utils import logger

import binary_search_perforce

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


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

  def __init__(self, get_initial_items, switch_to_good, switch_to_bad,
               install_script, test_script, incremental, prune, iterations,
               prune_iterations, verify_level, file_args, verbose):
    self.get_initial_items = get_initial_items
    self.switch_to_good = switch_to_good
    self.switch_to_bad = switch_to_bad
    self.install_script = install_script
    self.test_script = test_script
    self.incremental = incremental
    self.prune = prune
    self.iterations = iterations
    self.prune_iterations = prune_iterations
    self.verify_level = verify_level
    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.PopulateItemsUsingCommand(self.get_initial_items)
    self.currently_good_items = set([])
    self.currently_bad_items = set([])
    self.found_items = set([])

  def SwitchToGood(self, item_list):
    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):
    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):
    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))
      ret, _, _ = self.ce.RunCommandWExceptionCleanup(
          command, print_to_console=self.verbose)
    assert ret == 0, 'Switch script %s returned %d' % (switch_script, ret)

  def TestScript(self):
    command = self.test_script
    ret, _, _ = self.ce.RunCommandWExceptionCleanup(command)
    return ret

  def InstallScript(self):
    if not self.install_script:
      return 0

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

  def DoVerify(self):
    self.l.LogOutput('VERIFICATION')
    self.l.LogOutput('Beginning %d tests to verify good/bad sets\n')
    for _ in range(int(self.verify_level)):
      self.l.LogOutput('Resetting all items to good to verify.')
      self.SwitchToGood(self.all_items)
      status = self.InstallScript()
      assert status == 0, 'When reset_to_good, install should succeed.'
      status = self.TestScript()
      assert status == 0, 'When reset_to_good, status should be 0.'

      self.l.LogOutput('Resetting all items to bad to verify.')
      self.SwitchToBad(self.all_items)
      status = self.InstallScript()
      assert status == 0, 'When reset_to_bad, install should succeed.'
      status = self.TestScript()
      assert status == 1, 'When reset_to_bad, status should be 1.'

  def DoSearch(self):
    while (True and
           len(self.all_items) > 1 and
           self.prune_cycles < self.prune_iterations):
      terminated = self.DoBinarySearch()
      self.prune_cycles += 1
      if not terminated:
        break
      if not self.prune:
        self.l.LogOutput('Not continuning further, --prune is not set')
        break
      # Prune is set.
      prune_index = self.binary_search.current

      # 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. '
                          'Done searching.' % self.all_items[prune_index]))
        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])

      if prune_index:
        new_all_items = new_all_items[prune_index - 1:]

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

      # FIXME: Do we need to Convert the currently good items to bad
      self.PopulateItemsUsingList(new_all_items)

  def DoBinarySearch(self):
    # 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.OutputProgress()
      self.search_cycles += 1
      [bad_items, good_items] = self.GetNextItems()

      # TODO: bad_items should come first.
      self.SwitchToGood(good_items)
      self.SwitchToBad(bad_items)
      status = self.InstallScript()
      if status == 0:
        status = self.TestScript()
      else:
        # Install script failed, treat as skipped item
        status = 2
      terminated = self.binary_search.SetStatus(status)

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

  def PopulateItemsUsingCommand(self, command):
    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):
    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):
    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):
    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.resumed = True
      binary_search_perforce.verbose = bss.verbose
      return bss
    except Exception:
      return None

  def RemoveState(self):
    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):
    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:]

    return [next_bad_items, next_good_items]

  def OutputProgress(self):
    out = ('\n********** PROGRESS **********\n'
           '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,
                 str(self.found_items))

    self.l.LogOutput(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,
        'install_script': None,
        'test_script': None,
        'incremental': None,
        'prune': None,
        'iterations': None,
        'prune_iterations': None,
        'verify_level': None,
        'file_args': None,
        'verbose': None
    }
    default_kwargs.update(kwargs)
    super(MockBinarySearchState, self).__init__(**default_kwargs)


def _CanonicalizeScript(script_name):
  script_name = os.path.expanduser(script_name)
  if not script_name.startswith('/'):
    return os.path.join('.', script_name)


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

  parser = argparse.ArgumentParser()
  parser.add_argument('-n',
                      '--iterations',
                      dest='iterations',
                      help='Number of iterations to try in the search.',
                      default=50)
  parser.add_argument('-i',
                      '--get_initial_items',
                      dest='get_initial_items',
                      help=('Script to run to get the initial objects. '
                            'If your script requires user input '
                            'the --verbose option must be used'))
  parser.add_argument('-g',
                      '--switch_to_good',
                      dest='switch_to_good',
                      help=('Script to run to switch to good. '
                            'If your switch script requires user input '
                            'the --verbose option must be used'))
  parser.add_argument('-b',
                      '--switch_to_bad',
                      dest='switch_to_bad',
                      help=('Script to run to switch to bad. '
                            'If your switch script requires user input '
                            'the --verbose option must be used'))
  parser.add_argument('-I',
                      '--install_script',
                      dest='install_script',
                      default=None,
                      help=('Optional script to perform building, flashing, '
                            'and other setup before the test script runs.'))
  parser.add_argument('-t',
                      '--test_script',
                      dest='test_script',
                      help=('Script to run to test the '
                            'output after packages are built.'))
  parser.add_argument('-p',
                      '--prune',
                      dest='prune',
                      action='store_true',
                      default=False,
                      help=('Script to run to test the output after '
                            'packages are built.'))
  parser.add_argument('-c',
                      '--noincremental',
                      dest='noincremental',
                      action='store_true',
                      default=False,
                      help='Do not propagate good/bad changes incrementally.')
  parser.add_argument('-f',
                      '--file_args',
                      dest='file_args',
                      action='store_true',
                      default=False,
                      help='Use a file to pass arguments to scripts.')
  parser.add_argument('-v',
                      '--verify_level',
                      dest='verify_level',
                      default=1,
                      help=('Check binary search assumptions N times '
                            'before starting.'))
  parser.add_argument('-N',
                      '--prune_iterations',
                      dest='prune_iterations',
                      help='Number of prune iterations to try in the search.',
                      default=100)
  parser.add_argument('-V',
                      '--verbose',
                      dest='verbose',
                      action='store_true',
                      help='Print full output to console.')
  parser.add_argument('-r',
                      '--resume',
                      dest='resume',
                      action='store_true',
                      help=('Resume bisection tool execution from state file.'
                            'Useful if the last bisection was terminated '
                            'before it could properly finish.'))

  logger.GetLogger().LogOutput(' '.join(argv))
  options = parser.parse_args(argv)

  if not (options.get_initial_items and options.switch_to_good and
          options.switch_to_bad and options.test_script) and not options.resume:
    parser.print_help()
    return 1

  if options.resume:
    logger.GetLogger().LogOutput('Resuming from %s' % STATE_FILE)
    if len(argv) > 1:
      logger.GetLogger().LogOutput(('Note: resuming from previous state, '
                                    'ignoring given options and loading saved '
                                    'options instead.'))
    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
  else:
    iterations = int(options.iterations)
    switch_to_good = _CanonicalizeScript(options.switch_to_good)
    switch_to_bad = _CanonicalizeScript(options.switch_to_bad)
    install_script = options.install_script
    if install_script:
      install_script = _CanonicalizeScript(options.install_script)
    test_script = _CanonicalizeScript(options.test_script)
    get_initial_items = _CanonicalizeScript(options.get_initial_items)
    prune = options.prune
    prune_iterations = options.prune_iterations
    verify_level = options.verify_level
    file_args = options.file_args
    verbose = options.verbose
    binary_search_perforce.verbose = verbose

    if options.noincremental:
      incremental = False
    else:
      incremental = True

    bss = BinarySearchState(get_initial_items, switch_to_good, switch_to_bad,
                            install_script, test_script, incremental, prune,
                            iterations, prune_iterations, verify_level,
                            file_args, verbose)
    bss.DoVerify()

  try:
    bss.DoSearch()
    bss.RemoveState()
  except Error as e:
    logger.GetLogger().LogError(e)
    return 1

  return 0


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