#!/usr/bin/python

from __future__ import with_statement
import roslib; roslib.load_manifest('rostest')

import sys
import os

import roslib.rosenv
import rostest.xmlresults as xmlr

print "------------------------------------------------------"
print "------------------------------------------------------"
print "------------------ STARTING EPIC FAIL ----------------"
print "------------------------------------------------------"
print "------------------------------------------------------"



def get_last_number(dir):
    max = 0
    for file in os.listdir(dir):
        if ((file[0] == '1' or file[0] == '2' or file[0] == '3'
             or file[0] == '4' or file[0] == '5' or file[0] == '6'
             or file[0] == '7' or file[0] == '8' or file[0] == '9')
            and file.find("_") != -1):
            num = file[0:file.find("_")]
            if (int(num) > max):
                max = int(num)

    return max

def limit_bag_file_number(bags_dir, result_name, bag_limit):
    result_bag_dir = os.path.join(bags_dir, result_name)
    try:
        n = get_last_number(result_bag_dir)
        while (n > bag_limit): #limit of bags
            print "Too many bags in", result_name, n
            for i in range(1, n + 1):
                input_file = os.path.join(result_bag_dir, 
                                          str(i) + "_" +  result_name + ".bag")
                output_file = os.path.join(result_bag_dir, 
                                           str(i - 1) + "_" +  result_name + ".bag")
                cmd = "mv " + input_file + " " + output_file
                os.system(cmd)
                n = get_last_number(result_bag_dir)
    except:
        pass

def delete_test_bags(raw_bags_dir, result_name):
    file = os.path.join(raw_bags_dir, result_name + ".bag")
    count = ""
    while (os.path.exists(file)):
        print "Removing bag file:", file
        os.system("rm " + file) #FIXME: don't use system commands
        count = count + "I"
        file = os.path.join(raw_bags_dir, result_name + count + ".bag")

def get_result_bag_dir(bags_dir, result_name):
    result_bag_dir = os.path.join(bags_dir, result_name)
    if (not os.path.exists(result_bag_dir)):
        os.makedirs(result_bag_dir)
    return result_bag_dir

def handle_test(base_test_name, file, test_dir):
    test_results_dir = roslib.rosenv.get_test_results_dir()
    raw_bags_dir = os.path.join(test_results_dir, "ros_epic_fail_raw_bags")
    bags_dir = os.path.join(test_results_dir, "ros_epic_fail_trapped_bags")

    if (os.getenv("ROS_EPIC_FAIL_BAGS_DIR")):
        bags_dir = os.getenv("ROS_EPIC_FAIL_BAGS_DIR").strip()
    print "Bags dir:", bags_dir

    test_name = base_test_name + '.' + file[:-4]
    file = os.path.join(test_dir, file)
    print "Test: ", file
    try:
        result = xmlr.read(file, test_name)
        print "Test name for trapper:", result.name #Used for the trapper.
        fail = (result.num_errors + result.num_failures) > 0
        file = os.path.join(raw_bags_dir, result.name + ".bag")
        retryfail = os.path.exists(os.path.join(raw_bags_dir, result.name + "I.bag")) #copy bags if a test fails, retries, and passes.
        if (fail or retryfail):
            if (retryfail):
                print "Detected failed retry test", test_name
            if (os.path.exists(file)):
                count = ""
                while (os.path.exists(file)):
                    print "Failure of", result.name
                    result_bag_dir = get_result_bag_dir(bags_dir, result.name)
                    n = get_last_number(result_bag_dir) + 1
                    output_file = os.path.join(result_bag_dir, 
                                               str(n) + "_" +  result.name + ".bag")
                    #FIXME: this is brittle
                    cmd = "mv \"" + file + "\" \"" + output_file + "\""
                    print "Moving: ", cmd
                    os.system(cmd)
                    count = count + "I"
                    file = os.path.join(raw_bags_dir, result.name + count + ".bag")
                    
            else:
                print "Failed, no bag for", result.name
                print "File = ", file
        else:
            print "Succeed, file = ", file
            delete_test_bags(raw_bags_dir, result.name)
                            
        limit_bag_file_number(bags_dir, result.name, 30)
                        
    except Exception, e:
        print >> sys.stderr, "ignoring [%s]: %s"%(file, e)


def epic_fail_main():
    test_results_dir = roslib.rosenv.get_test_results_dir()
    raw_bags_dir = os.path.join(test_results_dir, "ros_epic_fail_raw_bags")
    bags_dir = os.path.join(test_results_dir, "ros_epic_fail_trapped_bags")

    if (os.getenv("ROS_EPIC_FAIL_BAGS_DIR")):
        bags_dir = os.getenv("ROS_EPIC_FAIL_BAGS_DIR").strip()

    print "Bags directory:", bags_dir
        
    print "------------------------------------------------------"
    for d in os.listdir(test_results_dir):
        test_dir = os.path.join(test_results_dir, d)
        base_test_name = os.path.basename(test_dir)
        try:
            for file in os.listdir(test_dir):
                if file.endswith('.xml'):
                    handle_test(base_test_name, file, test_dir)
        except Exception, e:
            print >> sys.stderr, "ignoring [%s]: %s"%(test_dir, e)
    


    print "------------------------------------------------------"
    print "------------------------------------------------------"
    print "-------------------- DONE EPIC FAIL ------------------"
    print "------------------------------------------------------"
    print "------------------------------------------------------"


if(__name__ == "__main__"):
    epic_fail_main()
