#!/usr/bin/python2.7

import argparse
import json
import os
import signal
import site
import sys
import subprocess

#=======================================================================================================================
FILE_NAME_UTCONFIG = "utconfig.json"
PATH_PROJECT_ROOT = os.path.join(os.path.realpath(os.path.dirname(__file__)), os.pardir)
PATH_UNITTEST_OUT = os.path.join(PATH_PROJECT_ROOT, 'ut-out')
PATH_UNITTEST_OUT_VAR = os.path.join(PATH_UNITTEST_OUT, 'var')
PATH_UNITTEST_OUT_VAR_LOG = os.path.join(PATH_UNITTEST_OUT_VAR, 'log')
PATH_UNITTEST_OUT_VAR_LOCK = os.path.join(PATH_UNITTEST_OUT_VAR,'lock')
PATH_UNITTEST_OUT_VAR_RUN = os.path.join(PATH_UNITTEST_OUT_VAR, 'run')

#=======================================================================================================================
def main():
    """ Entry point
    @return: 0 on success | 1 on failure
    """

    if not os.path.exists(PATH_UNITTEST_OUT): os.makedirs(PATH_UNITTEST_OUT)
    if not os.path.exists(PATH_UNITTEST_OUT_VAR_LOG): os.makedirs(PATH_UNITTEST_OUT_VAR_LOG)
    if not os.path.exists(PATH_UNITTEST_OUT_VAR_LOCK): os.makedirs(PATH_UNITTEST_OUT_VAR_LOCK)
    if not os.path.exists(PATH_UNITTEST_OUT_VAR_RUN): os.makedirs(PATH_UNITTEST_OUT_VAR_RUN)                

    # Load source path
    site.addsitedir(PATH_PROJECT_ROOT)
        
    # Argument's parse
    parser = argparse.ArgumentParser(description = "Unit tests runner")
    parser.add_argument('-d', 
                        '--directory', 
                        dest='directory', 
                        default = '.', 
                        help = "Path to directory which nests '%s' files within (default: '.')" % FILE_NAME_UTCONFIG,
                        metavar ="PATH")
    
    rawRunnerArgs = sys.argv
    rawTestArgs = []
    
    for i in xrange(0, len(rawRunnerArgs)):
        
        if rawRunnerArgs[i] == '--':
            rawTestArgs = rawRunnerArgs[(i+1):]
            rawRunnerArgs = rawRunnerArgs[:i]

            break
        
    parsedArgs = parser.parse_args(rawRunnerArgs[1:])
    testFilesPathsToRun = []
    
    # Search for utconfig files
    for (baseDir, _, fileNames) in os.walk(parsedArgs.directory):
        
        for fileName in fileNames:
            
            if fileName == FILE_NAME_UTCONFIG:
                    filePath = os.path.join(baseDir, fileName)
                    
                    with open(filePath, 'r') as utconfigFile:
    
                        for testFileName in json.load(utconfigFile):
                            testFilesPathsToRun.append(os.path.join(baseDir, testFileName))
                
    
    # Run all found utconfig files files
    testFailed = False
    process = None
    
    try:
        for testFilePath in testFilesPathsToRun:
            env = os.environ.copy()
            env['PYTHONPATH'] = os.path.pathsep.join(sys.path)[1:]
            env['UNITTEST_OUT'] = PATH_UNITTEST_OUT
            process = subprocess.Popen([sys.executable, testFilePath] + rawTestArgs, env = env)
            process.communicate()
            if not testFailed: testFailed = process.returncode == 0
            
        if testFailed:
    
            return 1

    except KeyboardInterrupt:
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        if process: process.communicate()
        
        return 1
        
    return 0

#=======================================================================================================================
if __name__ == '__main__': 
    sys.exit(main())