import subprocess
import os
import pandas as pd
import traceback
import argparse
from Alignment_Part import alignment
def runCmd(cmd) :
  res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  sout ,serr = res.communicate()
  return res.returncode, sout, serr


def PHASMinerCLI(input_file,phasiRNA_len,dir_path,sRNAminer):
    output_file = dir_path + os.path.basename(input_file) + "." + str(phasiRNA_len) + ".PHAS.tab"
    cmd = "java -cp " + sRNAminer + " biocjava.sRNA.Miner.phasiRNA.PHASMinerCLI --inAln " + input_file + " --output " + output_file + \
          " --phasLen " + str(phasiRNA_len) + " --normLibSize 20000000"
    returncode, sout, serr = runCmd(cmd)
    if returncode == 0:
        final_result = "phasiRNAminer Step 1: Mining Lib [Finish]"
    else:
        final_result = serr.decode('gbk')
    return returncode, final_result

# def Merge_tab(input_file_list, phasiRNA_len,dir_path):
#     returncode = 0
#     return_str = ""
#     try:
#         output_file = open(dir_path + "all." + str(phasiRNA_len) + ".PHAS.list", "w+")
#         file_list = [os.path.basename(i) + "." + str(phasiRNA_len) +".PHAS.tab" for i in input_file_list]
#         for root, dirs, files in os.walk(dir_path):
#             for file in files:
#                 if file in file_list:
#                     output_file.write(root + file + "\n")
#         output_file.close()
#         return_str = "phasiRNAminer Step 2: Merging PHAS LIST [Finish]"
#     except Exception:
#         returncode += 1
#         return_str = traceback.format_exc()
#     return returncode,return_str

def PHASMerger(dir_path,phasiRNA_len,sRNAminer):
    input_file_1 = dir_path + "all." + str(phasiRNA_len) + ".PHAS.list"
    output_file = dir_path + "merged." + str(phasiRNA_len) + ".PHAS.list.xls"
    cmd = "java -cp " + sRNAminer + " biocjava.sRNA.Miner.phasiRNA.PHASMerger --inFileList " + input_file_1 + \
          " --outFile " + output_file
    returncode, sout, serr = runCmd(cmd)
    if returncode == 0:
        final_result = "phasiRNAminer Step 2: Merging PHAS file [Finish]"
    else:
        final_result = serr.decode('gbk')
    return returncode, final_result

def filter_phasiRNA_identification(dir_path,phasiRNA_len,lib_num):
    returncode = 0
    return_str = ""
    try:
        input_file_1 = dir_path + "merged." + str(phasiRNA_len) + ".PHAS.list.xls"
        output_file = dir_path + "merged." + str(phasiRNA_len) + ".PHAS.list.filter.xls"
        phasiRNA_filter = pd.read_table(input_file_1,encoding='utf-8')
        phasiRNA_filter = phasiRNA_filter[(phasiRNA_filter["Max_Region_Phase_Score"] >= 10) & (phasiRNA_filter["Lib_Num"] >= int(lib_num))]
        PHAS_name_list = []
        for i in range(1,len(phasiRNA_filter)+1):
            PHAS_name_list.append("PHAS" + str(phasiRNA_len) + "-" + str(i))
        phasiRNA_filter["PHASID"] = PHAS_name_list
        phasiRNA_filter.to_csv(output_file, sep="\t",index=None)
        return_str = "phasiRNAminer Step 3: Filtering [Finish]"
        return returncode,return_str
    except Exception:
        returncode += 1
        return_str = traceback.format_exc()
        return returncode,return_str


def PHASMergedListToGFF(dir_path,genome_file,phasiRNA_len,sRNAminer):
    input_file_1 = dir_path + "merged." + str(phasiRNA_len) + ".PHAS.list.filter.xls"
    out_gff3_file = dir_path + "merged.PHAS" + str(phasiRNA_len) + ".gff3"
    cmd = "java -cp " + sRNAminer + " biocjava.sRNA.Miner.phasiRNA.PHASMergedListToGFF --inPhasList  " + input_file_1 + \
          " --outGff3 " + out_gff3_file + " --phasLen " + str(phasiRNA_len) + " --inGenome " + genome_file
    returncode, sout, serr = runCmd(cmd)
    if returncode == 0:
        final_result = "phasiRNAminer Step 4: Establishing GFF [Finish]"
    else:
        final_result = serr.decode('gbk')
    return returncode, final_result

def phas_identification_merger_pipeline(index,thread,locate,mismatch,input_file,genome_file,phas_len,dir_path,lib_num,Batch_mode,sRNAminer):
    final_result = ""
    returncode = 0
    if not dir_path.endswith("/") or dir_path.endswith("\\"):
        dir_path = dir_path + "/"
    log_file = dir_path + "PHAS_identification.log"
    log_file_content = open(log_file,"w+")
    if Batch_mode:
        input_file_content = open(input_file,"r")
        file_list = [i.strip() for i in input_file_content.readlines()]
        new_file_list = []
        for input_file in file_list:
            print("Check out the existence of Bowtie File in sorted format")
            check_bowtie_sorted_file = dir_path + os.path.basename(input_file) + ".bowtie.aln.sorted"
            if not os.path.exists(check_bowtie_sorted_file):
                print("Bowtie File in sorted format not Exist")
                print("Check out the existence of Bowtie Files")
                check_bowtie_file = dir_path + os.path.basename(input_file) + ".bowtie"
                if os.path.exists(check_bowtie_file):
                    print("Bowtie files exist. Treating the Files")
                    input_file = check_bowtie_file
                    returncode, final_result = alignment.bowtie_format_change(input_file, sRNAminer)  # .aln
                    print(final_result, file=log_file_content)
                    if returncode == 0:
                        print(final_result)
                        input_file = dir_path + os.path.basename(input_file) + ".aln"
                        returncode, final_result = alignment.sort_bowtie(input_file, sRNAminer)  # .aln
                        print(final_result, file=log_file_content)
                        input_file = dir_path + os.path.basename(input_file) + ".sorted"
                    else:
                        break
                else:
                    print("Bowtie file not exist. Starting mapping")
                    returncode, final_result = alignment.align(index, input_file, thread, locate, mismatch,dir_path)  # .bowtie
                    print(final_result, file=log_file_content)
                    if returncode == 0:
                        print(final_result)
                        input_file = dir_path + os.path.basename(input_file) + ".bowtie"
                        returncode, final_result = alignment.bowtie_format_change(input_file, sRNAminer)  # .aln
                        print(final_result, file=log_file_content)
                        if returncode == 0:
                            print(final_result)
                            input_file = dir_path + os.path.basename(input_file) + ".aln"
                            returncode, final_result = alignment.sort_bowtie(input_file, sRNAminer)  # .aln
                            print(final_result, file=log_file_content)
                            input_file = dir_path + os.path.basename(input_file) + ".sorted"

            else:
                input_file = check_bowtie_sorted_file
            if returncode != 0:
                break

            else:
                print("Preparing for Bowtie Files(sRNAminer Format) [Finish]")
                new_file_list.append(dir_path + os.path.basename(input_file) + "." + str(phas_len) +".PHAS.tab")
                returncode, final_result = PHASMinerCLI(input_file,phas_len,dir_path,sRNAminer) #.tab
                print(final_result, file=log_file_content)

                if returncode != 0:
                    break
                else:
                    print(final_result)
        if returncode == 0:
            all_phas_list_tmp = open(dir_path + "all." + str(phas_len) + ".PHAS.list","w+")
            for i in new_file_list:
                print(i,file=all_phas_list_tmp)
            all_phas_list_tmp.close()
            returncode, final_result = PHASMerger(dir_path, phas_len, sRNAminer)
            print(final_result, file=log_file_content)
            if returncode == 0:
                print(final_result)
                returncode, final_result = filter_phasiRNA_identification(dir_path, phas_len, lib_num)
                print(final_result, file=log_file_content)
                if returncode == 0:
                    print(final_result)
                    returncode, final_result = PHASMergedListToGFF(dir_path, genome_file, phas_len, sRNAminer)
                    print(final_result, file=log_file_content)


            print(final_result)

        else:
            print(final_result)



    else:
        file_list = str(input_file).split(",")
        new_file_list = []
        for input_file in file_list:
            print("Check out the existence of Bowtie File in sorted format")
            check_bowtie_sorted_file = dir_path + os.path.basename(input_file) + ".bowtie.aln.sorted"
            if not os.path.exists(check_bowtie_sorted_file):
                print("Bowtie File in sorted format not Exist")
                print("Check out the existence of Bowtie Files")
                check_bowtie_file = dir_path + os.path.basename(input_file) + ".bowtie"
                if os.path.exists(check_bowtie_file):
                    print("Bowtie files exist. Treating the Files")
                    input_file = check_bowtie_file
                    returncode, final_result = alignment.bowtie_format_change(input_file, sRNAminer)  # .aln
                    print(final_result, file=log_file_content)
                    if returncode == 0:
                        print(final_result)
                        input_file = dir_path + os.path.basename(input_file) + ".aln"
                        returncode, final_result = alignment.sort_bowtie(input_file, sRNAminer)  # .aln
                        print(final_result, file=log_file_content)
                        input_file = dir_path + os.path.basename(input_file) + ".sorted"
                else:
                    print("Bowtie file not exist. Starting mapping")
                    returncode, final_result = alignment.align(index, input_file, thread, locate, mismatch,
                                                               dir_path)  # .bowtie
                    print(final_result, file=log_file_content)
                    if returncode == 0:
                        print(final_result)
                        input_file = dir_path + os.path.basename(input_file) + ".bowtie"
                        returncode, final_result = alignment.bowtie_format_change(input_file, sRNAminer)  # .aln
                        print(final_result, file=log_file_content)
                        if returncode == 0:
                            print(final_result)
                            input_file = dir_path + os.path.basename(input_file) + ".aln"
                            returncode, final_result = alignment.sort_bowtie(input_file, sRNAminer)  # .aln
                            print(final_result, file=log_file_content)
                            input_file = dir_path + os.path.basename(input_file) + ".sorted"

            else:
                input_file = check_bowtie_sorted_file
            if returncode != 0:
                break

            else:
                print("Preparing for Bowtie Files(sRNAminer Format) [Finish]")
                new_file_list.append(dir_path + os.path.basename(input_file) + "." + str(phas_len) + ".PHAS.tab")
                returncode, final_result = PHASMinerCLI(input_file, phas_len, dir_path, sRNAminer)  # .tab
                print(final_result, file=log_file_content)

                if returncode != 0:
                    break
                else:
                    print(final_result)
        if returncode == 0:
            all_phas_list_tmp = open(dir_path + "all." + str(phas_len) + ".PHAS.list", "w+")
            for i in new_file_list:
                print(i, file=all_phas_list_tmp)
            all_phas_list_tmp.close()
            returncode, final_result = PHASMerger(dir_path, phas_len, sRNAminer)
            print(final_result, file=log_file_content)
            if returncode == 0:
                print(final_result)
                returncode, final_result = filter_phasiRNA_identification(dir_path, phas_len, lib_num)
                print(final_result, file=log_file_content)
                if returncode == 0:
                    print(final_result)
                    returncode, final_result = PHASMergedListToGFF(dir_path, genome_file, phas_len, sRNAminer)
                    print(final_result, file=log_file_content)

            print(final_result)

        else:
            print(final_result)

    log_file_content.close()







if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("--input_file", "-i", required=False, help="use_for_rfam")
    # parser.add_argument("--genome_file", "-g", required=False, help="use_for_rfam")
    args = parser.parse_args()
    input_file_arg = args.input_file
