#!/usr/bin/env python3
#coding: utf-8
############usage##################
#############################

# In[2]:

import re,sys,os,time
def xopen_fun(SM_f):
    with open(SM_f,'r') as handle:
        for line in handle:
            yield(line.strip())


# In[35]:

def qsub_script_fun(path,TaskID,Ver,TR,qsub_line,step,step_i,analysisCode,dataFiledir,dataFilelist,module,Update):
    TR=str(TR)
    Date=time.strftime('%Y%m%d',time.localtime(time.time()))
    qsub_f=os.path.join(path,'.'.join((TaskID,module + '-' + Ver,str(step_i),Date,'qsub')))
    o_f=os.path.join(path,'.'.join((TaskID,Date,'o')))
    e_f=os.path.join(path,'.'.join((TaskID,Date,'e')))
    th_done=os.path.join(path,'.'.join((TaskID,module,str(step_i),Ver,step,'done')))
    step_i = str(step_i)
    STEP=step
    sub_JOBID_th = os.path.join(path,'.'.join((TaskID,module + '-' + Ver ,'JOBID'))) # if failed those qIDs need to be killed,this is a qids file generated by codes at the back.
    #print("sub_JOBID_th",sub_JOBID_th)
    ID = TaskID.split('-')[0]
    JOBID_th = os.path.join('R' + os.path.dirname(os.path.dirname(path)),'.'.join((ID,'JOBID')))
    #print("JOBID_th",JOBID_th)

    with open(qsub_f,'w') as handle:
        print('#!/bin/bash',file=handle)
        print('#$ -S /bin/bash',file=handle)
        print('#-cwd',file=handle)
        print('#$ -pe thread '+TR,file=handle)
        print('#$ -o '+o_f,file=handle)
        print('#$ -e '+e_f,file=handle)
        print('#',file=handle)
        print("# Start Runing",file=handle)
        print("echo `date` "+qsub_f+' start...',file=handle)   
        print("#",file=handle)
        print("if [ ! -f {0} ];then".format(th_done),file=handle)
        if Update != 'no' and Update == 'yes':
            #print('    hs_GDT_v1.2.py -m cu -t step -f analysisCode={0} -f stepCode={1} -f stepName={2} -f stepVersion={3} -f dataFiledir={4} -f stepStatus=start -u stepStatus=start'.format(analysisCode,module  + ':step:'+ step_i,STEP,Ver,dataFiledir),file=handle)
            print('    bigdata.py -W save -T step -I analysisCode={ac}:stepCode={sc}:stepName={sn}:stepVersion={sv}:dataFiledir={dd}:stepStatus=start'.format(ac=analysisCode,sc=module  + ':step:'+ step_i,sn=STEP,sv=Ver,dd=dataFiledir),file=handle)
        print('    '+qsub_line,file=handle)
        print("    if [ $? -ne 0 ];then",file=handle)
        print('        echo `date` '+step+' failed !!!!!',file=handle)
        print('        qdel `cat {0}` '.format(sub_JOBID_th),file=handle)
        if Update != 'no' and Update == 'yes':
            #print('        hs_GDT_v1.2.py -m cu -t step -f analysisCode={0} -f stepCode={1} -f stepVersion={2} -f dataFiledir={3} -f dataFilelist={4} -u stepStatus=fault -f stepStatus=fault'.format(analysisCode,module  + ':step:' + step_i,Ver,dataFiledir,dataFilelist),file=handle)
            print('         bigdata.py -W update -T step -I analysisCode={ac}:stepCode={sc}:stepVersion={sv}:dataFiledir={dd} -U stepStatus=end:dataFilelist={df}'.format(ac=analysisCode,sc=module  + ':step:' + step_i,sv=Ver,dd=dataFiledir,df=dataFilelist),file=handle)
        #print('        qdel `cat {0}`'.format(sub_JOBID_th),file=handle)
        #print('        qdel `cat {0}`'.format(JOBID_th),file=handle)
        print('        exit 1',file=handle)
        print('      else',file=handle)
        print('        echo `date` '+step+' finished',file=handle)
        if Update == 'yes':
            print('        hs_GDT_v1.2.py -m cu -t step -f analysisCode={0} -f stepCode={1} -f stepVersion={2} -f dataFiledir={3} -f dataFilelist={4} -u stepStatus=end -f stepStatus=end'.format(analysisCode,module + ':step:' + step_i,Ver,dataFiledir,dataFilelist),file=handle)
        print('        touch {0}'.format(th_done),file=handle)
        print('    fi',file=handle)
        print('fi',file=handle)
    return(qsub_f)


#if script line is start with "cd |mkdir |#;then run it directly"
def get_step_name(line,Ver):
    if line.startswith("#"):
        step = re.sub(re.compile("\s+|\t+"),"_",line).replace("#","")
        return(step)

def run_fun(line):
    line_sp=re.split('\s+',line)
    if "#" in line_sp[0]:
        pass
    elif line_sp[0]=='cd':
        os.chdir(line_sp[1])
    elif line_sp[0]=='mkdir':
        os.system(line)
    elif line_sp[0]!='wait':
        return(line)
# In[43]:

def get_wait_fun(SM_f):
    wait_dic = {}
    index_line = 0;block_index = 0
    block = []
    for line in xopen_fun(SM_f):
        index_line += 1
        block.append(line)
        if 'wait' in line:
            block_index += 1
            wait_dic.update({block_index:block})
            block = []
    wait_dic.update({block_index+1:block})
    return(wait_dic)

# In[44]:

def par_fun(pid):
    if pid=='':
        par=''
    else:
        par='-hold_jid'
    return(par)


# In[45]:

def block_run(path,tmp_all_pid,all_pid,block_pid,add,line,step,step_i,TaskID,Ver,TR,analysisCode,dataFiledir,dataFilelist,module,prio,Update):
    if add==1:
        x = block_pid + tmp_all_pid
        pid = ','.join(x)
    else:
        pid = ','.join(block_pid)
    par=par_fun(pid)


    run_line = line.rstrip()
    if run_line.endswith('&'):
       run_line = run_line[:-1]
    
    #run_line = line.replace('&','')
    qsub_f = qsub_script_fun(path,TaskID,Ver,TR,run_line,step,step_i,analysisCode,dataFiledir,dataFilelist,module,Update)
    #qsub_s = r'qsub -q long.q@hw10 {0} {1} -p {2} {3}'.format(par,pid,prio,qsub_f)
    qsub_s = r'qsub {0} {1} -p {2} {3}'.format(par,pid,prio,qsub_f)
    #qsub_s = r'qsub {0} {1} {2}'.format(par,pid,qsub_f)
    #print(qsub_s)
    qr = list(os.popen(qsub_s))
    qid = re.split('\s+',qr[0])[2]
    #print(qsub_s,qid,qsub_f,sep="===")

    if not run_line.endswith('&'):
    #if '&' not in line:
        block_pid.append(qid)
    all_pid.append(qid)
    return(tmp_all_pid,block_pid,all_pid)

# In[48]:

def main(path,SM_f,TaskID,Ver,TR,analysisCode,dataFiledir,dataFilelist,module,prio,Update):
    step='noname'
    block_script = get_wait_fun(SM_f)
    all_pid = []
    step_i = 0

    for B in block_script.keys():
        tmp_all_pid = all_pid[:]
        block_pid = []
        if B==1:
            add = 0
        else:
            add = 1
        for line in block_script[B]:
            step_tmp =  get_step_name(line,Ver)
            if step_tmp:
                step = step_tmp
           
            line = run_fun(line)
            if line:
                step_i += 1                      #get step number
                mid = block_run(path,tmp_all_pid,all_pid,block_pid,add,line,step,step_i,TaskID,Ver,TR,analysisCode,dataFiledir,dataFilelist,module,prio,Update)
                tmp_all_pid = mid[0]
                block_pid = mid[1]
        all_pid = mid[2]

    ppid = ','.join(all_pid)
    sc =  module + '-' +Ver
    JOBID_th = os.path.join(path,'.'.join((TaskID,sc,'JOBID')))
    with open(JOBID_th,'w') as handle:
        print(ppid,file=handle)

# In[ ]:

if __name__ == "__main__":
    path = sys.argv[1]
    SM_f = sys.argv[2]     #the script name ,including module and version,format {sample}.{module}-{ver}.script
    TaskID = sys.argv[3]    # the sample id
    TR = sys.argv[4]       # the thread
    analysisCode = sys.argv[5]
    prio = sys.argv[6]
    Update = sys.argv[7]
    #dataFiledir = sys.argv[6]
    #dataFilelist = sys.argv[7]
    dataFiledir = '/fastzone/worker/ctDNA'
    dataFilelist = 'NA,NA'
    module,Ver = os.path.basename(SM_f).split(".")[1].split('-')
    Ver = Ver + '.' + os.path.basename(SM_f).split(".")[2]
    main(path,SM_f,TaskID,Ver,TR,analysisCode,dataFiledir,dataFilelist,module,prio,Update)

