#!/usr/bin/python3
#(C) 2015 Peter Michael Green <plugwash@debian.org>
#This software is provided 'as-is', without any express or implied warranty. In
#no event will the authors be held liable for any damages arising from the use
#of this software.
#
#Permission is granted to anyone to use this software for any purpose, including
#commercial applications, and to alter it and redistribute it freely, subject to
#the following restrictions:
#
#1. The origin of this software must not be misrepresented; you must not claim.
#that you wrote the original software. If you use this software in a product,
#an acknowledgment in the product documentation would be appreciated but is.
#not required.
#
#2. Altered source versions must be plainly marked as such, and must not be
#misrepresented as being the original software.
#
#3. This notice may not be removed or altered from any source distribution.

import sys
import re
import subprocess

filetofix = sys.argv[1]
tempdir = sys.argv[2]

f = open(filetofix,'rb')
lines = f.readlines()
f.close()

fd = open(tempdir+'/dtmp','wb')
fm = open(tempdir+'/mtmp','wb')
fu = open(tempdir+'/utmp','wb')


mode = 0; # 0: unconflicted text 1: downstream text 2: mergehead text 3: upstream text

downstream = set()
mergehead = set()
upstream = set()
deferred = []

def writesplitline(f,line):
	hasnewline = False
	if line[-1:] == b"\n":
		line = line[:-1]
		hasnewline = True
	#print(repr(line[-1:]))
	linesplit = re.match(rb'^(\s*[^\s]*)(.*)$',line).groups()
	
	f.write(b'[1]'+linesplit[0]+b"\n")
	f.write(b'[2]'+linesplit[1]+b"\n")
	if hasnewline:
		f.write(b'[3]'+linesplit[0]+b"\n")
	else:
		f.write(b'[3]'+linesplit[0])

#for stage in range(0,2):
for line in lines:
		#print(repr(line))
		if (line.startswith(b'<<<<<<< ')):
			if (mode == 0):
				mode = 1
				#print('found <<<<<<< switching to mode 1')
			else:
				print('broken diff3, unexpected <<<<<<<', file=sys.stderr)
				sys.exit(1);
		elif (line.startswith(b'||||||| ')):
			if (mode == 1):
				mode = 2
				#print('found ||||||| switching to mode 2')
			else:
				print('broken diff3, unexpected |||||||', file=sys.stderr)
				sys.exit(1);
		elif (line == b'=======\n'):
			if (mode == 2):
				mode = 3
				#print('found ======= switching to mode 3')
			else:
				print('broken diff3, unexpected =======', file=sys.stderr)
				sys.exit(1);
		elif (line.startswith(b'>>>>>>> ')):
			if (mode == 3):
				#print('found >>>>>>> switching to mode 0')
				mode = 0
			else:
				print('broken diff3, unexpected >>>>>>>', file=sys.stderr)
				sys.exit(1);
		else:
			if ((mode == 0) or (mode == 1)):
				writesplitline(fd,line)
			if ((mode == 0) or (mode == 2)):
				writesplitline(fm,line)
			if ((mode == 0) or (mode == 3)):
				writesplitline(fu,line)



fd.close()
fm.close()
fu.close()

command = ['merge',tempdir+'/dtmp',tempdir+'/mtmp',tempdir+'/utmp']
print(command, flush=True)
if (subprocess.call(command) != 0): 
    print('merge of processed files failed')
    sys.exit(1)

fd = open(tempdir+'/dtmp','rb')

l1 = b''
l2 = b''
l3 = b''

f = open(filetofix+'.new','wb')

for line in fd:
	hasnewline = False
	if line[-1:] == b"\n":
		line = line[:-1]
		hasnewline = True
	if line[:3] == b'[1]':
		l1 = line[3:]
	elif line[:3] == b'[2]':
		l2 = line[3:]
	elif line[:3] == b'[3]':
		l3 = line[3:]
		if (l1 != l3):
			print('l1 and l3 do not match in merge result')
			sys.exit(1)
		output = l1 + l2
		if hasnewline:
			output += b'\n';
		f.write(output)
	else:
		print('unexpected line in merge result')
		sys.exit(1)

f.close

command = ['mv',filetofix+'.new',filetofix]
print(command, flush=True)
if (subprocess.call(command) != 0): 
    print('moviing result into place failed')
    sys.exit(1)
