# Copyright (c) 2005 Mark Williamson <mark.williamson@cl.cam.ac.uk>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import re

from ctcore import *

def doCommit(keepFiles, filesToCommit, msg):
    commitFileNames = []
    for f in filesToCommit:
        commitFileNames.append(f.dstName)
    runProgram(['hg', 'commit', '-A', '-l', '-'] + commitFileNames, msg)

class HgFile(File):
    def __init__(self, unknown=False):
        File.__init__(self)

    def getPatchImpl(self):
        return getPatch(self)

def fileSetFactory(addCallback, removeCallback):
    return FileSet(addCallback, removeCallback)

parseDiffRE = re.compile('([AMR?]) (.*)')

def getPatch(file, otherFile = None):
    if file.change == 'M' or \
       file.change == 'R' or \
       file.change == 'A':
        return runProgram(['hg', 'diff', file.dstName])
    elif file.change == '?':
        return runProgram(['diff', '-u', '/dev/null', file.dstName],
                          expectedexits=[0,1,2])
    else:
        assert(False)

def __parseStatus():
    inp = runProgram(['hg', 'status'])
    ret = []
    try:
        recs = inp.split("\n")
        recs.pop() # remove last entry (which is '')
        it = recs.__iter__()
        while True:
            rec = it.next()
            m = parseDiffRE.match(rec)
            
            if not m:
                print "Unknown output from hg status!: " + rec + "\n"
                continue

            f = HgFile()
            f.change = m.group(1)

            if f.change == '?' and not settings().showUnknown:
                continue
            
            f.srcName = f.dstName = m.group(2)

            ret.append(f)
    except StopIteration:
        pass
    return ret


def updateFiles(fileSet):
    for f in list([x for x in fileSet]):
        fileSet.remove(f)

    files = __parseStatus()
    for f in files:
        c = f.change
        if   c == 'A':
            f.text = 'Added file: ' + f.srcName
        elif c == '?':
            f.text = 'New file: ' + f.srcName
        elif c == 'R':
            f.text = 'Removed file: ' + f.srcName
        else:
            f.text = f.srcName

        fileSet.add(f)

def initialize():
    def basicsFailed(msg):
        print "hg status: " + msg
        print "Make sure that the current working directory contains a '.hg' directory."
        sys.exit(1)
        
    try:
        runProgram(['hg', 'status'])
    except OSError, e:
        basicsFailed(e.strerror)
    except ProgramError, e:
        basicsFailed(e.error)

def doUpdateCache(file):
    return

def discardFile(file):
    if file.change == "M":
        runProgram(['hg', 'revert', file.dstName])
    elif file.change == "?":
        runProgram(['rm', '-f', file.dstName])
    return

def ignoreFile(file):
    hgignore = open('.hgignore', 'a')
    print >> hgignore, "^" + re.escape(file.dstName) + "$"
    hgignore.close()


# Not yet implemented
def commitIsMerge():
    return False

def mergeMessage():
    return ''

# Not yet implemented
def getCurrentBranch():
    return None
