#end times in all files must be the same!!

import glob
import re

#GET RUN NAMES
runNames = glob.glob('*.rep')
#GET TRACESTATE OBJECT NAMES
traceObjects = ['BPBerth1','BPBerth2']
#STATES THAT EXIST FOR OCCUPIED -- INCLUDES KICKED OFF BERTH STATES AS WELL
states = ['Wait to Handle','Handling delay - RampUp','Handling','Handling delay - RampDown',
          'Clear Berth','Wait for Conditions to Approach Berth','Wait for Conditions to Clear Berth','Approach Berth']

#THIS PYTHON FILE NEEDS TO BE IN THE SAME DIRECTORY AS REP AND TRACE STATE FILES
#THIS FILE GRABS RUN NAMES FROM THE REP FILE AND ADDS traceObjects to the end
def main():
    overlapOccupied = 0.0
    Dict1 = []
    data = [[],[]]
    combined = []
    #something in this loop screws up the array, causes the data to create an array within an array
    for run in runNames:
        Dict1 = []
        for i in range(len(traceObjects)):
            with open('./'+run[:-4]+'-'+traceObjects[i]+'.trc') as fread:
                alllines = []
                alllines = fread.readlines()
                for lines in alllines:
                    data[i].append(lines)
        #grab the last array because it contains all the data appended
        Dict1 = parseData(data[0])
        Dict2 = parseData(data[1])
        Dict3 = Dict1+Dict2
    #berth1Occupied = getOccupied(Dict1,traceObjects[0])
    #berth2Occupied = getOccupied(Dict2,traceObjects[1])
    berth1Occupied = getOccupiedTime(Dict3,traceObjects[0])
    berth2Occupied = getOccupiedTime(Dict3,traceObjects[1])
    #sort based on start time
    sortedData = sorted(Dict3)
    #PERCENTAGE OF TIME THAT BOTH BERTHS ARE OCCUPIED
    for i in range(len(sortedData)):
        #if the two lines are the same berth, cannot overlap
        if (i == len(sortedData)-1) or sortedData[i+1][4] == 'end':
            pass
        elif (sortedData[i][2]==sortedData[i+1][2]):
            pass
        #end1 >= start2 and end2 >= start1: if true: overlap
        elif (sortedData[i][3]>=sortedData[i+1][0] and sortedData[i+1][3]>=sortedData[i][0]):
            #overlap
            #first berth found encapsulates second berth found
            #end2-start2
            if (sortedData[i][3]>=sortedData[i+1][3]):
                overlapOccupied += sortedData[i+1][3]-sortedData[i+1][0]
                print str(overlapOccupied)+'end2-start2\n'
            #second berth ends later: end1-start2
            elif (sortedData[i+1][3]>sortedData[i][3]):
                overlapOccupied += sortedData[i][3]-sortedData[i+1][0]
                print str(overlapOccupied)+'end1-start2\n'
            else:
                #because the data is sorted, the other two scenarios cannot happen
                #error out here
                print 'some random case'
    print sortedData
    print overlapOccupied
    print Dict3[-1][3]
    writer = open(run[:-4]+'-occupied'+'.trc','w')
    writer.write('Percentage Occupied')
    writer.write('\n'+traceObjects[0]+' Occupied: '+str(berth1Occupied)+'\t'+'%')
    writer.write('\n'+traceObjects[1]+' Occupied: '+str(berth2Occupied)+'\t'+'%')
    writer.write('\n'+'Both Berths Occupied at the same time: '+str(overlapOccupied/Dict3[-1][3]*100)+'\t'+'%')

#create temporary data to add times up
#TRACE STATE FILES ARE ALWAYS OUTPUT IN THE REGEX BELOW -- UPDATE IF THE OUTPUT CHANGES
def parseData(data):
    timeOccupied = 0.0
    startTime = 0.0
    endTime = 0.0
    #newEndTime used to check to make sure the math is correct
    newEndTime = 0.0
    berth = ''
    occupied = False
    myDict = [['Time','Berth','Duration','EndTime','TimeEndTime']]
    preHandle = 'Pre-Handling Time'
    postHandle = 'Post-Handling Time'
    for i in range(len(data)):
        searchFound = re.match('([0-9.]+)  (BPBerth[12]).setState\( "([a-zA-Z -0-9]+)" \) dt = ([0-9.]+)',data[i])
        if i != len(data)-1:
            searchNextLine = re.match('([0-9.]+)  (BPBerth[12]).setState\( "([a-zA-Z -0-9]+)" \) dt = ([0-9.]+)',data[i+1])
            if searchFound.group(2) != searchNextLine.group(2):
                occupied = False
        if (searchFound and searchFound.group(3)==preHandle): 
            if occupied:
                timeOccupied += float(searchFound.group(4))
            else:
                timeOccupied = float(searchFound.group(4))
                startTime = float(searchFound.group(1))
                occupied = True
                berth=searchFound.group(2)
        elif (occupied and (searchFound and (searchFound.group(3)==postHandle))):
            searchConditions = re.match('([0-9.]+)  (BPBerth[12]).setState\( "([a-zA-Z -0-9]+)" \) dt = ([0-9.]+)',data[i+1])
            if (searchConditions and searchConditions.group(3)==states[6]):
                timeOccupied += float(searchConditions.group(4)) + float(searchFound.group(4))
                newEndTime = float(searchConditions.group(1)) + float(searchConditions.group(4))
            else:
                timeOccupied += float(searchFound.group(4))
                newEndTime = float(searchFound.group(1)) + float(searchFound.group(4))
            myDict.append([startTime,berth,timeOccupied,startTime+timeOccupied,newEndTime])
            occupied = False
        elif (occupied and (searchFound and (searchFound.group(3) in states))):
            timeOccupied += float(searchFound.group(4))
        if (i==len(data)-1 and searchFound.group(3) in states and occupied):
            myDict.append([startTime,berth,timeOccupied,startTime+timeOccupied,newEndTime])
            occupied = False
            myDict.append([float(searchFound.group(1)),searchFound.group(2),float(searchFound.group(4)),float(searchFound.group(1))+float(searchFound.group(4)),'end'])
        elif (i==len(data)-1):
            myDict.append([float(searchFound.group(1)),searchFound.group(2),float(searchFound.group(4)),float(searchFound.group(1))+float(searchFound.group(4)),'end'])
            occupied = False
    return myDict

#AS LONG AS parseData(data) IS USED, DATA WILL BE IN THE FORMAT BELOW TO ADD UP TIME OCCUPIED AND DIVIDE BY END TIME
def getOccupiedTime(myData, myObject):
    sumOccupied = 0
    for i in myData:
        if (isinstance(i[0], float) and i[1] == myObject and (i[4] != 'end')):
            sumOccupied += i[2]
    lastLine = myData[-1]
    percentOccupied = sumOccupied/(lastLine[0]+lastLine[2])*100
    return percentOccupied
            
def 
