'''
Copyright 2011 Google Inc.

Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
'''

import fnmatch
import os
import re
import subprocess

PROPERTY_MIMETYPE = 'svn:mime-type'

# Status types for GetFilesWithStatus()
STATUS_ADDED                 = 0x01
STATUS_DELETED               = 0x02
STATUS_MODIFIED              = 0x04
STATUS_NOT_UNDER_SVN_CONTROL = 0x08


if os.name == 'nt':
  SVN = 'svn.bat'
else:
  SVN = 'svn'


def Cat(svn_url):
    """Returns the contents of the file at the given svn_url. 

    @param svn_url URL of the file to read
    """
    proc = subprocess.Popen([SVN, 'cat', svn_url],
                            stdout=subprocess.PIPE,
                            stderr=subprocess.STDOUT)
    exitcode = proc.wait()
    if not exitcode == 0:
        raise Exception('Could not retrieve %s. Verify that the URL is valid '
                        'and check your connection.' % svn_url)
    return proc.communicate()[0]


class Svn:

    def __init__(self, directory):
        """Set up to manipulate SVN control within the given directory.

        @param directory
        """
        self._directory = directory

    def _RunCommand(self, args):
        """Run a command (from self._directory) and return stdout as a single
        string.

        @param args a list of arguments
        """
        print 'RunCommand: %s' % args
        proc = subprocess.Popen(args, cwd=self._directory,
                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        (stdout, stderr) = proc.communicate()
        if proc.returncode is not 0:
            raise Exception('command "%s" failed in dir "%s": %s' %
                            (args, self._directory, stderr))
        return stdout

    def GetInfo(self):
        """Run "svn info" and return a dictionary containing its output.
        """
        output = self._RunCommand([SVN, 'info'])
        svn_info = {}
        for line in output.split('\n'):
          if ':' in line:
            (key, value) = line.split(':', 1)
            svn_info[key.strip()] = value.strip()
        return svn_info

    def Checkout(self, url, path):
        """Check out a working copy from a repository.
        Returns stdout as a single string.

        @param url URL from which to check out the working copy
        @param path path (within self._directory) where the local copy will be
        written
        """
        return self._RunCommand([SVN, 'checkout', url, path])

    def ListSubdirs(self, url):
        """Returns a list of all subdirectories (not files) within a given SVN
        url.

        @param url remote directory to list subdirectories of
        """
        subdirs = []
        filenames = self._RunCommand([SVN, 'ls', url]).split('\n')
        for filename in filenames:
            if filename.endswith('/'):
                subdirs.append(filename.strip('/'))
        return subdirs

    def GetNewFiles(self):
        """Return a list of files which are in this directory but NOT under
        SVN control.
        """
        return self.GetFilesWithStatus(STATUS_NOT_UNDER_SVN_CONTROL)

    def GetNewAndModifiedFiles(self):
        """Return a list of files in this dir which are newly added or modified,
        including those that are not (yet) under SVN control.
        """
        return self.GetFilesWithStatus(
            STATUS_ADDED | STATUS_MODIFIED | STATUS_NOT_UNDER_SVN_CONTROL)

    def GetFilesWithStatus(self, status):
        """Return a list of files in this dir with the given SVN status.

        @param status bitfield combining one or more STATUS_xxx values
        """
        status_types_string = ''
        if status & STATUS_ADDED:
            status_types_string += 'A'
        if status & STATUS_DELETED:
            status_types_string += 'D'
        if status & STATUS_MODIFIED:
            status_types_string += 'M'
        if status & STATUS_NOT_UNDER_SVN_CONTROL:
            status_types_string += '\?'
        status_regex_string = '^[%s].....\s+(.+)$' % status_types_string
        stdout = self._RunCommand([SVN, 'status'])
        status_regex = re.compile(status_regex_string, re.MULTILINE)
        files = status_regex.findall(stdout)
        return files

    def AddFiles(self, filenames):
        """Adds these files to SVN control.

        @param filenames files to add to SVN control
        """
        self._RunCommand([SVN, 'add'] + filenames)

    def SetProperty(self, filenames, property_name, property_value):
        """Sets a svn property for these files.

        @param filenames files to set property on
        @param property_name property_name to set for each file
        @param property_value what to set the property_name to
        """
        if filenames:
            self._RunCommand(
                [SVN, 'propset', property_name, property_value] + filenames)

    def SetPropertyByFilenamePattern(self, filename_pattern,
                                     property_name, property_value):
        """Sets a svn property for all files matching filename_pattern.

        @param filename_pattern set the property for all files whose names match
               this Unix-style filename pattern (e.g., '*.jpg')
        @param property_name property_name to set for each file
        @param property_value what to set the property_name to
        """
        all_files = os.listdir(self._directory)
        matching_files = sorted(fnmatch.filter(all_files, filename_pattern))
        self.SetProperty(matching_files, property_name, property_value)

    def ExportBaseVersionOfFile(self, file_within_repo, dest_path):
        """Retrieves a copy of the base version (what you would get if you ran
        'svn revert') of a file within the repository.

        @param file_within_repo path to the file within the repo whose base
               version you wish to obtain
        @param dest_path destination to which to write the base content
        """
        self._RunCommand([SVN, 'export', '--revision', 'BASE',
                          file_within_repo, dest_path])
