#! /usr/bin/env python

import re
import subprocess
import glob
import os
import sys

# Methods
def printAll(lines):
    for line in lines:
        print (line)

def buildG(lines):
    gs = {} 
    for line in lines:
        if 'G-Group:' in line:
            a = map(int,re.findall(r'\d+',line))
            gs[a[0]] = a[1]
    return gs

def getC(lines):
    for line in lines:
        if 'Plan cost:' in line:
            return map(int,re.findall(r'\d+',line))[0]
            

def runFMM(command):
    p = subprocess.Popen(command, stdout=subprocess.PIPE, shell=False)
    outs, errs = p.communicate()
    if errs is not None:
        errlines = errs.splitlines()
        printAll(errlines)
        print 'Error Occurred = true'
        exit(1)
    else: 
        return (getC(outs.splitlines()),buildG(outs.splitlines()))

def dual(i,c):
    return c-i;

def sumStates(a,b,groups):
    result = 0
    for x in range(a,b):
        result += groups.get(x,0)
    return result

            
            
# Initialize
print('Program is running ...')

# Variables
problem = '/driverlog/p01.pddl' if len(sys.argv) < 2 else '/' + sys.argv[1]
algo = 'lmcut' if len(sys.argv) < 3 else sys.argv[2]
fd = os.getenv('DOWNWARD_REPO')
benchmark = os.getenv('DOWNWARD_BENCHMARKS') #('MASTER_BENCHMARK')
command = [ fd + '/fast-downward.py']
command2 = [fd + '/returnArgs.py']
fmmF = ['--search', 'fmm('+algo+', b_eval='+algo+'(transform=backward), p=1, print_g_groups=true)']
fmmB = ['--search', 'fmm('+algo+', b_eval='+algo+'(transform=backward), p=0, print_g_groups=true)']
fullCommand = command + [benchmark + problem] + fmmF

print('Running forward search..')
cF, gF = runFMM(fullCommand + fmmF)
print(gF)

print('Running backward search..')
cB, gB = runFMM(fullCommand + fmmB)
print(gB)

if cB != cF:
    print('Warning: ' + str(cF) + ' != ' + str(cB))
    exit(1)
else:
    print('C* = ' + str(cF))
    c = cF

if c is None:
    print 'Error Occurred = true'
    exit(1)
    

print('Computing different vertex covers..')
i = 0
i_min = 0
j = dual(i,c)
WVC = sumStates(0,i,gF) + sumStates(0,j,gB)
minWVC = WVC
print 'WVC (' + str('%.2f'% ((1.0*i)/c)) + '): ' + str(WVC)
while i < c:
    WVC += sumStates(i,i+1,gF)
    WVC -= sumStates(j-1,j,gB)
    i += 1
    j -= 1
    print 'WVC (' + str('%.2f'% ((1.0*i)/c)) + '): ' + str(WVC)
    if WVC < minWVC:
        minWVC = WVC
        i_min = i
print 'WVC = ' + str(minWVC)
print 'p* = ' + str((1.0*i_min)/c)


print('Program is finished!')
