#!/usr/bin/env python
# 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.

"""\
Wrapper script around Rietveld's upload.py that simplifies working with groups
of files.
"""

import json
import optparse
import os
import random
import re
import ssl
import string
import sys
import tempfile
import time
import urllib2

import breakpad  # pylint: disable=W0611


import fix_encoding
import gclient_utils
import git_cl
import presubmit_support
import rietveld
from scm import SVN
import subprocess2
from third_party import upload

__version__ = '1.2.1'


CODEREVIEW_SETTINGS = {
  # To make gcl send reviews to a server, check in a file named
  # "codereview.settings" (see |CODEREVIEW_SETTINGS_FILE| below) to your
  # project's base directory and add the following line to codereview.settings:
  # CODE_REVIEW_SERVER: codereview.yourserver.org
}

# globals that store the root of the current repository and the directory where
# we store information about changelists.
REPOSITORY_ROOT = ""

# Filename where we store repository specific information for gcl.
CODEREVIEW_SETTINGS_FILE = "codereview.settings"
CODEREVIEW_SETTINGS_FILE_NOT_FOUND = (
    'No %s file found. Please add one.' % CODEREVIEW_SETTINGS_FILE)

# Warning message when the change appears to be missing tests.
MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!"

# Global cache of files cached in GetCacheDir().
FILES_CACHE = {}

# Valid extensions for files we want to lint.
DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
DEFAULT_LINT_IGNORE_REGEX = r"$^"

def CheckHomeForFile(filename):
  """Checks the users home dir for the existence of the given file.  Returns
  the path to the file if it's there, or None if it is not.
  """
  home_vars = ['HOME']
  if sys.platform in ('cygwin', 'win32'):
    home_vars.append('USERPROFILE')
  for home_var in home_vars:
    home = os.getenv(home_var)
    if home != None:
      full_path = os.path.join(home, filename)
      if os.path.exists(full_path):
        return full_path
  return None


def UnknownFiles():
  """Runs svn status and returns unknown files."""
  return [
      item[1] for item in SVN.CaptureStatus([], GetRepositoryRoot())
      if item[0][0] == '?'
  ]


def GetRepositoryRoot():
  """Returns the top level directory of the current repository.

  The directory is returned as an absolute path.
  """
  global REPOSITORY_ROOT
  if not REPOSITORY_ROOT:
    REPOSITORY_ROOT = SVN.GetCheckoutRoot(os.getcwd())
    if not REPOSITORY_ROOT:
      raise gclient_utils.Error("gcl run outside of repository")
  return REPOSITORY_ROOT


def GetInfoDir():
  """Returns the directory where gcl info files are stored."""
  return os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info')


def GetChangesDir():
  """Returns the directory where gcl change files are stored."""
  return os.path.join(GetInfoDir(), 'changes')


def GetCacheDir():
  """Returns the directory where gcl change files are stored."""
  return os.path.join(GetInfoDir(), 'cache')


def GetCachedFile(filename, max_age=60*60*24*3, use_root=False):
  """Retrieves a file from the repository and caches it in GetCacheDir() for
  max_age seconds.

  use_root: If False, look up the arborescence for the first match, otherwise go
            directory to the root repository.

  Note: The cache will be inconsistent if the same file is retrieved with both
        use_root=True and use_root=False. Don't be stupid.
  """
  if filename not in FILES_CACHE:
    # Don't try to look up twice.
    FILES_CACHE[filename] = None
    # First we check if we have a cached version.
    try:
      cached_file = os.path.join(GetCacheDir(), filename)
    except (gclient_utils.Error, subprocess2.CalledProcessError):
      return None
    if (not os.path.exists(cached_file) or
        (time.time() - os.stat(cached_file).st_mtime) > max_age):
      dir_info = SVN.CaptureLocalInfo([], '.')
      repo_root = dir_info['Repository Root']
      if use_root:
        url_path = repo_root
      else:
        url_path = dir_info['URL']
      while True:
        # Look in the repository at the current level for the file.
        for _ in range(5):
          content = None
          try:
            # Take advantage of the fact that svn won't output to stderr in case
            # of success but will do in case of failure so don't mind putting
            # stderr into content_array.
            content_array = []
            svn_path = url_path + '/' + filename
            args = ['svn', 'cat', svn_path]
            if sys.platform != 'darwin':
              # MacOSX 10.5.2 has a bug with svn 1.4.4 that will trigger the
              # 'Can\'t get username or password' and can be fixed easily.
              # The fix doesn't work if the user upgraded to svn 1.6.x. Bleh.
              # I don't have time to fix their broken stuff.
              args.append('--non-interactive')
            gclient_utils.CheckCallAndFilter(
                args, cwd='.', filter_fn=content_array.append)
            # Exit the loop if the file was found. Override content.
            content = '\n'.join(content_array)
            break
          except (gclient_utils.Error, subprocess2.CalledProcessError):
            if content_array[0].startswith(
                'svn: Can\'t get username or password'):
              ErrorExit('Your svn credentials expired. Please run svn update '
                        'to fix the cached credentials')
            if content_array[0].startswith('svn: Can\'t get password'):
              ErrorExit('If are using a Mac and svn --version shows 1.4.x, '
                  'please hack gcl.py to remove --non-interactive usage, it\'s'
                  'a bug on your installed copy')
            if (content_array[0].startswith('svn: File not found:') or
                content_array[0].endswith('path not found')):
              break
            # Otherwise, fall through to trying again.
        if content:
          break
        if url_path == repo_root:
          # Reached the root. Abandoning search.
          break
        # Go up one level to try again.
        url_path = os.path.dirname(url_path)
      if content is not None or filename != CODEREVIEW_SETTINGS_FILE:
        # Write a cached version even if there isn't a file, so we don't try to
        # fetch it each time. codereview.settings must always be present so do
        # not cache negative.
        gclient_utils.FileWrite(cached_file, content or '')
    else:
      content = gclient_utils.FileRead(cached_file, 'r')
    # Keep the content cached in memory.
    FILES_CACHE[filename] = content
  return FILES_CACHE[filename]


def GetCodeReviewSetting(key):
  """Returns a value for the given key for this repository."""
  # Use '__just_initialized' as a flag to determine if the settings were
  # already initialized.
  if '__just_initialized' not in CODEREVIEW_SETTINGS:
    settings_file = GetCachedFile(CODEREVIEW_SETTINGS_FILE)
    if settings_file:
      CODEREVIEW_SETTINGS.update(
          gclient_utils.ParseCodereviewSettingsContent(settings_file))
    CODEREVIEW_SETTINGS.setdefault('__just_initialized', None)
  return CODEREVIEW_SETTINGS.get(key, "")


def Warn(msg):
  print >> sys.stderr, msg


def ErrorExit(msg):
  print >> sys.stderr, msg
  sys.exit(1)


def RunShellWithReturnCode(command, print_output=False):
  """Executes a command and returns the output and the return code."""
  p = subprocess2.Popen(
      command,
      cwd=GetRepositoryRoot(),
      stdout=subprocess2.PIPE,
      stderr=subprocess2.STDOUT,
      universal_newlines=True)
  if print_output:
    output_array = []
    while True:
      line = p.stdout.readline()
      if not line:
        break
      if print_output:
        print line.strip('\n')
      output_array.append(line)
    output = "".join(output_array)
  else:
    output = p.stdout.read()
  p.wait()
  p.stdout.close()
  return output, p.returncode


def RunShell(command, print_output=False):
  """Executes a command and returns the output."""
  return RunShellWithReturnCode(command, print_output)[0]


def FilterFlag(args, flag):
  """Returns True if the flag is present in args list.

  The flag is removed from args if present.
  """
  if flag in args:
    args.remove(flag)
    return True
  return False


class ChangeInfo(object):
  """Holds information about a changelist.

    name: change name.
    issue: the Rietveld issue number or 0 if it hasn't been uploaded yet.
    patchset: the Rietveld latest patchset number or 0.
    description: the description.
    files: a list of 2 tuple containing (status, filename) of changed files,
           with paths being relative to the top repository directory.
    local_root: Local root directory
    rietveld: rietveld server for this change
  """
  # Kept for unit test support. This is for the old format, it's deprecated.
  SEPARATOR = "\n-----\n"

  def __init__(self, name, issue, patchset, description, files, local_root,
               rietveld_url, needs_upload):
    # Defer the description processing to git_cl.ChangeDescription.
    self._desc = git_cl.ChangeDescription(description)
    self.name = name
    self.issue = int(issue)
    self.patchset = int(patchset)
    self._files = files or  []
    self.patch = None
    self._local_root = local_root
    self.needs_upload = needs_upload
    self.rietveld = gclient_utils.UpgradeToHttps(
        rietveld_url or GetCodeReviewSetting('CODE_REVIEW_SERVER'))
    self._rpc_server = None

  @property
  def description(self):
    return self._desc.description

  def force_description(self, new_description):
    self._desc = git_cl.ChangeDescription(new_description)
    self.needs_upload = True

  def append_footer(self, line):
    self._desc.append_footer(line)

  def get_reviewers(self):
    return self._desc.get_reviewers()

  def update_reviewers(self, reviewers):
    self._desc.update_reviewers(reviewers)

  def NeedsUpload(self):
    return self.needs_upload

  def GetFileNames(self):
    """Returns the list of file names included in this change."""
    return [f[1] for f in self._files]

  def GetFiles(self):
    """Returns the list of files included in this change with their status."""
    return self._files

  def GetLocalRoot(self):
    """Returns the local repository checkout root directory."""
    return self._local_root

  def Exists(self):
    """Returns True if this change already exists (i.e., is not new)."""
    return (self.issue or self.description or self._files)

  def _NonDeletedFileList(self):
    """Returns a list of files in this change, not including deleted files."""
    return [f[1] for f in self.GetFiles()
            if not f[0].startswith("D")]

  def _AddedFileList(self):
    """Returns a list of files added in this change."""
    return [f[1] for f in self.GetFiles() if f[0].startswith("A")]

  def Save(self):
    """Writes the changelist information to disk."""
    data = json.dumps({
          'issue': self.issue,
          'patchset': self.patchset,
          'needs_upload': self.NeedsUpload(),
          'files': self.GetFiles(),
          'description': self.description,
          'rietveld': self.rietveld,
        }, sort_keys=True, indent=2)
    gclient_utils.FileWrite(GetChangelistInfoFile(self.name), data)

  def Delete(self):
    """Removes the changelist information from disk."""
    os.remove(GetChangelistInfoFile(self.name))

  def RpcServer(self):
    if not self._rpc_server:
      if not self.rietveld:
        ErrorExit(CODEREVIEW_SETTINGS_FILE_NOT_FOUND)
      self._rpc_server = rietveld.CachingRietveld(self.rietveld, None, None)
    return self._rpc_server

  def CloseIssue(self):
    """Closes the Rietveld issue for this changelist."""
    # Newer versions of Rietveld require us to pass an XSRF token to POST, so
    # we fetch it from the server.
    xsrf_token = self.SendToRietveld(
        '/xsrf_token',
        extra_headers={'X-Requesting-XSRF-Token': '1'})

    # You cannot close an issue with a GET.
    # We pass an empty string for the data so it is a POST rather than a GET.
    data = [("description", self.description),
            ("xsrf_token", xsrf_token)]
    ctype, body = upload.EncodeMultipartFormData(data, [])
    self.SendToRietveld('/%d/close' % self.issue, payload=body,
        content_type=ctype)

  def UpdateRietveldDescription(self):
    """Sets the description for an issue on Rietveld."""
    data = [("description", self.description),]
    ctype, body = upload.EncodeMultipartFormData(data, [])
    self.SendToRietveld('/%d/description' % self.issue, payload=body,
        content_type=ctype)
    self.needs_upload = False

  def GetIssueDescription(self):
    """Returns the issue description from Rietveld."""
    return self.SendToRietveld('/%d/description' % self.issue).replace('\r\n',
                                                                       '\n')

  def UpdateDescriptionFromIssue(self):
    """Updates self.description with the issue description from Rietveld."""
    self._desc = git_cl.ChangeDescription(self.GetIssueDescription())

  def GetApprovingReviewers(self):
    """Returns the issue reviewers list from Rietveld."""
    return git_cl.get_approving_reviewers(
        self.RpcServer().get_issue_properties(self.issue, True))

  def AddComment(self, comment):
    """Adds a comment for an issue on Rietveld.
    As a side effect, this will email everyone associated with the issue."""
    return self.RpcServer().add_comment(self.issue, comment)

  def PrimeLint(self):
    """Do background work on Rietveld to lint the file so that the results are
    ready when the issue is viewed."""
    if self.issue and self.patchset:
      try:
        self.SendToRietveld('/lint/issue%s_%s' % (self.issue, self.patchset),
            timeout=60)
      except ssl.SSLError as e:
        # It takes more than 60 seconds to lint some CLs. Silently ignore
        # the expected timeout.
        if e.message != 'The read operation timed out':
          raise

  def SendToRietveld(self, request_path, timeout=None, **kwargs):
    """Send a POST/GET to Rietveld.  Returns the response body."""
    try:
      return self.RpcServer().Send(request_path, timeout=timeout, **kwargs)
    except urllib2.URLError:
      if timeout is None:
        ErrorExit('Error accessing url %s' % request_path)
      else:
        return None

  def MissingTests(self):
    """Returns True if the change looks like it needs unit tests but has none.

    A change needs unit tests if it contains any new source files or methods.
    """
    SOURCE_SUFFIXES = [".cc", ".cpp", ".c", ".m", ".mm"]
    # Ignore third_party entirely.
    files = [f for f in self._NonDeletedFileList()
             if f.find("third_party") == -1]
    added_files = [f for f in self._AddedFileList()
                   if f.find("third_party") == -1]

    # If the change is entirely in third_party, we're done.
    if len(files) == 0:
      return False

    # Any new or modified test files?
    # A test file's name ends with "test.*" or "tests.*".
    test_files = [test for test in files
                  if os.path.splitext(test)[0].rstrip("s").endswith("test")]
    if len(test_files) > 0:
      return False

    # Any new source files?
    source_files = [item for item in added_files
                    if os.path.splitext(item)[1] in SOURCE_SUFFIXES]
    if len(source_files) > 0:
      return True

    # Do the long test, checking the files for new methods.
    return self._HasNewMethod()

  def _HasNewMethod(self):
    """Returns True if the changeset contains any new functions, or if a
    function signature has been changed.

    A function is identified by starting flush left, containing a "(" before
    the next flush-left line, and either ending with "{" before the next
    flush-left line or being followed by an unindented "{".

    Currently this returns True for new methods, new static functions, and
    methods or functions whose signatures have been changed.

    Inline methods added to header files won't be detected by this. That's
    acceptable for purposes of determining if a unit test is needed, since
    inline methods should be trivial.
    """
    # To check for methods added to source or header files, we need the diffs.
    # We'll generate them all, since there aren't likely to be many files
    # apart from source and headers; besides, we'll want them all if we're
    # uploading anyway.
    if self.patch is None:
      self.patch = GenerateDiff(self.GetFileNames())

    definition = ""
    for line in self.patch.splitlines():
      if not line.startswith("+"):
        continue
      line = line.strip("+").rstrip(" \t")
      # Skip empty lines, comments, and preprocessor directives.
      # TODO(pamg): Handle multiline comments if it turns out to be a problem.
      if line == "" or line.startswith("/") or line.startswith("#"):
        continue

      # A possible definition ending with "{" is complete, so check it.
      if definition.endswith("{"):
        if definition.find("(") != -1:
          return True
        definition = ""

      # A { or an indented line, when we're in a definition, continues it.
      if (definition != "" and
          (line == "{" or line.startswith(" ") or line.startswith("\t"))):
        definition += line

      # A flush-left line starts a new possible function definition.
      elif not line.startswith(" ") and not line.startswith("\t"):
        definition = line

    return False

  @staticmethod
  def Load(changename, local_root, fail_on_not_found, update_status):
    """Gets information about a changelist.

    Args:
      fail_on_not_found: if True, this function will quit the program if the
        changelist doesn't exist.
      update_status: if True, the svn status will be updated for all the files
        and unchanged files will be removed.

    Returns: a ChangeInfo object.
    """
    info_file = GetChangelistInfoFile(changename)
    if not os.path.exists(info_file):
      if fail_on_not_found:
        ErrorExit("Changelist " + changename + " not found.")
      return ChangeInfo(changename, 0, 0, '', None, local_root, None, False)
    content = gclient_utils.FileRead(info_file)
    save = False
    try:
      values = ChangeInfo._LoadNewFormat(content)
    except ValueError:
      try:
        values = ChangeInfo._LoadOldFormat(content)
        save = True
      except ValueError:
        ErrorExit(
            ('Changelist file %s is corrupt.\n'
            'Either run "gcl delete %s" or manually edit the file') % (
                info_file, changename))
    files = values['files']
    if update_status:
      for item in files[:]:
        status_result = SVN.CaptureStatus(item[1], local_root)
        if not status_result or not status_result[0][0]:
          # File has been reverted.
          save = True
          files.remove(item)
          continue
        status = status_result[0][0]
        if status != item[0]:
          save = True
          files[files.index(item)] = (status, item[1])
    change_info = ChangeInfo(
        changename,
        values['issue'],
        values['patchset'],
        values['description'],
        files,
        local_root,
        values.get('rietveld'),
        values['needs_upload'])
    if save:
      change_info.Save()
    return change_info

  @staticmethod
  def _LoadOldFormat(content):
    # The info files have the following format:
    # issue_id, patchset\n   (, patchset is optional)
    # SEPARATOR\n
    # filepath1\n
    # filepath2\n
    # .
    # .
    # filepathn\n
    # SEPARATOR\n
    # description
    split_data = content.split(ChangeInfo.SEPARATOR, 2)
    if len(split_data) != 3:
      raise ValueError('Bad change format')
    values = {
      'issue': 0,
      'patchset': 0,
      'needs_upload': False,
      'files': [],
    }
    items = split_data[0].split(', ')
    if items[0]:
      values['issue'] = int(items[0])
    if len(items) > 1:
      values['patchset'] = int(items[1])
    if len(items) > 2:
      values['needs_upload'] = (items[2] == "dirty")
    for line in split_data[1].splitlines():
      status = line[:7]
      filename = line[7:]
      values['files'].append((status, filename))
    values['description'] = split_data[2]
    return values

  @staticmethod
  def _LoadNewFormat(content):
    return json.loads(content)

  def __str__(self):
    out = ['%s:' % self.__class__.__name__]
    for k in dir(self):
      if k.startswith('__'):
        continue
      v = getattr(self, k)
      if v is self or callable(getattr(self, k)):
        continue
      out.append('  %s: %r' % (k, v))
    return '\n'.join(out)


def GetChangelistInfoFile(changename):
  """Returns the file that stores information about a changelist."""
  if not changename or re.search(r'[^\w-]', changename):
    ErrorExit("Invalid changelist name: " + changename)
  return os.path.join(GetChangesDir(), changename)


def LoadChangelistInfoForMultiple(changenames, local_root, fail_on_not_found,
                                  update_status):
  """Loads many changes and merge their files list into one pseudo change.

  This is mainly usefull to concatenate many changes into one for a 'gcl try'.
  """
  changes = changenames.split(',')
  aggregate_change_info = ChangeInfo(
      changenames, 0, 0, '', None, local_root, None, False)
  for change in changes:
    aggregate_change_info._files += ChangeInfo.Load(
        change, local_root, fail_on_not_found, update_status).GetFiles()
  return aggregate_change_info


def GetCLs():
  """Returns a list of all the changelists in this repository."""
  cls = os.listdir(GetChangesDir())
  if CODEREVIEW_SETTINGS_FILE in cls:
    cls.remove(CODEREVIEW_SETTINGS_FILE)
  return cls


def GenerateChangeName():
  """Generate a random changelist name."""
  random.seed()
  current_cl_names = GetCLs()
  while True:
    cl_name = (random.choice(string.ascii_lowercase) +
               random.choice(string.digits) +
               random.choice(string.ascii_lowercase) +
               random.choice(string.digits))
    if cl_name not in current_cl_names:
      return cl_name


def GetModifiedFiles():
  """Returns a set that maps from changelist name to (status,filename) tuples.

  Files not in a changelist have an empty changelist name.  Filenames are in
  relation to the top level directory of the current repository.  Note that
  only the current directory and subdirectories are scanned, in order to
  improve performance while still being flexible.
  """
  files = {}

  # Since the files are normalized to the root folder of the repositary, figure
  # out what we need to add to the paths.
  dir_prefix = os.getcwd()[len(GetRepositoryRoot()):].strip(os.sep)

  # Get a list of all files in changelists.
  files_in_cl = {}
  for cl in GetCLs():
    change_info = ChangeInfo.Load(cl, GetRepositoryRoot(),
                                  fail_on_not_found=True, update_status=False)
    for status, filename in change_info.GetFiles():
      files_in_cl[filename] = change_info.name

  # Get all the modified files down the current directory.
  for line in SVN.CaptureStatus(None, os.getcwd()):
    status = line[0]
    filename = line[1]
    if status[0] == "?":
      continue
    if dir_prefix:
      filename = os.path.join(dir_prefix, filename)
    change_list_name = ""
    if filename in files_in_cl:
      change_list_name = files_in_cl[filename]
    files.setdefault(change_list_name, []).append((status, filename))

  return files


def GetFilesNotInCL():
  """Returns a list of tuples (status,filename) that aren't in any changelists.

  See docstring of GetModifiedFiles for information about path of files and
  which directories are scanned.
  """
  modified_files = GetModifiedFiles()
  if "" not in modified_files:
    return []
  return modified_files[""]


def ListFiles(show_unknown_files):
  files = GetModifiedFiles()
  cl_keys = files.keys()
  cl_keys.sort()
  for cl_name in cl_keys:
    if not cl_name:
      continue
    note = ""
    change_info = ChangeInfo.Load(cl_name, GetRepositoryRoot(),
                                  fail_on_not_found=True, update_status=False)
    if len(change_info.GetFiles()) != len(files[cl_name]):
      note = " (Note: this changelist contains files outside this directory)"
    print "\n--- Changelist " + cl_name + note + ":"
    for filename in files[cl_name]:
      print "".join(filename)
  if show_unknown_files:
    unknown_files = UnknownFiles()
  if (files.get('') or (show_unknown_files and len(unknown_files))):
    print "\n--- Not in any changelist:"
    for item in files.get('', []):
      print "".join(item)
    if show_unknown_files:
      for filename in unknown_files:
        print "?      %s" % filename
  return 0


def GenerateDiff(files):
  return SVN.GenerateDiff(
      files, GetRepositoryRoot(), full_move=False, revision=None)


def GetTreeStatus():
  tree_status_url = GetCodeReviewSetting('STATUS')
  return git_cl.GetTreeStatus(tree_status_url) if tree_status_url else "unset"


def OptionallyDoPresubmitChecks(change_info, committing, args):
  if FilterFlag(args, "--no_presubmit") or FilterFlag(args, "--force"):
    breakpad.SendStack(
        breakpad.DEFAULT_URL + '/breakpad',
        'GclHooksBypassedCommit',
        'Issue %s/%s bypassed hook when committing (tree status was "%s")' %
        (change_info.rietveld, change_info.issue, GetTreeStatus()),
        verbose=False)
    return presubmit_support.PresubmitOutput()
  return DoPresubmitChecks(change_info, committing, True)


def defer_attributes(a, b):
  """Copy attributes from an object (like a function) to another."""
  for x in dir(a):
    if not getattr(b, x, None):
      setattr(b, x, getattr(a, x))


def need_change(function):
  """Converts args -> change_info."""
  # pylint: disable=W0612,W0621
  def hook(args):
    if not len(args) == 1:
      ErrorExit("You need to pass a change list name")
    change_info = ChangeInfo.Load(args[0], GetRepositoryRoot(), True, True)
    return function(change_info)
  defer_attributes(function, hook)
  hook.need_change = True
  hook.no_args = True
  return hook


def need_change_and_args(function):
  """Converts args -> change_info."""
  # pylint: disable=W0612,W0621
  def hook(args):
    if not args:
      ErrorExit("You need to pass a change list name")
    change_info = ChangeInfo.Load(args.pop(0), GetRepositoryRoot(), True, True)
    return function(change_info, args)
  defer_attributes(function, hook)
  hook.need_change = True
  return hook


def no_args(function):
  """Make sure no args are passed."""
  # pylint: disable=W0612,W0621
  def hook(args):
    if args:
      ErrorExit("Doesn't support arguments")
    return function()
  defer_attributes(function, hook)
  hook.no_args = True
  return hook


def attrs(**kwargs):
  """Decorate a function with new attributes."""
  def decorate(function):
    for k in kwargs:
      setattr(function, k, kwargs[k])
    return function
  return decorate


@no_args
def CMDopened():
  """Lists modified files in the current directory down."""
  return ListFiles(False)


@no_args
def CMDstatus():
  """Lists modified and unknown files in the current directory down."""
  return ListFiles(True)


@need_change_and_args
@attrs(usage='[--no_presubmit] [--no_watchlists]')
def CMDupload(change_info, args):
  """Uploads the changelist to the server for review.

  This does not submit a try job; use gcl try to submit a try job.
  """
  if '-s' in args or '--server' in args:
    ErrorExit('Don\'t use the -s flag, fix codereview.settings instead')
  if not change_info.GetFiles():
    print "Nothing to upload, changelist is empty."
    return 0

  output = OptionallyDoPresubmitChecks(change_info, False, args)
  if not output.should_continue():
    return 1
  no_watchlists = (FilterFlag(args, "--no_watchlists") or
                   FilterFlag(args, "--no-watchlists"))

  # Map --send-mail to --send_mail
  if FilterFlag(args, "--send-mail"):
    args.append("--send_mail")

  # Replace -m with -t and --message with --title, but make sure to
  # preserve anything after the -m/--message.
  found_deprecated_arg = [False]
  def replace_message(a):
    if a.startswith('-m'):
      found_deprecated_arg[0] = True
      return '-t' + a[2:]
    elif a.startswith('--message'):
      found_deprecated_arg[0] = True
      return '--title' + a[9:]
    return a
  args = map(replace_message, args)
  if found_deprecated_arg[0]:
    print >> sys.stderr, (
        '\nWARNING: Use -t or --title to set the title of the patchset.\n'
        'In the near future, -m or --message will send a message instead.\n'
        'See http://goo.gl/JGg0Z for details.\n')

  upload_arg = ["upload.py", "-y"]
  upload_arg.append("--server=%s" % change_info.rietveld.encode('utf-8'))

  reviewers = change_info.get_reviewers() or output.reviewers
  if (reviewers and
      not any(arg.startswith('-r') or arg.startswith('--reviewer') for
              arg in args)):
    upload_arg.append('--reviewers=%s' % ','.join(reviewers))

  upload_arg.extend(args)

  desc_file = None
  try:
    if change_info.issue:
      # Uploading a new patchset.
      upload_arg.append("--issue=%d" % change_info.issue)

      if not any(i.startswith('--title') or i.startswith('-t') for i in args):
        upload_arg.append('--title= ')
    else:
      # First time we upload.
      handle, desc_file = tempfile.mkstemp(text=True)
      os.write(handle, change_info.description)
      os.close(handle)

      # Watchlist processing -- CC people interested in this changeset
      # http://dev.chromium.org/developers/contributing-code/watchlists
      if not no_watchlists:
        import watchlists
        watchlist = watchlists.Watchlists(change_info.GetLocalRoot())
        watchers = watchlist.GetWatchersForPaths(change_info.GetFileNames())

      # We check this before applying the "PRIVATE" parameter of codereview
      # settings assuming that the author of the settings file has put
      # addresses which we can send private CLs to, and so we should ignore
      # CC_LIST only when --private is specified explicitly on the command
      # line.
      if "--private" in upload_arg:
        Warn("WARNING: CC_LIST and WATCHLISTS are ignored when --private is "
             "specified.  You need to review and add them manually if "
             "necessary.")
        cc_list = ""
        no_watchlists = True
      else:
        cc_list = GetCodeReviewSetting("CC_LIST")
      if not no_watchlists and watchers:
        # Filter out all empty elements and join by ','
        cc_list = ','.join(filter(None, [cc_list] + watchers))
      if cc_list:
        upload_arg.append("--cc=" + cc_list)
      upload_arg.append("--file=%s" % desc_file)

      if GetCodeReviewSetting("PRIVATE") == "True":
        upload_arg.append("--private")

      project = GetCodeReviewSetting("PROJECT")
      if project:
        upload_arg.append("--project=%s" % project)

    # If we have a lot of files with long paths, then we won't be able to fit
    # the command to "svn diff".  Instead, we generate the diff manually for
    # each file and concatenate them before passing it to upload.py.
    if change_info.patch is None:
      change_info.patch = GenerateDiff(change_info.GetFileNames())

    # Change the current working directory before calling upload.py so that it
    # shows the correct base.
    previous_cwd = os.getcwd()
    os.chdir(change_info.GetLocalRoot())
    try:
      try:
        issue, patchset = upload.RealMain(upload_arg, change_info.patch)
      except KeyboardInterrupt:
        sys.exit(1)
      if issue and patchset:
        change_info.issue = int(issue)
        change_info.patchset = int(patchset)
        change_info.Save()
      change_info.PrimeLint()
    finally:
      os.chdir(previous_cwd)
  finally:
    if desc_file:
      os.remove(desc_file)
  print "*** Upload does not submit a try; use gcl try to submit a try. ***"
  return 0


@need_change_and_args
@attrs(usage='[--upload]')
def CMDpresubmit(change_info, args):
  """Runs presubmit checks on the change.

  The actual presubmit code is implemented in presubmit_support.py and looks
  for PRESUBMIT.py files."""
  if not change_info.GetFiles():
    print('Nothing to presubmit check, changelist is empty.')
    return 0
  parser = optparse.OptionParser()
  parser.add_option('--upload', action='store_true')
  options, args = parser.parse_args(args)
  if args:
    parser.error('Unrecognized args: %s' % args)
  if options.upload:
    print('*** Presubmit checks for UPLOAD would report: ***')
    return not DoPresubmitChecks(change_info, False, False)
  else:
    print('*** Presubmit checks for COMMIT would report: ***')
    return not DoPresubmitChecks(change_info, True, False)


def TryChange(change_info, args, swallow_exception):
  """Create a diff file of change_info and send it to the try server."""
  try:
    import trychange
  except ImportError:
    if swallow_exception:
      return 1
    ErrorExit("You need to install trychange.py to use the try server.")

  trychange_args = []
  if change_info:
    trychange_args.extend(['--name', change_info.name])
    if change_info.issue:
      trychange_args.extend(["--issue", str(change_info.issue)])
    if change_info.patchset:
      trychange_args.extend(["--patchset", str(change_info.patchset)])
    change = presubmit_support.SvnChange(change_info.name,
                                         change_info.description,
                                         change_info.GetLocalRoot(),
                                         change_info.GetFiles(),
                                         change_info.issue,
                                         change_info.patchset,
                                         None)
  else:
    change = None

  trychange_args.extend(args)
  return trychange.TryChange(
      trychange_args,
      change=change,
      swallow_exception=swallow_exception,
      prog='gcl try',
      extra_epilog='\n'
          'When called from gcl, use the format gcl try <change_name>.\n')


@need_change_and_args
@attrs(usage='[--no_presubmit]')
def CMDcommit(change_info, args):
  """Commits the changelist to the repository."""
  if not change_info.GetFiles():
    print "Nothing to commit, changelist is empty."
    return 1

  # OptionallyDoPresubmitChecks has a side-effect which eats these flags.
  bypassed = '--no_presubmit' in args or '--force' in args
  output = OptionallyDoPresubmitChecks(change_info, True, args)
  if not output.should_continue():
    return 1

  # We face a problem with svn here: Let's say change 'bleh' modifies
  # svn:ignore on dir1\. but another unrelated change 'pouet' modifies
  # dir1\foo.cc. When the user `gcl commit bleh`, foo.cc is *also committed*.
  # The only fix is to use --non-recursive but that has its issues too:
  # Let's say if dir1 is deleted, --non-recursive must *not* be used otherwise
  # you'll get "svn: Cannot non-recursively commit a directory deletion of a
  # directory with child nodes". Yay...
  commit_cmd = ["svn", "commit"]
  if change_info.issue:
    # Get the latest description from Rietveld.
    change_info.UpdateDescriptionFromIssue()

  change_info.update_reviewers(change_info.GetApprovingReviewers())

  commit_desc = git_cl.ChangeDescription(change_info.description)
  if change_info.issue:
    server = change_info.rietveld
    if not server.startswith("http://") and not server.startswith("https://"):
      server = "http://" + server
    commit_desc.append_footer('Review URL: %s/%d' % (server, change_info.issue))

  handle, commit_filename = tempfile.mkstemp(text=True)
  os.write(handle, commit_desc.description)
  os.close(handle)
  try:
    handle, targets_filename = tempfile.mkstemp(text=True)
    os.write(handle, "\n".join(change_info.GetFileNames()))
    os.close(handle)
    try:
      commit_cmd += ['--file=' + commit_filename]
      commit_cmd += ['--targets=' + targets_filename]
      # Change the current working directory before calling commit.
      output = ''
      try:
        output = RunShell(commit_cmd, True)
      except subprocess2.CalledProcessError, e:
        ErrorExit('Commit failed.\n%s' % e)
    finally:
      os.remove(commit_filename)
  finally:
    os.remove(targets_filename)
  if output.find("Committed revision") != -1:
    change_info.Delete()

    if change_info.issue:
      revision = re.compile(".*?\nCommitted revision (\d+)",
                            re.DOTALL).match(output).group(1)
      viewvc_url = GetCodeReviewSetting('VIEW_VC')
      if viewvc_url and revision:
        change_info.append_footer('Committed: ' + viewvc_url + revision)
      elif revision:
        change_info.append_footer('Committed: ' + revision)
      change_info.CloseIssue()
      props = change_info.RpcServer().get_issue_properties(
          change_info.issue, False)
      patch_num = len(props['patchsets'])
      comment = "Committed patchset #%d manually as r%s" % (patch_num, revision)
      if bypassed:
        comment += ' (tree was closed).' if GetTreeStatus() == 'closed' else '.'
      else:
        comment += ' (presubmit successful).'
      change_info.AddComment(comment)
  return 0


def CMDchange(args):
  """Creates or edits a changelist.

  Only scans the current directory and subdirectories.
  """
  # Verify the user is running the change command from a read-write checkout.
  svn_info = SVN.CaptureLocalInfo([], '.')
  if not svn_info:
    ErrorExit("Current checkout is unversioned.  Please retry with a versioned "
              "directory.")

  if len(args) == 0:
    # Generate a random changelist name.
    changename = GenerateChangeName()
  elif args[0] == '--force':
    changename = GenerateChangeName()
  else:
    changename = args[0]
  change_info = ChangeInfo.Load(changename, GetRepositoryRoot(), False, True)

  if len(args) == 2:
    if not os.path.isfile(args[1]):
      ErrorExit('The change "%s" doesn\'t exist.' % args[1])
    f = open(args[1], 'rU')
    override_description = f.read()
    f.close()
  else:
    override_description = None

  if change_info.issue and not change_info.NeedsUpload():
    try:
      description = change_info.GetIssueDescription()
    except urllib2.HTTPError, err:
      if err.code == 404:
        # The user deleted the issue in Rietveld, so forget the old issue id.
        description = change_info.description
        change_info.issue = 0
        change_info.Save()
      else:
        ErrorExit("Error getting the description from Rietveld: " + err)
  else:
    if override_description:
      description = override_description
    else:
      description = change_info.description

  other_files = GetFilesNotInCL()

  # Edited files (as opposed to files with only changed properties) will have
  # a letter for the first character in the status string.
  file_re = re.compile(r"^[a-z].+\Z", re.IGNORECASE)
  affected_files = [x for x in other_files if file_re.match(x[0])]
  unaffected_files = [x for x in other_files if not file_re.match(x[0])]

  description = description.rstrip() + '\n'

  separator1 = ("\n---All lines above this line become the description.\n"
                "---Repository Root: " + change_info.GetLocalRoot() + "\n"
                "---Paths in this changelist (" + change_info.name + "):\n")
  separator2 = "\n\n---Paths modified but not in any changelist:\n\n"

  text = (description + separator1 + '\n' +
          '\n'.join([f[0] + f[1] for f in change_info.GetFiles()]))

  if change_info.Exists():
    text += (separator2 +
            '\n'.join([f[0] + f[1] for f in affected_files]) + '\n')
  else:
    text += ('\n'.join([f[0] + f[1] for f in affected_files]) + '\n' +
            separator2)
  text += '\n'.join([f[0] + f[1] for f in unaffected_files]) + '\n'

  result = gclient_utils.RunEditor(text, False)
  if not result:
    ErrorExit('Running editor failed')

  split_result = result.split(separator1, 1)
  if len(split_result) != 2:
    ErrorExit("Don't modify the text starting with ---!\n\n%r" % result)

  # Update the CL description if it has changed.
  new_description = split_result[0]
  cl_files_text = split_result[1]
  if new_description != description or override_description:
    change_info.force_description(new_description)

  new_cl_files = []
  for line in cl_files_text.splitlines():
    if not len(line):
      continue
    if line.startswith("---"):
      break
    status = line[:7]
    filename = line[7:]
    new_cl_files.append((status, filename))

  if (not len(change_info.GetFiles()) and not change_info.issue and
      not len(new_description) and not new_cl_files):
    ErrorExit("Empty changelist not saved")

  change_info._files = new_cl_files
  change_info.Save()
  if svn_info.get('URL', '').startswith('http:'):
    Warn("WARNING: Creating CL in a read-only checkout.  You will need to "
         "commit using a commit queue!")

  print change_info.name + " changelist saved."
  if change_info.MissingTests():
    Warn("WARNING: " + MISSING_TEST_MSG)

  # Update the Rietveld issue.
  if change_info.issue and change_info.NeedsUpload():
    change_info.UpdateRietveldDescription()
    change_info.Save()
  return 0


@need_change_and_args
def CMDlint(change_info, args):
  """Runs cpplint.py on all the files in the change list.

  Checks all the files in the changelist for possible style violations.
  """
  # Access to a protected member _XX of a client class
  # pylint: disable=W0212
  try:
    import cpplint
    import cpplint_chromium
  except ImportError:
    ErrorExit("You need to install cpplint.py to lint C++ files.")
  # Change the current working directory before calling lint so that it
  # shows the correct base.
  previous_cwd = os.getcwd()
  os.chdir(change_info.GetLocalRoot())
  try:
    # Process cpplints arguments if any.
    filenames = cpplint.ParseArguments(args + change_info.GetFileNames())

    white_list = GetCodeReviewSetting("LINT_REGEX")
    if not white_list:
      white_list = DEFAULT_LINT_REGEX
    white_regex = re.compile(white_list)
    black_list = GetCodeReviewSetting("LINT_IGNORE_REGEX")
    if not black_list:
      black_list = DEFAULT_LINT_IGNORE_REGEX
    black_regex = re.compile(black_list)
    extra_check_functions = [cpplint_chromium.CheckPointerDeclarationWhitespace]
    for filename in filenames:
      if white_regex.match(filename):
        if black_regex.match(filename):
          print "Ignoring file %s" % filename
        else:
          cpplint.ProcessFile(filename, cpplint._cpplint_state.verbose_level,
                              extra_check_functions)
      else:
        print "Skipping file %s" % filename
  finally:
    os.chdir(previous_cwd)

  print "Total errors found: %d\n" % cpplint._cpplint_state.error_count
  return 1


def DoPresubmitChecks(change_info, committing, may_prompt):
  """Imports presubmit, then calls presubmit.DoPresubmitChecks."""
  root_presubmit = GetCachedFile('PRESUBMIT.py', use_root=True)
  change = presubmit_support.SvnChange(change_info.name,
                                       change_info.description,
                                       change_info.GetLocalRoot(),
                                       change_info.GetFiles(),
                                       change_info.issue,
                                       change_info.patchset,
                                       None)
  output = presubmit_support.DoPresubmitChecks(
      change=change,
      committing=committing,
      verbose=False,
      output_stream=sys.stdout,
      input_stream=sys.stdin,
      default_presubmit=root_presubmit,
      may_prompt=may_prompt,
      rietveld_obj=change_info.RpcServer())
  if not output.should_continue() and may_prompt:
    # TODO(dpranke): move into DoPresubmitChecks(), unify cmd line args.
    print "\nPresubmit errors, can't continue (use --no_presubmit to bypass)"

  return output


@no_args
def CMDchanges():
  """Lists all the changelists and their files."""
  for cl in GetCLs():
    change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True)
    print "\n--- Changelist " + change_info.name + ":"
    for filename in change_info.GetFiles():
      print "".join(filename)
  return 0


@no_args
def CMDdeleteempties():
  """Delete all changelists that have no files."""
  print "\n--- Deleting:"
  for cl in GetCLs():
    change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), True, True)
    if not len(change_info.GetFiles()):
      print change_info.name
      change_info.Delete()
  return 0


@no_args
def CMDnothave():
  """Lists files unknown to Subversion."""
  for filename in UnknownFiles():
    print "?      " + "".join(filename)
  return 0


@attrs(usage='<svn options>')
def CMDdiff(args):
  """Diffs all files in the changelist or all files that aren't in a CL."""
  files = None
  if args:
    change_info = ChangeInfo.Load(args.pop(0), GetRepositoryRoot(), True, True)
    files = change_info.GetFileNames()
  else:
    files = [f[1] for f in GetFilesNotInCL()]

  root = GetRepositoryRoot()
  cmd = ['svn', 'diff']
  cmd.extend([os.path.join(root, x) for x in files])
  cmd.extend(args)
  return RunShellWithReturnCode(cmd, print_output=True)[1]


@no_args
def CMDsettings():
  """Prints code review settings for this checkout."""
  # Force load settings
  GetCodeReviewSetting("UNKNOWN")
  del CODEREVIEW_SETTINGS['__just_initialized']
  print '\n'.join(("%s: %s" % (str(k), str(v))
                    for (k,v) in CODEREVIEW_SETTINGS.iteritems()))
  return 0


@need_change
def CMDdescription(change_info):
  """Prints the description of the specified change to stdout."""
  print change_info.description
  return 0


def CMDdelete(args):
  """Deletes a changelist."""
  if not len(args) == 1:
    ErrorExit('You need to pass a change list name')
  filepath = GetChangelistInfoFile(args[0])
  if not os.path.isfile(filepath):
    ErrorExit('You need to pass a valid change list name')
  os.remove(filepath)
  return 0


def CMDtry(args):
  """Sends the change to the tryserver to do a test run on your code.

  To send multiple changes as one path, use a comma-separated list of
  changenames. Use 'gcl help try' for more information!"""
  # When the change contains no file, send the "changename" positional
  # argument to trychange.py.
  # When the command is 'try' and --patchset is used, the patch to try
  # is on the Rietveld server.
  if not args:
    ErrorExit("You need to pass a change list name")
  if args[0].find(',') != -1:
    change_info = LoadChangelistInfoForMultiple(args[0], GetRepositoryRoot(),
                                                True, True)
  else:
    change_info = ChangeInfo.Load(args[0], GetRepositoryRoot(),
                                  True, True)

  props = change_info.RpcServer().get_issue_properties(
    change_info.issue, False)
  if props.get('private'):
    ErrorExit('Cannot use trybots on a private issue')

  if change_info.GetFiles():
    args = args[1:]
  else:
    change_info = None
  return TryChange(change_info, args, swallow_exception=False)


@attrs(usage='<old-name> <new-name>')
def CMDrename(args):
  """Renames an existing change."""
  if len(args) != 2:
    ErrorExit("Usage: gcl rename <old-name> <new-name>.")
  src, dst = args
  src_file = GetChangelistInfoFile(src)
  if not os.path.isfile(src_file):
    ErrorExit("Change '%s' does not exist." % src)
  dst_file = GetChangelistInfoFile(dst)
  if os.path.isfile(dst_file):
    ErrorExit("Change '%s' already exists; pick a new name." % dst)
  os.rename(src_file, dst_file)
  print "Change '%s' renamed '%s'." % (src, dst)
  return 0


def CMDpassthru(args):
  """Everything else that is passed into gcl we redirect to svn.

  It assumes a change list name is passed and is converted with the files names.
  """
  if not args or len(args) < 2:
    ErrorExit("You need to pass a change list name for this svn fall-through "
              "command")
  cl_name = args[1]
  args = ["svn", args[0]]
  if len(args) > 1:
    root = GetRepositoryRoot()
    change_info = ChangeInfo.Load(cl_name, root, True, True)
    args.extend([os.path.join(root, x) for x in change_info.GetFileNames()])
  return RunShellWithReturnCode(args, print_output=True)[1]


def Command(name):
  return getattr(sys.modules[__name__], 'CMD' + name, None)


def GenUsage(command):
  """Modify an OptParse object with the function's documentation."""
  obj = Command(command)
  display = command
  more = getattr(obj, 'usage', '')
  if command == 'help':
    display = '<command>'
  need_change_val = ''
  if getattr(obj, 'need_change', None):
    need_change_val = ' <change_list>'
  options = ' [options]'
  if getattr(obj, 'no_args', None):
    options = ''
  res = 'Usage: gcl %s%s%s %s\n\n' % (display, need_change_val, options, more)
  res += re.sub('\n  ', '\n', obj.__doc__)
  return res


def CMDhelp(args):
  """Prints this help or help for the given command."""
  if args and 'CMD' + args[0] in dir(sys.modules[__name__]):
    print GenUsage(args[0])

    # These commands defer to external tools so give this info too.
    if args[0] == 'try':
      TryChange(None, ['--help'], swallow_exception=False)
    if args[0] == 'upload':
      upload.RealMain(['upload.py', '--help'])
    return 0

  print GenUsage('help')
  print sys.modules[__name__].__doc__
  print 'version ' + __version__ + '\n'

  print('Commands are:\n' + '\n'.join([
        '  %-12s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
        for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')]))
  return 0


def main(argv):
  if sys.hexversion < 0x02060000:
    print >> sys.stderr, (
        '\nYour python version %s is unsupported, please upgrade.\n' %
        sys.version.split(' ', 1)[0])
    return 2
  if not argv:
    argv = ['help']
  command = Command(argv[0])
  # Help can be run from anywhere.
  if command == CMDhelp:
    return command(argv[1:])

  try:
    GetRepositoryRoot()
  except (gclient_utils.Error, subprocess2.CalledProcessError):
    print >> sys.stderr, 'To use gcl, you need to be in a subversion checkout.'
    return 1

  # Create the directories where we store information about changelists if it
  # doesn't exist.
  try:
    if not os.path.exists(GetInfoDir()):
      os.mkdir(GetInfoDir())
    if not os.path.exists(GetChangesDir()):
      os.mkdir(GetChangesDir())
    if not os.path.exists(GetCacheDir()):
      os.mkdir(GetCacheDir())

    if command:
      return command(argv[1:])
    # Unknown command, try to pass that to svn
    return CMDpassthru(argv)
  except (gclient_utils.Error, subprocess2.CalledProcessError), e:
    print >> sys.stderr, 'Got an exception'
    print >> sys.stderr, str(e)
    return 1
  except upload.ClientLoginError, e:
    print >> sys.stderr, 'Got an exception logging in to Rietveld'
    print >> sys.stderr, str(e)
    return 1
  except urllib2.HTTPError, e:
    if e.code != 500:
      raise
    print >> sys.stderr, (
        'AppEngine is misbehaving and returned HTTP %d, again. Keep faith '
        'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))
    return 1


if __name__ == "__main__":
  fix_encoding.fix_encoding()
  sys.exit(main(sys.argv[1:]))
