#!/usr/bin/python

import sys, math, random, os, re, signal, tempfile, stat, errno, traceback
from heapq import heappush, heappop
from sets import Set

sys.path.append('@@GIT_PYTHON_PATH@@')
from gitMergeCommon import *

# The actual merge code
# ---------------------

originalIndexFile = os.environ.get('GIT_INDEX_FILE',
                                   os.environ.get('GIT_DIR', '.git') + '/index')
temporaryIndexFile = os.environ.get('GIT_DIR', '.git') + \
                     '/merge-recursive-tmp-index'
def setupIndex(temporary):
    try:
        os.unlink(temporaryIndexFile)
    except OSError:
        pass
    if temporary:
        newIndex = temporaryIndexFile
        os.environ
    else:
        newIndex = originalIndexFile
    os.environ['GIT_INDEX_FILE'] = newIndex

def merge(h1, h2, branch1Name, branch2Name, graph, callDepth=0):
    '''Merge the commits h1 and h2, return the resulting virtual
    commit object and a flag indicating the cleaness of the merge.'''
    assert(isinstance(h1, Commit) and isinstance(h2, Commit))
    assert(isinstance(graph, Graph))

    def infoMsg(*args):
        sys.stdout.write('  '*callDepth)
        printList(args)
    infoMsg('Merging:')
    infoMsg(h1)
    infoMsg(h2)
    sys.stdout.flush()

    ca = getCommonAncestors(graph, h1, h2)
    infoMsg('found', len(ca), 'common ancestor(s):')
    for x in ca:
        infoMsg(x)
    sys.stdout.flush()

    Ms = ca[0]
    for h in ca[1:]:
        [Ms, ignore] = merge(Ms, h,
                             'Temporary shared merge branch 1',
                             'Temporary shared merge branch 2',
                             graph, callDepth+1)
        assert(isinstance(Ms, Commit))

    if callDepth == 0:
        setupIndex(False)
        cleanCache = False
    else:
        setupIndex(True)
        runProgram(['git-read-tree', h1.tree()])
        cleanCache = True

    [shaRes, clean] = mergeTrees(h1.tree(), h2.tree(), Ms.tree(),
                                 branch1Name, branch2Name,
                                 cleanCache)

    if clean or cleanCache:
        res = Commit(None, [h1, h2], tree=shaRes)
        graph.addNode(res)
    else:
        res = None

    return [res, clean]

getFilesRE = re.compile(r'^([0-7]+) (\S+) ([0-9a-f]{40})\t(.*)$', re.S)
def getFilesAndDirs(tree):
    files = Set()
    dirs = Set()
    out = runProgram(['git-ls-tree', '-r', '-z', tree])
    for l in out.split('\0'):
        m = getFilesRE.match(l)
        if m:
            if m.group(2) == 'tree':
                dirs.add(m.group(4))
            elif m.group(2) == 'blob':
                files.add(m.group(4))

    return [files, dirs]

class CacheEntry:
    def __init__(self, path):
        class Stage:
            def __init__(self):
                self.sha1 = None
                self.mode = None
        
        self.stages = [Stage(), Stage(), Stage()]
        self.path = path

unmergedRE = re.compile(r'^([0-7]+) ([0-9a-f]{40}) ([1-3])\t(.*)$', re.S)
def unmergedCacheEntries():
    '''Create a dictionary mapping file names to CacheEntry
    objects. The dictionary contains one entry for every path with a
    non-zero stage entry.'''

    lines = runProgram(['git-ls-files', '-z', '--unmerged']).split('\0')
    lines.pop()

    res = {}
    for l in lines:
        m = unmergedRE.match(l)
        if m:
            mode = int(m.group(1), 8)
            sha1 = m.group(2)
            stage = int(m.group(3)) - 1
            path = m.group(4)

            if res.has_key(path):
                e = res[path]
            else:
                e = CacheEntry(path)
                res[path] = e
                
            e.stages[stage].mode = mode
            e.stages[stage].sha1 = sha1
        else:
            die('Error: Merge program failed: Unexpected output from', \
                'git-ls-files:', l)
    return res

def mergeTrees(head, merge, common, branch1Name, branch2Name,
               cleanCache):
    '''Merge the trees 'head' and 'merge' with the common ancestor
    'common'. The name of the head branch is 'branch1Name' and the name of
    the merge branch is 'branch2Name'. Return a tuple (tree, cleanMerge)
    where tree is the resulting tree and cleanMerge is True iff the
    merge was clean.'''
    
    assert(isSha(head) and isSha(merge) and isSha(common))

    if common == merge:
        print 'Already uptodate!'
        return [head, True]

    if cleanCache:
        updateArg = '-i'
    else:
        updateArg = '-u'

    runProgram(['git-read-tree', updateArg, '-m', common, head, merge])
    cleanMerge = True

    [tree, code] = runProgram('git-write-tree', returnCode=True)
    tree = tree.rstrip()
    if code != 0:
        [files, dirs] = getFilesAndDirs(head)
        [filesM, dirsM] = getFilesAndDirs(merge)
        files.union_update(filesM)
        dirs.union_update(dirsM)
        
        cleanMerge = True
        entries = unmergedCacheEntries()
        for name in entries:
            if not processEntry(entries[name], branch1Name, branch2Name,
                                files, dirs, cleanCache):
                cleanMerge = False
                
        if cleanMerge or cleanCache:
            tree = runProgram('git-write-tree').rstrip()
        else:
            tree = None
    else:
        cleanMerge = True

    return [tree, cleanMerge]

def processEntry(entry, branch1Name, branch2Name, files, dirs, cleanCache):
    '''Merge one cache entry. 'files' is a Set with the files in both of
    the heads that we are going to merge. 'dirs' contains the
    corresponding data for directories. If 'cleanCache' is True no
    non-zero stages will be left in the cache for the path
    corresponding to the entry 'entry'.'''

# cleanCache == True  => Don't leave any non-stage 0 entries in the cache and
#                        don't update the working directory
#               False => Leave unmerged entries and update the working directory

# clean     == True  => non-conflict case
#              False => conflict case

# If cleanCache == False then the cache shouldn't be updated if clean == False

    def updateFile(clean, sha, mode, path, onlyWd=False):
        updateCache = not onlyWd and (cleanCache or (not cleanCache and clean))
        updateWd = onlyWd or (not cleanCache and clean)

        if updateWd:
            prog = ['git-cat-file', 'blob', sha]
            if stat.S_ISREG(mode):
                try:
                    os.unlink(path)
                except OSError:
                    pass
                if mode & 0100:
                    mode = 0777
                else:
                    mode = 0666
                fd = os.open(path, os.O_WRONLY | os.O_TRUNC | os.O_CREAT, mode)
                proc = subprocess.Popen(prog, stdout=fd)
                proc.wait()
                os.close(fd)
            elif stat.S_ISLNK(mode):
                linkTarget = runProgram(prog)
                os.symlink(linkTarget, path)
            else:
                assert(False)

        if updateWd and updateCache:
            runProgram(['git-update-index', '--add', '--', path])
        elif updateCache:
            runProgram(['git-update-index', '--add', '--cacheinfo',
                        '0%o' % mode, sha, path])

    def removeFile(clean, path):
        if cleanCache or (not cleanCache and clean):
            runProgram(['git-update-index', '--force-remove', '--', path])

        if not cleanCache and clean:
            try:
                os.unlink(path)
            except OSError, e:
                if e.errno != errno.ENOENT and e.errno != errno.EISDIR:
                    raise

    def uniquePath(path, branch):
        newPath = path + '_' + branch
        suffix = 0
        while newPath in files or newPath in dirs:
            suffix += 1
            newPath = path + '_' + branch + '_' + str(suffix)
        files.add(newPath)
        return newPath

    debug('processing', entry.path, 'clean cache:', cleanCache)

    cleanMerge = True

    path = entry.path
    oSha = entry.stages[0].sha1
    oMode = entry.stages[0].mode
    aSha = entry.stages[1].sha1
    aMode = entry.stages[1].mode
    bSha = entry.stages[2].sha1
    bMode = entry.stages[2].mode

    assert(oSha == None or isSha(oSha))
    assert(aSha == None or isSha(aSha))
    assert(bSha == None or isSha(bSha))

    assert(oMode == None or type(oMode) is int)
    assert(aMode == None or type(aMode) is int)
    assert(bMode == None or type(bMode) is int)

    if (oSha and (not aSha or not bSha)):
    #
    # Case A: Deleted in one
    #
        if (not aSha     and not bSha) or \
           (aSha == oSha and not bSha) or \
           (not aSha     and bSha == oSha):
    # Deleted in both or deleted in one and unchanged in the other
            if aSha:
                print 'Removing ' + path
            removeFile(True, path)
        else:
    # Deleted in one and changed in the other
            cleanMerge = False
            if not aSha:
                print 'CONFLICT (del/mod): "' + path + '" deleted in', \
                      branch1Name, 'and modified in', branch2Name, \
                      '. Version', branch2Name, ' of "' + path + \
                      '" left in tree'
                mode = bMode
                sha = bSha
            else:
                print 'CONFLICT (mod/del): "' + path + '" deleted in', \
                      branch2Name, 'and modified in', branch1Name + \
                      '. Version', branch1Name, 'of "' + path + \
                      '" left in tree'
                mode = aMode
                sha = aSha

            updateFile(False, sha, mode, path)
    
    elif (not oSha and aSha     and not bSha) or \
         (not oSha and not aSha and bSha):
    #
    # Case B: Added in one.
    #
        if aSha:
            addBranch = branch1Name
            otherBranch = branch2Name
            mode = aMode
            sha = aSha
            conf = 'file/dir'
        else:
            addBranch = branch2Name
            otherBranch = branch1Name
            mode = bMode
            sha = bSha
            conf = 'dir/file'
    
        if path in dirs:
            cleanMerge = False
            newPath = uniquePath(path, addBranch)
            print 'CONFLICT (' + conf + \
                  '): There is a directory with name "' + path + '" in', \
                  otherBranch + '. Adding "' + path + '" as "' + newPath + '"'

            removeFile(False, path)
            path = newPath
        else:
            print 'Adding "' + path + '"'

        updateFile(True, sha, mode, path)
    
    elif not oSha and aSha and bSha:
    #
    # Case C: Added in both (check for same permissions).
    #
        if aSha == bSha:
            if aMode != bMode:
                cleanMerge = False
                print 'CONFLICT: File "' + path + \
                      '" added identically in both branches,', \
                      'but permissions conflict', '0%o' % aMode, '->', \
                      '0%o' % bMode
                print 'CONFLICT: adding with permission:', '0%o' % aMode

                updateFile(False, aSha, aMode, path)
            else:
                # This case is handled by git-read-tree
                assert(False)
        else:
            cleanMerge = False
            newPath1 = uniquePath(path, branch1Name)
            newPath2 = uniquePath(path, branch2Name)
            print 'CONFLICT (add/add): File "' + path + \
                  '" added non-identically in both branches.'
            removeFile(False, path)
            updateFile(False, aSha, aMode, newPath1)
            updateFile(False, bSha, bMode, newPath2)

    elif oSha and aSha and bSha:
    #
    # case D: Modified in both, but differently.
    #
        print 'Auto-merging', path 
        orig = runProgram(['git-unpack-file', oSha]).rstrip()
        src1 = runProgram(['git-unpack-file', aSha]).rstrip()
        src2 = runProgram(['git-unpack-file', bSha]).rstrip()
        [out, ret] = runProgram(['merge',
                                 '-L', branch1Name + '/' + path,
                                 '-L', 'orig/' + path,
                                 '-L', branch2Name + '/' + path,
                                 src1, orig, src2], returnCode=True)

        if aMode == oMode:
            mode = bMode
        else:
            mode = aMode

        sha = runProgram(['git-hash-object', '-t', 'blob', '-w',
                          src1]).rstrip()

        if ret != 0:
            cleanMerge = False
            print 'CONFLICT (content): Merge conflict in "' + path + '".'

            if cleanCache:
                updateFile(False, sha, mode, path)
            else:
                updateFile(True, aSha, aMode, path)
                updateFile(False, sha, mode, path, True)
        else:
            updateFile(True, sha, mode, path)

        os.unlink(orig)
        os.unlink(src1)
        os.unlink(src2)
    else:
        die("ERROR: Fatal merge failure, shouldn't happen.")

    return cleanMerge

def usage():
    die('Usage:', sys.argv[0], ' <base>... -- <head> <remote>..')

# main entry point as merge strategy module
# The first parameters up to -- are merge bases, and the rest are heads.
# This strategy module figures out merge bases itself, so we only
# get heads.

if len(sys.argv) < 4:
    usage()

for nextArg in xrange(1, len(sys.argv)):
    if sys.argv[nextArg] == '--':
        if len(sys.argv) != nextArg + 3:
            die('Not handling anything other than two heads merge.')
        try:
            h1 = firstBranch = sys.argv[nextArg + 1]
            h2 = secondBranch = sys.argv[nextArg + 2]
	except IndexError:
            usage()
        break

print 'Merging', h1, 'with', h2

try:
    h1 = runProgram(['git-rev-parse', '--verify', h1 + '^0']).rstrip()
    h2 = runProgram(['git-rev-parse', '--verify', h2 + '^0']).rstrip()

    graph = buildGraph([h1, h2])

    [res, clean] = merge(graph.shaMap[h1], graph.shaMap[h2],
                         firstBranch, secondBranch, graph)

    print ''
except:
    traceback.print_exc(None, sys.stderr)
    sys.exit(2)

if clean:
    sys.exit(0)
else:
    sys.exit(1)
