import sys
import os
import glob
import re
import subprocess
import numpy

pyhst = None
excludes = None
new_pattern = None
old_pattern = None
rename_filenames = None
convert_filename = None
skiplines = None
prefix = None
simple_time_benchmark = None
flip_filenames = None
flipping = None

try:
    from PyMca import EdfFile
except ImportError:
    try:
        import EdfFile
    except ImportError:
        from . import EdfFile

index = 1
endindex = len(sys.argv)
while index < endindex:
    arg = sys.argv[index]
    index = index+1
    if arg == '-pyhst':
        pyhst= sys.argv[index]
        index = index+1
        print("PyHST: %s" % convert_filename)
    elif arg == '-convert':
        convert_filename= sys.argv[index]
        index = index+1
        print("Convert: %s" % convert_filename)
    elif arg == '-rename':
        rename_filenames= sys.argv[index]
        index = index+1
        old_pattern= sys.argv[index]
        index = index+1
        new_pattern= sys.argv[index]
        index = index+1
        print("Rename: %s from %s to %s"
               % (convert_filename, old_pattern, new_pattern) )
    elif arg == '-excludes':
        if excludes is None:
            excludes = []
        excludes.append(sys.argv[index])
        index = index+1
        print("Excluding: %s" % prefix)
    elif arg == '-simple-benchmark':
        simple_time_benchmark= sys.argv[index]
        index = index+1
        print("Benchmarking: %s" % simple_time_benchmark)
    elif arg == '-prefix':
        prefix= sys.argv[index]
        index = index+1
        print("Prefix: %s" % prefix)
    elif arg == '-skiplines':
        skiplines= int(sys.argv[index])
        index = index+1
        print("Skip lines: %d" % skiplines)
    elif arg == '-flip':
        flip_filenames= sys.argv[index]
        index = index+1
        flipping= sys.argv[index]
        index = index+1
        print("Flipping images: %s" % flip_filenames)
    else:
        print("Skipping argument: %s" % arg)

def convert(filenames):
    listOfNames = glob.glob(filenames)
    if excludes is not None:
        for excl in excludes:
            for excl_filename in glob.glob(excl):
                listOfNames.remove(excl_filename)

    for filename in listOfNames:
        slice = open(filename, 'r')
        outfilename = '.'.join(filename.split('.')[0:-1]) + '.edf'
        if prefix is not None:
            outfilename = prefix + outfilename

        listOfLists = []
        lines = slice.readlines()
        if skiplines is not None:
            for index in range(skiplines, len(lines)):
                line = lines[index][1:-1]
                listOfLists.append([float(value) for value in line.split(' ')])
        else:
            for line in lines:
                line = line[1:-1]
                listOfLists.append([float(value) for value in line.split(' ')])
        arr = numpy.array(listOfLists)

        print('out filename: %s' % outfilename)
        try:
            os.remove(outfilename)
            print('File replaced')
        except OSError:
            print('New file created')
        edf=EdfFile.EdfFile(outfilename,'w')
        edf.WriteImage({},arr)
        edf=None

def rename(filenames, old_pattern, new_pattern):
    listOfNames = glob.glob(filenames)
    if listOfNames is None:
        raise ValueError("No files from '%s'" % filenames)

    if excludes is not None:
        for excl in excludes:
            for excl_filename in glob.glob(excl):
                listOfNames.remove(excl_filename)

    for filename in listOfNames:
        outfilename = filename.replace(old_pattern, new_pattern)
        if prefix is not None:
            outfilename = prefix + outfilename
        if outfilename is not None:
            print("Renaming %s to %s" % (filename, outfilename))
            os.rename(filename, outfilename)
        else:
            print("Could not find '%s' pattern in '%s'"
                   % (old_pattern, filename))

def simpleBenchmark(benchmark):
    totNum = 10
    totalUTime = 0.0
    totalRTime = 0.0
    bench_cmd = 'time ' + benchmark
    for i in range(totNum):
        print("Iteration num: %d (tot: %d)" % (i+1, totNum))
        pipe = subprocess.Popen(bench_cmd, stderr=subprocess.PIPE, shell=True)
        output = str(pipe.stderr.read())
        usertime = re.search("user\s*\d*m\d*\.\d*s", output)
        realtime = re.search("real\s*\d*m\d*\.\d*s", output)
        if usertime is not None and realtime is not None:
            str_time = usertime.group().split('\t')[-1].split('m')
            str_time[1] = str_time[1].split('s')[0]
            totalUTime = totalUTime + float(str_time[0])*60 + float(str_time[1])
            str_time = realtime.group().split('\t')[-1].split('m')
            str_time[1] = str_time[1].split('s')[0]
            totalRTime = totalRTime + float(str_time[0])*60 + float(str_time[1])
        else:
            raise ValueError("Time output not found")
    print("Average utime (seconds): %f" % (totalUTime/totNum))
    print("Average rtime (seconds): %f" % (totalRTime/totNum))

def flip(filenames, type_flip):
    listOfNames = glob.glob(filenames)
    if excludes is not None:
        for excl in excludes:
            for excl_filename in glob.glob(excl):
                listOfNames.remove(excl_filename)
    if type_flip == 'horizontal':
        horizontal = True
    elif type_flip == 'vertical':
        horizontal = False
    else:
        raise ValueError("Unknown flipping direction: %s" % type_flip)
    flipUnit(listOfNames, horizontal)

#    numOfThreads = 4;
#    listOfListsOfFilenames = []
#    for ii in range(numOfThreads):
#        listOfListsOfFilenames.append([])
#    for ii in range(len(listOfNames)):
#        index = ii % numOfThreads
#        listOfListsOfFilenames[index].append(listOfNames[ii])


def flipUnit(listOfNames, horizontal):
    orientationString = ""
    if horizontal is True:
        orientationString = "Horizontal"
    else:
        orientationString = "Vertical"

    index = 1;
    for filename in listOfNames:
        edf = EdfFile.EdfFile(filename, 'r')
        img = edf.GetData(0)
        edf = None
        if horizontal is True:
            img = numpy.fliplr(img)
        else:
            img = numpy.flipud(img)
        os.remove(filename)

        edf = EdfFile.EdfFile(filename, 'w')
        edf.WriteImage({}, img)
        edf = None
        print("Flipped image (%s) (%04d/%04d): %s" % (orientationString, index, len(listOfNames), filename))
        index = index+1

if convert_filename is not None:
    convert(convert_filename)

if ( rename_filenames is not None
       and new_pattern is not None
       and old_pattern is not None ):
    rename(rename_filenames, old_pattern, new_pattern)

if pyhst is not None:
    par_name = '.'.join(pyhst.split('.')[0:-1]) + '.par'
    vol_name = '.'.join(os.path.abspath(pyhst).split('.')[0:-1]) + '.vol'
    os.system('/scisoft/ESRF_sw/opteron/PACKAGES/PyHST_gpu/WRAPPERS/PyHST %s'
               % par_name)
    os.system('ImageJ %s' % vol_name)

if simple_time_benchmark is not None:
    simpleBenchmark(simple_time_benchmark)

if ( flip_filenames is not None
       and flipping is not None ):
    flip(flip_filenames, flipping)