#! /usr/bin/python

import sys

def get_task_list(label):
    """Return an integer list of tasks from an edge label."""
    task_list = []
    current = 0
    in_range = False
    range_start = -1
    for char in label:
        if char.isdigit():
            current = current * 10 + int(char)
        elif char == '-':
            range_start = current
            current = 0
            in_range = True
        elif char == ',' or char == ']':
            if in_range:
                range_end = current
                for i in range(range_start, range_end + 1):
                    task_list.append(i)
            else:
                task_list.append(current)
            if char == ']':
                break
            in_range = False
            current = 0
            range_start = -1
    return task_list

def get_word_bit(task):
    global word_size
    word = task / word_size
    bit = task % word_size
    return word, bit

def add_task(word_list, task):
    word, bit = get_word_bit(task)
    word_list[word] = word_list[word] | (1 << bit)

def list_contains_task(word_list, task):
    word, bit = get_word_bit(task)
    element = word_list[word] 
    if element & (1 << bit) == (1 << bit):
        return True
    return False

if len(sys.argv) != 3:
    print '\nThis script reads a dot file generated by STAT and returns a list of tasks that do not have a stack trace'
    print '\nUSAGE:\n\t[python] dot_missing_tasks.py <dot_file> <job_size>\n'
    sys.exit(1)

filename = sys.argv[1]
job_size = int(sys.argv[2])

f = open(filename, 'r')
lines = f.readlines()
whole_list = []
missing = []
word_size = 30
num_words = job_size / word_size
if job_size % word_size != 0:
    num_words += 1
for i in range(num_words):
    whole_list.append(0)

for line in lines:
    if line.find('->') != -1 and line.find('label="[') != -1:
        label = line[line.find('label="[') + 7:line.find(']"') + 1]
        list = get_task_list(label)
        for task in list:
            add_task(whole_list, task)

for i in range (job_size):
    if list_contains_task(whole_list, i) == False:
        missing.append(i)

missing_string = '['
prev = -2
range = False
first = True

for i in missing:
    if i == prev + 1:
        range = True
    else:
        if range == True:
            missing_string += '-' + '%d'%prev
        if first == False:
            missing_string += ','
        missing_string += '%d'%i
        range = False
        first = False
    prev = i
if range == True:
    missing_string += '-%d'%prev
missing_string += ']'    

print missing_string
print 'total %d\n'%len(missing)
