# -*- coding: utf-8 -*-

# Copyright (c) 2006 - 2007 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the VCS status monitor thread class for CVS.
"""

from PyQt4.QtCore import QRegExp, QProcess, QStringList, QString

from VCS.StatusMonitorThread import VcsStatusMonitorThread

import Preferences

class CvsStatusMonitorThread(VcsStatusMonitorThread):
    """
    Class implementing the VCS status monitor thread class for Subversion.
    """
    def __init__(self, interval, projectDir, parent = None):
        """
        Constructor
        
        @param interval new interval in seconds (integer)
        @param projectDir project directory to monitor (string or QString)
        @param parent reference to the parent object (QObject)
        """
        VcsStatusMonitorThread.__init__(self, interval, projectDir, parent)
        
        self.__ioEncoding = str(Preferences.getSystem("IOEncoding"))
        
        self.rx_status = \
            QRegExp('([UPARMC])\\s+(.+)\\s*')
    
    def _performMonitor(self):
        """
        Protected method implementing the monitoring action.
        
        This method populates the statusList member variable
        with a list of strings giving the status in the first column and the
        path relative to the project directory starting with the third column.
        The allowed status flags are:
        <li>
            <ul>"A" path was added but not yet comitted</ul>
            <ul>"M" path has local changes</ul>
            <ul>"U" path needs an update</ul>
            <ul>"Z" path contains a conflict</ul>
            <ul>" " path is back at normal</ul>
        </li>
        
        @return tuple of flag indicating successful operation (boolean) and 
            a status message in case of non successful operation (QString)
        """
        process = QProcess()
        args = QStringList()
        args.append('-n')
        args.append('-q')
        args.append('update')
        process.setWorkingDirectory(self.projectDir)
        process.start('cvs', args)
        procStarted = process.waitForStarted()
        if procStarted:
            finished = process.waitForFinished(300000)
            if finished and process.exitCode() == 0:
                output = \
                    unicode(process.readAllStandardOutput(), self.__ioEncoding, 'replace')
                states = {}
                for line in output.splitlines():
                    if self.rx_status.exactMatch(line):
                        status = str(self.rx_status.cap(1))
                        path = self.rx_status.cap(2).trimmed()
                    else:
                        continue
                    if status == "P":
                        status = "U"
                    elif status == "C":
                        status = "Z"    # give it highest priority
                    if status in "AMUZ":
                        name = unicode(path)
                        states[name] = status
                        try:
                            if self.reportedStates[name] != status:
                                self.statusList.append("%s %s" % (status, name))
                        except KeyError:
                            self.statusList.append("%s %s" % (status, name))
                for name in self.reportedStates.keys():
                    if name not in states:
                        self.statusList.append("  %s" % name)
                self.reportedStates = states
                return True, self.trUtf8("CVS status checked successfully")
            else:
                return False, QString(process.readAllStandardError())
        else:
            return False, self.trUtf8("Could not start the CVS process.")
