# Copyright (c) 2012 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.

"""A subclass of commands.SVN that allows more flexible error recovery.

This code is only used on the slave but it is living in common/ because it is
directly imported from buildbot/slave/bot.py."""

import os
import re

from twisted.python import log
from twisted.internet import defer

from common import chromium_utils

from buildslave.commands.base import SourceBaseCommand
from buildslave.commands.registry import commandRegistry
from buildslave import runprocess


PROJECTS_LOOKING_FOR = {
  os.path.join('src'): 'got_chromium_revision',
  os.path.join('src', 'native_client'): 'got_nacl_revision',
  os.path.join('src', 'tools', 'swarming_client'):
    'got_swarming_client_revision',
  os.path.join('src', 'v8'): 'got_v8_revision',
  os.path.join('src', 'third_party', 'WebKit'): 'got_webkit_revision',
  os.path.join('src', 'third_party', 'webrtc'): 'got_webrtc_revision',
}


# Local errors.
class InvalidPath(Exception): pass


def FixDiffLineEnding(diff):
  """Fix patch files generated on windows and applied on mac/linux.

  For files with svn:eol-style=crlf, svn diff puts CRLF in the diff hunk header.
  patch on linux and mac barfs on those hunks. As usual, blame svn."""
  output = ''
  for line in diff.splitlines(True):
    if (line.startswith('---') or line.startswith('+++') or
        line.startswith('@@ ') or line.startswith('\\ No')):
      # Strip any existing CRLF on the header lines
      output += line.rstrip() + '\n'
    else:
      output += line
  return output


def untangle(stdout_lines):
  """Sort the lines of stdout by the job number prefix."""
  out = []
  tasks = {}
  UNTANGLE_RE = re.compile(r'^(\d+)>(.*)$')
  for line in stdout_lines:
    m = UNTANGLE_RE.match(line)
    if not m:
      if line:  # skip empty lines
        # Output untangled lines so far.
        for key in sorted(tasks.iterkeys()):
          out.extend(tasks[key])
        tasks = {}
        out.append(line)
    else:
      if m.group(2):  # skip empty lines
        tasks.setdefault(int(m.group(1)), []).append(m.group(2))
  for key in sorted(tasks.iterkeys()):
    out.extend(tasks[key])
  return out


def extract_revisions(output):
  """Extracts revision numbers for all the dependencies checked out.

  svn checkout operations finish with 'Checked out revision 16657.'
  svn update operations finish the line 'At revision 16654.' when there is no
  change. They finish with 'Updated to revision 16655.' otherwise.

  The first project checked out gets to be set to got_revision property. This is
  important since this class is not only used for chromium, it's also used for
  other projects.
  """
  SCM_RE = {
    'git': r'^Checked out revision ([0-9a-fA-F]{40})$',
    'svn': r'^(?:Checked out|At|Updated to) revision ([0-9]+)\.',
  }
  GCLIENT_CMD = re.compile(r'^________ running \'(.+?)\' in \'(.+?)\'$')
  GCLIENT_AT_REV = re.compile(r'_____ (.+?) at (\d+|[0-9a-fA-F]{40})$')

  untangled_stdout = untangle(output.splitlines(False))
  # We only care about the last sync which starts with "solutions=[...".
  # Look backwards to find the last gclient sync call. It's parsing the whole
  # sync step in one pass here, which could include gclient revert and two
  # gclient sync calls. Only the last gclient sync call should be parsed.
  for i, line in enumerate(reversed(untangled_stdout)):
    if line.startswith('solutions=['):
      # Only keep from "solutions" line to end.
      untangled_stdout = untangled_stdout[-i-1:]
      break

  revisions_found = {}
  current_scm = None
  current_project = None
  reldir = None
  for line in untangled_stdout:
    match = GCLIENT_AT_REV.match(line)
    if match:
      current_project = None
      current_scm = None
      log.msg('gclient: %s == %s' % match.groups())
      project = PROJECTS_LOOKING_FOR.get(match.group(1))
      if not revisions_found:
        # Set it to got_revision, independent if it's a chromium-specific
        # thing.
        revisions_found['got_revision'] = match.group(2)
      if project:
        revisions_found[project] = match.group(2)
      continue

    if current_scm:
      # Look for revision.
      match = re.match(SCM_RE[current_scm], line)
      if match:
        # Override any previous value, since update can happen multiple times.
        log.msg(
            'scm: %s (%s) == %s' % (reldir, current_project, match.group(1)))
        if not revisions_found:
          revisions_found['got_revision'] = match.group(1)
        if current_project:
          revisions_found[current_project] = match.group(1)
        current_project = None
        current_scm = None
        continue

    match = GCLIENT_CMD.match(line)
    if match:
      command, directory = match.groups()
      parts = command.split(' ')
      directory = directory.rstrip(os.path.sep) + os.path.sep
      if parts[0] in SCM_RE:
        current_scm = parts[0]
        for part in parts:
          # This code assumes absolute paths, which are easy to find in the
          # argument list.
          if part.startswith(directory):
            reldir = part[len(directory):]
            if reldir:
              current_project = PROJECTS_LOOKING_FOR.get(reldir)
              break

  return revisions_found


def _RenameDirectoryCommand(src_dir, dest_dir):
  """Returns a command list to rename a directory (or file) using Python."""
  # Use / instead of \ in paths to avoid issues with escaping.
  return ['python', '-c',
          'import os; '
          'os.rename("%s", "%s")' %
              (src_dir.replace('\\', '/'), dest_dir.replace('\\', '/'))]


def _RemoveFileCommand(filename):
  """Returns a command list to remove a directory (or file) using Python."""
  # Use / instead of \ in paths to avoid issues with escaping.
  return ['python', '-c',
          'from common import chromium_utils; '
          'chromium_utils.RemoveFile("%s")' % filename.replace('\\', '/')]


class GClient(SourceBaseCommand):
  """Source class that handles gclient checkouts.

  Buildbot 8.3 changed from commands.SourceBase to SourceBaseCommand,
  so this inherits from a variable set to the right item.  Docs below
  assume 8.3 (and this hack should be removed when pre-8.3 clients are
  turned down.

  In addition to the arguments handled by SourceBaseCommand, this command
  reads the following keys:

  ['gclient_spec']:
    if not None, then this specifies the text of the .gclient file to use.
    this overrides any 'svnurl' argument that may also be specified.

  ['rm_timeout']:
    if not None, a different timeout used only for the 'rm -rf' operation in
    doClobber.  Otherwise the svn timeout will be used for that operation too.

  ['svnurl']:
    if not None, then this specifies the svn url to pass to 'gclient config'
    to create a .gclient file.

  ['branch']:
    if not None, then this specifies the module name to pass to 'gclient sync'
    in --revision argument.

  ['project']:
    if not None, then this specifies the module name to pass to 'gclient sync'
    in --revision argument. This value overloads 'branch', and is mostly useful
    for git checkouts. See also 'no_gclient_branch'.

  ['env']:
    Augment os.environ.

  ['no_gclient_branch']:
    If --revision is specified, don't prepend it with <branch>@.  This is
    necessary for git, where the solution name is 'src' and the branch name
    is 'master'. Use the project attribute if there are several solution in
    the .gclient file.

  ['no_gclient_revision']:
    Do not specify the --revision argument to gclient at all.
  """

  # pylint complains that __init__ in GClient's parent isn't called.  This is
  # because it doesn't realize we call it through GetParentClass().  Disable
  # that warning next.
  # pylint: disable=W0231

  header = 'gclient'

  def __init__(self, *args, **kwargs):
    # TODO(maruel): Mainly to keep pylint happy, remove once buildbot fixed
    # their style.
    self.branch = None
    self.srcdir = None
    self.revision = None
    self.env = None
    self.sourcedatafile = None
    self.patch = None
    self.command = None
    self.vcexe = None
    self.svnurl = None
    self.sudo_for_remove = None
    self.gclient_spec = None
    self.gclient_deps = None
    self.rm_timeout = None
    self.gclient_nohooks = False
    self.was_patched = False
    self.no_gclient_branch = False
    self.no_gclient_revision = False
    self.delete_unversioned_trees_when_updating = True
    self.gclient_jobs = None
    self.project = None
    # TODO(maruel): Remove once buildbot 0.8.4p1 conversion is complete.
    self.sourcedata = None
    self.do_nothing = None
    chromium_utils.GetParentClass(GClient).__init__(self, *args, **kwargs)

  def setup(self, args):
    """Our implementation of command.Commands.setup() method.
    The method will get all the arguments that are passed to remote command
    and is invoked before start() method (that will in turn call doVCUpdate()).
    """
    SourceBaseCommand.setup(self, args)
    self.vcexe = self.getCommand('gclient')
    self.svnurl = args['svnurl']
    self.branch = args.get('branch')
    self.revision = args.get('revision')
    self.patch = args.get('patch')
    self.sudo_for_remove = args.get('sudo_for_remove')
    self.gclient_spec = args['gclient_spec']
    self.gclient_deps = args.get('gclient_deps')
    self.sourcedata = '%s\n' % self.svnurl
    self.rm_timeout = args.get('rm_timeout', self.timeout)
    self.env = args.get('env')
    self.gclient_nohooks = args.get('gclient_nohooks', False)
    self.env['CHROMIUM_GYP_SYNTAX_CHECK'] = '1'
    self.no_gclient_branch = args.get('no_gclient_branch')
    self.no_gclient_revision = args.get('no_gclient_revision', False)
    self.gclient_jobs = args.get('gclient_jobs')
    self.project = args.get('project', None)

  def start(self):
    """Start the update process.

    start() is cut-and-paste from the base class, the block calling
    self.sourcedirIsPatched() and the revert support is the only functional
    difference from base."""
    self.sendStatus({'header': "starting " + self.header + "\n"})
    self.command = None

    # self.srcdir is where the VC system should put the sources
    if self.mode == "copy":
      self.srcdir = "source" # hardwired directory name, sorry
    else:
      self.srcdir = self.workdir
    self.sourcedatafile = os.path.join(self.builder.basedir,
                                       self.srcdir,
                                       ".buildbot-sourcedata")
    self.do_nothing = os.path.isfile(os.path.join(self.builder.basedir,
                                                  self.srcdir,
                                                  'update.flag'))

    d = defer.succeed(0)

    if self.do_nothing:
      # If bot update is run, we don't need to run the traditional update step.
      msg = 'update.flag file found: bot_update has run and checkout is \n'
      msg += 'already in a consistent state.\n'
      msg += 'No actions will be performed in this step.'
      self.sendStatus({'header': msg})
      d.addCallback(self._sendRC)
      return d

    # Do we need to clobber anything?
    if self.mode in ("copy", "clobber", "export"):
      d.addCallback(self.doClobber, self.workdir)
    if not (self.sourcedirIsUpdateable() and self.sourcedataMatches()):
      # the directory cannot be updated, so we have to clobber it.
      # Perhaps the master just changed modes from 'export' to
      # 'update'.
      d.addCallback(self.doClobber, self.srcdir)
    elif self.sourcedirIsPatched():
      # The directory is patched. Revert the sources.
      d.addCallback(self.doRevert)
      self.was_patched = True

    d.addCallback(self.doVC)

    if self.mode == "copy":
      d.addCallback(self.doCopy)
    if self.patch:
      d.addCallback(self.doPatch)

    # Only after the patch call the actual code to get the revision numbers.
    d.addCallback(self._handleGotRevision)

    if (self.patch or self.was_patched) and not self.gclient_nohooks:
      # Always run doRunHooks if there *is* or there *was* a patch because
      # revert is run with --nohooks and `gclient sync` will not regenerate the
      # output files if the input files weren't updated..
      d.addCallback(self.doRunHooks)
    d.addCallbacks(self._sendRC, self._checkAbandoned)
    return d

  def sourcedirIsPatched(self):
    return os.path.exists(os.path.join(self.builder.basedir,
                                       self.srcdir, '.buildbot-patched'))

  def sourcedirIsUpdateable(self):
    # Patched directories are updatable.
    return os.path.exists(os.path.join(self.builder.basedir,
                                       self.srcdir, '.gclient'))

  # TODO(pamg): consolidate these with the copies above.
  def _RemoveDirectoryCommand(self, rm_dir):
    """Returns a command list to delete a directory using Python."""
    # Use / instead of \ in paths to avoid issues with escaping.
    cmd = ['python', '-c',
           'from common import chromium_utils; '
           'chromium_utils.RemoveDirectory("%s")' % rm_dir.replace('\\', '/')]
    if self.sudo_for_remove:
      cmd = ['sudo'] + cmd
    return cmd

  def doGclientUpdate(self):
    """Sync the client
    """
    dirname = os.path.join(self.builder.basedir, self.srcdir)
    command = [chromium_utils.GetGClientCommand(),
               'sync', '--verbose', '--reset', '--manually_grab_svn_rev',
               '--force', '--with_branch_heads']
    if self.delete_unversioned_trees_when_updating:
      command.append('--delete_unversioned_trees')
    if self.gclient_jobs:
      command.append('-j%d' % self.gclient_jobs)
    # Don't run hooks if it was patched or there is a patch since runhooks will
    # be run after.
    if self.gclient_nohooks or self.patch or self.was_patched:
      command.append('--nohooks')
    # GClient accepts --revision argument of two types 'module@rev' and 'rev'.
    if self.revision and not self.no_gclient_revision:
      command.append('--revision')
      # Ignore non-svn part of compound revisions.
      if ':' in self.revision:
        command.append(self.revision.split(':')[0])
      elif (not self.branch or
          self.no_gclient_branch or
          '@' in str(self.revision)):
        command.append(str(self.revision))
      else:
        # Make the revision look like branch@revision.
        prefix = self.project if self.project else self.branch
        command.append('%s@%s' % (prefix, self.revision))

    if self.gclient_deps:
      command.append('--deps=' + self.gclient_deps)

    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        keepStdout=True, environ=self.env)
    self.command = c
    return c.start()

  def getGclientConfigCommand(self):
    """Return the command to run the gclient config step.
    """
    dirname = os.path.join(self.builder.basedir, self.srcdir)
    command = [chromium_utils.GetGClientCommand(), 'config']

    if self.gclient_spec:
      command.append('--spec=%s' % self.gclient_spec)
    else:
      command.append(self.svnurl)

    git_cache_dir = os.path.abspath(
        os.path.join(self.builder.basedir, os.pardir, os.pardir, os.pardir,
                     'git_cache'))
    command.append('--cache-dir=' + git_cache_dir)
    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        keepStdout=True, environ=self.env)
    return c

  def doVCUpdate(self):
    """Sync the client
    """
    # Make sure the .gclient is updated.
    os.remove(os.path.join(self.builder.basedir, self.srcdir, '.gclient'))
    c = self.getGclientConfigCommand()
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    d.addCallback(lambda _: self.doGclientUpdate())
    return d

  def doVCFull(self):
    """Setup the .gclient file and then sync
    """
    chromium_utils.MaybeMakeDirectory(self.builder.basedir, self.srcdir)

    c = self.getGclientConfigCommand()
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    d.addCallback(lambda _: self.doGclientUpdate())
    return d

  def doClobber(self, dummy, dirname, _=False):
    """Move the old directory aside, or delete it if that's already been done.

    This function is designed to be used with a source dir.  If it's called
    with anything else, the caller will need to be sure to clean up the
    <dirname>.dead directory once it's no longer needed.

    If this is the first time we're clobbering since we last finished a
    successful update or checkout, move the old directory aside so a human
    can try to recover from it if desired.  Otherwise -- if such a backup
    directory already exists, because this isn't the first retry -- just
    remove the old directory.

    Args:
      dummy: unused
      dirname: the directory within self.builder.basedir to be clobbered
    """
    old_dir = os.path.join(self.builder.basedir, dirname)
    dead_dir = old_dir + '.dead'
    if os.path.isdir(old_dir):
      if os.path.isdir(dead_dir):
        command = self._RemoveDirectoryCommand(old_dir)
      else:
        command = _RenameDirectoryCommand(old_dir, dead_dir)
      c = runprocess.RunProcess(
          self.builder, command, self.builder.basedir,
          sendRC=0, timeout=self.rm_timeout,
          environ=self.env)
      self.command = c
      # See commands.SVN.doClobber for notes about sendRC.
      d = c.start()
      d.addCallback(self._abandonOnFailure)
      return d
    return None

  def doRevert(self, dummy):
    """Revert any modification done by a previous patch.

    This is done in 2 parts to trap potential errors at each step. Note that
    it is assumed that .orig and .rej files will be reverted, e.g. deleted by
    the 'gclient revert' command. If the try bot is configured with
    'global-ignores=*.orig', patch failure will occur."""
    dirname = os.path.join(self.builder.basedir, self.srcdir)
    command = [chromium_utils.GetGClientCommand(), 'revert', '--nohooks']
    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        keepStdout=True, environ=self.env)
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    # Remove patch residues.
    d.addCallback(lambda _: self._doRevertRemoveSignalFile())
    return d

  def _doRevertRemoveSignalFile(self):
    """Removes the file that signals that the checkout is patched.

    Must be called after a revert has been done and the patch residues have
    been removed."""
    command = _RemoveFileCommand(os.path.join(self.builder.basedir,
                                 self.srcdir, '.buildbot-patched'))
    dirname = os.path.join(self.builder.basedir, self.srcdir)
    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        keepStdout=True, environ=self.env)
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    return d

  def doPatch(self, res):
    patchlevel = self.patch[0]
    diff = FixDiffLineEnding(self.patch[1])

    # Allow overwriting the root with an environment variable.
    root = self.env.get("GCLIENT_PATCH_ROOT", None)

    if len(self.patch) >= 3 and root is None:
      root = self.patch[2]
    command = [
        self.getCommand("patch"),
        '-p%d' % patchlevel,
        '--remove-empty-files',
        '--force',
        '--forward',
    ]
    dirname = os.path.join(self.builder.basedir, self.workdir)
    # Mark the directory so we don't try to update it later.
    open(os.path.join(dirname, ".buildbot-patched"), "w").write("patched\n")

    # Update 'dirname' with the 'root' option. Make sure it is a subdirectory
    # of dirname.
    if (root and
        os.path.abspath(os.path.join(dirname, root)
                        ).startswith(os.path.abspath(dirname))):
      dirname = os.path.join(dirname, root)

    # Now apply the patch.
    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        initialStdin=diff, environ=self.env)
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    if diff.find('DEPS') != -1:
      d.addCallback(self.doVCUpdateOnPatch)
      d.addCallback(self._abandonOnFailure)
    return d

  def doVCUpdateOnPatch(self, res):
    if self.revision and not self.branch and '@' not in str(self.revision):
      self.branch = 'src'
    self.delete_unversioned_trees_when_updating = False
    return self.doVCUpdate()

  def doRunHooks(self, dummy):
    """Runs "gclient runhooks" after patching."""
    dirname = os.path.join(self.builder.basedir, self.srcdir)
    command = [chromium_utils.GetGClientCommand(), 'runhooks']
    c = runprocess.RunProcess(
        self.builder, command, dirname,
        sendRC=False, timeout=self.timeout,
        keepStdout=True, environ=self.env)
    self.command = c
    d = c.start()
    d.addCallback(self._abandonOnFailure)
    return d

  def writeSourcedata(self, res):
    """Write the sourcedata file and remove any dead source directory."""
    d = None
    dead_dir = os.path.join(self.builder.basedir, self.srcdir + '.dead')
    if os.path.isdir(dead_dir):
      msg = 'Removing dead source dir'
      self.sendStatus({'header': msg + '\n'})
      log.msg(msg)
      command = self._RemoveDirectoryCommand(dead_dir)
      c = runprocess.RunProcess(
          self.builder, command, self.builder.basedir,
          sendRC=0, timeout=self.rm_timeout,
          environ=self.env)
      self.command = c
      d = c.start()
      d.addCallback(self._abandonOnFailure)
    open(self.sourcedatafile, 'w').write(self.sourcedata)
    return d

  def parseGotRevision(self):
    if not hasattr(self.command, 'stdout'):
      # self.command may or may not have a .stdout property. The problem is when
      # buildslave.runprocess.RunProcess(keepStdout=False) is used, it doesn't
      # set the property .stdout at all.
      #
      # It may happen depending on the order of execution as self.command only
      # tracks the last run command.
      return {}
    return extract_revisions(self.command.stdout)


  def _handleGotRevision(self, res):
    """Sends parseGotRevision() return values as status updates to the master.
    """
    d = defer.maybeDeferred(self.parseGotRevision)
    # parseGotRevision returns the revision dict, which is passed as the first
    # argument to sendStatus.
    d.addCallback(self.sendStatus)
    return d

  def maybeDoVCFallback(self, rc):
    """Called after doVCUpdate."""
    if isinstance(rc, int) and rc == 2:
      # Non-VC failure, return 2 to turn the step red.
      return rc

    # super
    return SourceBaseCommand.maybeDoVCFallback(self, rc)

  def maybeDoVCRetry(self, res):
    """Called after doVCFull."""
    if isinstance(res, int) and res == 2:
      # Non-VC failure, return 2 to turn the step red.
      return res

    # super
    return SourceBaseCommand.maybeDoVCRetry(self, res)


def RegisterCommands():
  """Registers all command objects defined in this file."""
  try:
    # We run this code in a try because it fails with an assertion if
    # the module is loaded twice.
    commandRegistry['gclient'] = 'slave.chromium_commands.GClient'
    return
  except (AssertionError, NameError):
    pass


RegisterCommands()
