#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


"""Generic retry wrapper for Git operations. 

This is largely DEPRECATED in favor of the Infra Git wrapper:
https://chromium.googlesource.com/infra/infra/+/master/go/src/infra/tools/git
"""

import logging
import optparse
import os
import subprocess
import sys
import threading
import time

from git_common import GIT_EXE, GIT_TRANSIENT_ERRORS_RE


class TeeThread(threading.Thread):

  def __init__(self, fd, out_fd, name):
    super(TeeThread, self).__init__(name='git-retry.tee.%s' % (name,))
    self.data = None
    self.fd = fd
    self.out_fd = out_fd

  def run(self):
    chunks = []
    for line in self.fd:
      chunks.append(line)
      self.out_fd.write(line)
    self.data = ''.join(chunks)


class GitRetry(object):

  logger = logging.getLogger('git-retry')
  DEFAULT_DELAY_SECS = 3.0
  DEFAULT_RETRY_COUNT = 5

  def __init__(self, retry_count=None, delay=None, delay_factor=None):
    self.retry_count = retry_count or self.DEFAULT_RETRY_COUNT
    self.delay = max(delay, 0) if delay else 0
    self.delay_factor = max(delay_factor, 0) if delay_factor else 0

  def shouldRetry(self, stderr):
    m = GIT_TRANSIENT_ERRORS_RE.search(stderr)
    if not m:
      return False
    self.logger.info("Encountered known transient error: [%s]",
                     stderr[m.start(): m.end()])
    return True

  @staticmethod
  def execute(*args):
    args = (GIT_EXE,) + args
    proc = subprocess.Popen(
        args,
        stderr=subprocess.PIPE,
    )
    stderr_tee = TeeThread(proc.stderr, sys.stderr, 'stderr')

    # Start our process. Collect/tee 'stdout' and 'stderr'.
    stderr_tee.start()
    try:
      proc.wait()
    except KeyboardInterrupt:
      proc.kill()
      raise
    finally:
      stderr_tee.join()
    return proc.returncode, None, stderr_tee.data

  def computeDelay(self, iteration):
    """Returns: the delay (in seconds) for a given iteration

    The first iteration has a delay of '0'.

    Args:
      iteration: (int) The iteration index (starting with zero as the first
          iteration)
    """
    if (not self.delay) or (iteration == 0):
      return 0
    if self.delay_factor == 0:
      # Linear delay
      return iteration * self.delay
    # Exponential delay
    return (self.delay_factor ** (iteration - 1)) * self.delay

  def __call__(self, *args):
    returncode = 0
    for i in xrange(self.retry_count):
      # If the previous run failed and a delay is configured, delay before the
      # next run.
      delay = self.computeDelay(i)
      if delay > 0:
        self.logger.info("Delaying for [%s second(s)] until next retry", delay)
        time.sleep(delay)

      self.logger.debug("Executing subprocess (%d/%d) with arguments: %s",
                        (i+1), self.retry_count, args)
      returncode, _, stderr = self.execute(*args)

      self.logger.debug("Process terminated with return code: %d", returncode)
      if returncode == 0:
        break

      if not self.shouldRetry(stderr):
        self.logger.error("Process failure was not known to be transient; "
                          "terminating with return code %d", returncode)
        break
    return returncode


def main(args):
  # If we're using the Infra Git wrapper, do nothing here.
  # https://chromium.googlesource.com/infra/infra/+/master/go/src/infra/tools/git
  if 'INFRA_GIT_WRAPPER' in os.environ:
    # Remove Git's execution path from PATH so that our call-through re-invokes
    # the Git wrapper.
    # See crbug.com/721450
    env = os.environ.copy()
    git_exec = subprocess.check_output([GIT_EXE, '--exec-path']).strip()
    env['PATH'] = os.pathsep.join([
      elem for elem in env.get('PATH', '').split(os.pathsep)
      if elem != git_exec])
    return subprocess.call([GIT_EXE] + args, env=env)

  parser = optparse.OptionParser()
  parser.disable_interspersed_args()
  parser.add_option('-v', '--verbose',
                    action='count', default=0,
                    help="Increase verbosity; can be specified multiple times")
  parser.add_option('-c', '--retry-count', metavar='COUNT',
                    type=int, default=GitRetry.DEFAULT_RETRY_COUNT,
                    help="Number of times to retry (default=%default)")
  parser.add_option('-d', '--delay', metavar='SECONDS',
                    type=float, default=GitRetry.DEFAULT_DELAY_SECS,
                    help="Specifies the amount of time (in seconds) to wait "
                         "between successive retries (default=%default). This "
                         "can be zero.")
  parser.add_option('-D', '--delay-factor', metavar='FACTOR',
                    type=int, default=2,
                    help="The exponential factor to apply to delays in between "
                         "successive failures (default=%default). If this is "
                         "zero, delays will increase linearly. Set this to "
                         "one to have a constant (non-increasing) delay.")

  opts, args = parser.parse_args(args)

  # Configure logging verbosity
  if opts.verbose == 0:
    logging.getLogger().setLevel(logging.WARNING)
  elif opts.verbose == 1:
    logging.getLogger().setLevel(logging.INFO)
  else:
    logging.getLogger().setLevel(logging.DEBUG)

  # Execute retries
  retry = GitRetry(
      retry_count=opts.retry_count,
      delay=opts.delay,
      delay_factor=opts.delay_factor,
  )
  return retry(*args)


if __name__ == '__main__':
  logging.basicConfig()
  logging.getLogger().setLevel(logging.WARNING)
  try:
    sys.exit(main(sys.argv[2:]))
  except KeyboardInterrupt:
    sys.stderr.write('interrupted\n')
    sys.exit(1)
