# Create json interface file using mapping rules from idocmapin.txt

import os
import time
import datetime
import json
from collections import OrderedDict

# Get Current Path
dir_path = os.path.dirname(os.path.realpath(__file__))

def jsonAdd(key, segments, status):
	e = 0
# if key is Blank add to Main Segment
	if key == "":
		for segment in segments:
			try:
				jsonMain[segment.split(";")[0]] = segment.split(";")[1]
			except:
				e=e+1
	else:
# Create Associative Dictionary for JSON segment
#		jsonSegment = {}
		jsonSegment = OrderedDict()
		jsonSegment.clear()
#		del jsonSegment[:]
		for segment in segments:
			try:
				jsonSegment[segment.split(";")[0]] = segment.split(";")[1]
			except:
				e=e+1
# Add Segment to Main JSON
		if status == "new":
			if key not in jsonMain:
				if key == "nmukbporBody":
					jsonMain[key] = [jsonSegment]
				elif key == "vimsorderBody":
					jsonMain[key] = [jsonSegment]
				else:
					jsonMain[key] = jsonSegment
#				print("TEST1"+str(jsonMain)+"-"+str(segment))
			elif type(jsonMain[key]) == list:
				jsonMain[key].append(jsonSegment)
#				print("TEST2"+str(jsonMain)+"-"+str(segment))
			elif key == "nmukbporBody":
				jsonMain[key] = [jsonMain[key], jsonSegment]
			elif key == "vimsorderBody":
				jsonMain[key] = [jsonMain[key], jsonSegment]
#				print("TEST3"+str(jsonMain)+"-"+str(segment))
			else:
				jsonMain[key] = [jsonMain[key], jsonSegment]
#				print("TEST4"+str(jsonMain)+"-"+str(segment))
		else:
			if key not in jsonMain:
				jsonMain[key] = jsonSegment
			elif type(jsonMain[key]) == list:
				jsonMain[key].append(jsonSegment)
			else:
				try:
					del jsonSegment['SEGNAM']
				except:
					e=e+1
				jsonMain[key].update(jsonSegment)
#	print("main:"+str(jsonMain))
	
# Main Processing
def main():
    mapSegment = []
    mapLength = []
    mapMap = []

    segments = []
    outSegments = []

    jsonMain = OrderedDict()
	
# Read IDOC Mapping Values
    file_path_map = os.path.join(dir_path, 'idocmapin.txt')
    iDocMap = open(file_path_map,"r")
# for each line split out segment(eg.HDSUPPORDR), line length in chars.(eg.0039), segment field mapping.
    for line in iDocMap:
        line = line.replace('\n','')
        mapSegment.append(line.split(":")[0])
        mapLength.append(line.split(":")[1])
        mapMap.append(line.split(":")[2])
    iDocMap.close()
	
# Read IDOC Transaction
    file_path = os.path.join(dir_path, 'idoctranin.txt')
    iDocTran = open(file_path,"r")
    l = 0
    outSegments.clear()
#	del outSegments[:]
    lineType = ""
    segmentType = ""
# Read lines from the input message file - for each line:
    for line in iDocTran:
        line = line.replace('\n','')
        line = line.replace(',',' ')
#		print("LINE:"+line)
        offset = 0
# loop through all the characters in the message line to try & find a segment id.
        while len(line) > offset:
            segment = line[offset:offset+7]
            if (l == 0):
                if segment[0:6] == "TABNAM":
                    return False
# format segment from NMUK Message
            if segment[0:2] == "HD":
# get the segment name from the input message (eg. SUPPORDR)
                segment = "HD"+line[offset+10:offset+18]
                segmentType = line[offset+10:offset+18]
                lineType = "HD"
#				print("SEGMENT:"+segment+":"+segmentType)
            elif segment[0:2] == "DT":
                segment = "DT"+segmentType;
                lineType = "DT"
#				print("SEGMENT:"+segment+":"+segmentType)
            elif segment[0:2] == "FT":
                segment = "FT"+segmentType;
                lineType = "FT"
#				print("SEGMENT:"+segment+":"+segmentType)
# Look for matching Segment in Mapping List
            segmentFound = False
            i = 0
            while i < len(mapSegment) and segmentFound == False:
                if len(segment) > 0:
                    if segment.strip() == mapSegment[i].strip():						
#						print("MAPSEGMENT:"+segment+":"+mapSegment[i])
                        segments.append(segment)
                        segmentFound = True
                        firstPos = 0
                        lastPos = 0
                        detailStr = ""
# Split-out segment line from input string
                        segStr = line[offset:offset+int(mapLength[i])]
# Split-out Fields Mapping into array mapDetail - 0=name;1=start_position (or +);2=length;3=JSON_name)
                        mapDetail = mapMap[i].split(";")
#						print("MAPDETAIL:"+str(mapDetail))
                        d = 0
# Read through the mapping entries
                        while d < len(mapDetail):
# get field starting position in segment string
                            if mapDetail[d+1] == "+":
                                firstPos = lastPos
                            else:
                                firstPos = int(mapDetail[d+1])
# Check is Segment is to be included (not = '*' and not ending in ')')
                            if len(mapDetail) > d+2 and mapDetail[d+3] != "*" and mapDetail[d+3][-1:] != ")":
# if detailStr contains data - add ',' to the end before adding next segment
                                if len(detailStr) > 0:
                                    detailStr = detailStr+","
# add formatted segment detail to comma-seperared output string - as JSON_name;message_value								
                                if len(segStr) > firstPos:
                                    if mapDetail[d+3] != "" and mapDetail[d+3][-1:] != ")":
                                        detailStr = detailStr+mapDetail[d+3]+";"+segStr[firstPos:firstPos+int(mapDetail[d+2])]
                                    else:
                                        detailStr = detailStr+mapDetail[d]+";"+segStr[firstPos:firstPos+int(mapDetail[d+2])]
                                else:
                                    if mapDetail[d+3] != "" and mapDetail[d+3][-1:] != ")":
                                        detailStr = detailStr+mapDetail[d+3]+";"+segStr[firstPos:len(detailStr)]
                                    else:
                                        detailStr = detailStr+mapDetail[d]+";"+segStr[firstPos:len(detailStr)]
# store the last position to use as the first position of the next segment						
                            if len(mapDetail) > d+2:
                                lastPos = firstPos+int(mapDetail[d+2])
                            else:
                                lastPos = len(mapDetail)
# set index 'd' to the next set of segment mappings in array mapDetail
                            d = d+4
# Store formatted Segments
                        outSegments.append(detailStr)
# increment the message offset to position to the start of the next message                    
                        offset = offset+int(mapLength[i])
                i = i+1
# if no matching segment was found offset to the next character in the message
            if segmentFound == False:
                offset = offset+1
#		print("OUT:"+segment+":"+segmentType+":"+lineType+":"+str(outSegments))
        if (lineType == "FT" or lineType == ""):
# Create JSON Message Format
            i = 0
            e = 0
            jsonMain.clear()
#			del jsonMain[:]
# Split-out Message Segments
            print("OUT:",outSegments)
            while i < len(outSegments):
                segments = outSegments[i].split(",")
                if len(segments) > 0 and len(segments[0]) > 0:
                    key = segments[0].split(";")[1]
            #					print("KEY:"+key)
                    if key == "E2EDL24":
                        key = "receiptBody"
                    elif key == "E2EDL52":
                        key = "receiptBody"
                    elif key == "Z2EDL20":
                        key = "receiptBody"
                    elif key == "Z2EDL24":
                        key = "receiptBody"
                    elif key == "E2EDL20":
                        key = "receiptHeader"
                    elif key == "E2LTORH":
                        key = "vimsorderHeader"
                    elif key == "Z2LTORH":
                        key = "vimsorderBody"
                    elif key == "E2LTORI":
                        key = "vimsorderBody"
                    elif key == "HD":
                        if (segmentType.strip().lower() == "vimsor"):
                            key = "vimsorderHeader"
                        else:
                            key = segmentType.strip().lower()+"Header"
                    elif key == "DT":
                        if (segmentType.strip().lower() == "vimsor"):
                            key = "vimsorderBody"
                        else:
                            key = segmentType.strip().lower()+"Body"
                    elif key == "FT":
                        if (segmentType.strip().lower() == "vimsor"):
                            key = "vimsorderFooter"
                        else:
                            key = segmentType.strip().lower()+"Footer"
# Call Function to Format to JSON
                    if segments[0].split(";")[0].lower() != "segnam" or (segments[0].split(";")[0].lower() == "segnam" and len(segments) > 1):
#						jsonAdd(key, segments, "new")
                        e = 0
                        status = "new"
# if key is Blank add to Main Segment
                        if key == "":
                            for segment in segments:
                                try:
                                    jsonMain[segment.split(";")[0]] = segment.split(";")[1]
                                except:
                                    e=e+1
                        else:
# Create Associative Dictionary for JSON segment
#							jsonSegment = {}
                            jsonSegment = OrderedDict()
                            jsonSegment.clear()
#							del jsonSegment[:]
                            for segment in segments:
                                try:
                                    jsonSegment[segment.split(";")[0]] = segment.split(";")[1]
                                except:
                                    e=e+1
# Add Segment to Main JSON
                            if status == "new":
                                if key not in jsonMain:
                                    if key == "nmukbporBody":
                                        jsonMain[key] = [jsonSegment]
                                    elif key == "vimsorderBody":
                                        jsonMain[key] = [jsonSegment]
                                    else:
                                        jsonMain[key] = jsonSegment
            #									print("TEST1"+str(jsonMain)+"-"+str(segment))
                                elif type(jsonMain[key]) == list:
                                    jsonMain[key].append(jsonSegment)
            #								print("TEST2"+str(jsonMain)+"-"+str(segment))
                                elif key == "nmukbporBody":
                                    jsonMain[key] = [jsonMain[key], jsonSegment]
                                elif key == "vimsorderBody":
                                    jsonMain[key] = [jsonMain[key], jsonSegment]
            #								print("TEST3"+str(jsonMain)+"-"+str(segment))
                                else:
                                    jsonMain[key] = [jsonMain[key], jsonSegment]
            #								print("TEST4"+str(jsonMain)+"-"+str(segment))
                            else:
                                if key not in jsonMain:
                                    jsonMain[key] = jsonSegment
                                elif type(jsonMain[key]) == list:
                                    jsonMain[key].append(jsonSegment)
                                else:
                                    try:
                                        del jsonSegment['SEGNAM']
                                    except:
                                        e=e+1
                                    jsonMain[key].update(jsonSegment)
                i = i+1
            outSegments.clear();
#			del outSegments[:]

            print("JSON:"+json.dumps(jsonMain, ensure_ascii=False, indent=2))
# Create Message File
            ts = time.time()
            ts = datetime.datetime.fromtimestamp(ts).strftime('_%Y%m%d_%H%M%S_')
            l = l+1
            if (segmentType != ""):
#				jsonFile = segmentType.strip()+"MSGIN"+str(ts)+str(l)+".json"
                jsonFile = "IDOCMSGIN"+str(l)+".json"
            else:
                jsonFile = "IDOCMSGIN"+str(l)+".json"
            file_path_json = jsonFile
            with open(file_path_json, "w") as write_file:
                json.dump(jsonMain, write_file, indent=2)
            jsonMain.clear()
#			del jsonMain[:]
#			segmentType = ""
    if (outSegments):
        del outSegments
    try:
        if (jsonSegment):
            del jsonSegment
    except:
        pass
    if (jsonMain):
        del jsonMain
        
    iDocTran.close()

    return True

if __name__ == '__main__':
    main()