#!/usr/bin/env python
#
# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.


import datetime
import errno
import os
import shutil
import sys
import subprocess
import tempfile
import time
import uuid


GCLIENT = 'gclient.bat' if sys.platform == 'win32' else 'gclient'
WHICH = 'where' if sys.platform == 'win32' else 'which'
GIT = subprocess.check_output([WHICH, 'git']).splitlines()[0]

class print_timings(object):
  def __init__(self):
    self._start = None

  def __enter__(self):
    self._start = datetime.datetime.utcnow()
    print 'Task started at %s GMT' % str(self._start)

  def __exit__(self, t, v, tb):
    finish = datetime.datetime.utcnow()
    duration = (finish-self._start).total_seconds()
    print 'Task finished at %s GMT (%f seconds)' % (str(finish), duration)


class tmp_dir(object):
  """Helper class used for creating a temporary directory and working in it."""
  def __init__(self):
    self._orig_dir = None
    self._tmp_dir = None

  def __enter__(self):
    self._orig_dir = os.getcwd()
    self._tmp_dir = tempfile.mkdtemp()
    os.chdir(self._tmp_dir)
    return self

  def __exit__(self, t, v, tb):
    os.chdir(self._orig_dir)
    RemoveDirectory(self._tmp_dir)

  @property
  def name(self):
    return self._tmp_dir


class chdir(object):
  """Helper class used for changing into and out of a directory."""
  def __init__(self, d):
    self._dir = d
    self._orig_dir = None

  def __enter__(self):
    self._orig_dir = os.getcwd()
    os.chdir(self._dir)
    return self

  def __exit__(self, t, v, tb):
    os.chdir(self._orig_dir)


def git_clone(repo_url, dest_dir):
  """Clone the given repo into the given destination directory."""
  subprocess.check_call([GIT, 'clone', repo_url, dest_dir])


class git_branch(object):
  """Check out a temporary git branch.

  On exit, deletes the branch and attempts to restore the original state.
  """
  def __init__(self):
    self._branch = None
    self._orig_branch = None
    self._stashed = False

  def __enter__(self):
    output = subprocess.check_output([GIT, 'stash'])
    self._stashed = 'No local changes' not in output

    # Get the original branch name or commit hash.
    self._orig_branch = subprocess.check_output([
        GIT, 'rev-parse', '--abbrev-ref', 'HEAD']).rstrip()
    if self._orig_branch == 'HEAD':
      self._orig_branch = subprocess.check_output([
          GIT, 'rev-parse', 'HEAD']).rstrip()

    # Check out a new branch, based at updated origin/master.
    subprocess.check_call([GIT, 'fetch', 'origin'])
    self._branch = '_tmp_%s' % uuid.uuid4()
    subprocess.check_call([GIT, 'checkout', '-b', self._branch,
                           '-t', 'origin/master'])
    return self

  def __exit__(self, exc_type, _value, _traceback):
    subprocess.check_call([GIT, 'reset', '--hard', 'HEAD'])
    subprocess.check_call([GIT, 'checkout', self._orig_branch])
    if self._stashed:
      subprocess.check_call([GIT, 'stash', 'pop'])
    subprocess.check_call([GIT, 'branch', '-D', self._branch])


def RemoveDirectory(*path):
  """Recursively removes a directory, even if it's marked read-only.

  This was copied from:
  https://chromium.googlesource.com/chromium/tools/build/+/f3e7ff03613cd59a463b2ccc49773c3813e77404/scripts/common/chromium_utils.py#491

  Remove the directory located at *path, if it exists.

  shutil.rmtree() doesn't work on Windows if any of the files or directories
  are read-only, which svn repositories and some .svn files are.  We need to
  be able to force the files to be writable (i.e., deletable) as we traverse
  the tree.

  Even with all this, Windows still sometimes fails to delete a file, citing
  a permission error (maybe something to do with antivirus scans or disk
  indexing).  The best suggestion any of the user forums had was to wait a
  bit and try again, so we do that too.  It's hand-waving, but sometimes it
  works. :/
  """
  file_path = os.path.join(*path)
  if not os.path.exists(file_path):
    return

  if sys.platform == 'win32':
    # Give up and use cmd.exe's rd command.
    file_path = os.path.normcase(file_path)
    for _ in xrange(3):
      print 'RemoveDirectory running %s' % (' '.join(
          ['cmd.exe', '/c', 'rd', '/q', '/s', file_path]))
      if not subprocess.call(['cmd.exe', '/c', 'rd', '/q', '/s', file_path]):
        break
      print '  Failed'
      time.sleep(3)
    return

  def RemoveWithRetry_non_win(rmfunc, path):
    if os.path.islink(path):
      return os.remove(path)
    else:
      return rmfunc(path)

  remove_with_retry = RemoveWithRetry_non_win

  def RmTreeOnError(function, path, excinfo):
    r"""This works around a problem whereby python 2.x on Windows has no ability
    to check for symbolic links.  os.path.islink always returns False.  But
    shutil.rmtree will fail if invoked on a symbolic link whose target was
    deleted before the link.  E.g., reproduce like this:
    > mkdir test
    > mkdir test\1
    > mklink /D test\current test\1
    > python -c "import chromium_utils; chromium_utils.RemoveDirectory('test')"
    To avoid this issue, we pass this error-handling function to rmtree.  If
    we see the exact sort of failure, we ignore it.  All other failures we re-
    raise.
    """

    exception_type = excinfo[0]
    exception_value = excinfo[1]
    # If shutil.rmtree encounters a symbolic link on Windows, os.listdir will
    # fail with a WindowsError exception with an ENOENT errno (i.e., file not
    # found).  We'll ignore that error.  Note that WindowsError is not defined
    # for non-Windows platforms, so we use OSError (of which it is a subclass)
    # to avoid lint complaints about an undefined global on non-Windows
    # platforms.
    if (function is os.listdir) and issubclass(exception_type, OSError):
      if exception_value.errno == errno.ENOENT:
        # File does not exist, and we're trying to delete, so we can ignore the
        # failure.
        print 'WARNING:  Failed to list %s during rmtree.  Ignoring.\n' % path
      else:
        raise
    else:
      raise

  for root, dirs, files in os.walk(file_path, topdown=False):
    # For POSIX:  making the directory writable guarantees removability.
    # Windows will ignore the non-read-only bits in the chmod value.
    os.chmod(root, 0770)
    for name in files:
      remove_with_retry(os.remove, os.path.join(root, name))
    for name in dirs:
      remove_with_retry(lambda p: shutil.rmtree(p, onerror=RmTreeOnError),
                        os.path.join(root, name))

  remove_with_retry(os.rmdir, file_path)
