#! /bin/bash

# author: X.Gan

function print_mapper_init {
    if [ "$#" -lt 1 ]; then
	exit
	echo "print_mapper_initial mappername" >2
    fi
    mappername=$1

    if [ "$mappername" == "smalt" ]; then
	print_smalt_init
	return
    fi
    if [ "$mappername" == "stampy" -o "$mappername" == "stampypost" ]; then
	print_stampy_init
	return
    fi
    if [ "$mappername" == "bwa" -o "$mappername" == "bwamem" ]; then
	print_bwa_init
	return
    fi
    if [ "$mappername" == "maq" ]; then
	print_maq_init
	return
    fi
    if [ "$mappername" == "tophat" ]; then
	print_bowtie_init
	return
    fi
    if [ "$mappername" == "STAR" ]; then
	print_STAR_init
	return
    fi
}          

function print_mapper_run {
    if [ "$#" -lt 1 ]; then
	echo "print_mapper_run mappername" >2
	exit
    fi
    mappername=$1
    
    tmps=${bampart_file%.bam}
    sampart_file=$tmps.sam
    mappart_file=$tmps"_map.out"
    unmap_file=$tmps"_unmap.out"

    if [ "$mappername" == "smalt" ]; then
	print_smalt_run
	return
    fi
    if [ "$mappername" == "stampy" ]; then
	print_stampy_run
	return
    fi
    if [ "$mappername" == "stampypost" ]; then
	print_stampypost_run
	return
    fi
    if [ "$mappername" == "bwa" ]; then
	print_bwa_run
	return
    fi
    if [ "$mappername" == "bwamem" ]; then
	print_bwamem_run
	return
    fi
    if [ "$mappername" == "maq" ]; then
	print_maq_run
	return
    fi
    if [ "$mappername" == "tophat" ]; then
        ofolder=`dirname $bampart_file` 
        mappart_file="$ofoler/accepted_hits.bam"
        unmap_file="$ofoler/unmapped.bam"
	print_tophat_run
	return
    fi
    if [ "$mappername" == "STAR" ]; then
	print_STAR_run
	return
    fi
}          


##################################################
function print_STAR_init {
   ref_dir=$ref_file"_sj_$readlen1down"
   if [ ! -d "$ref_dir" -o "$ref_dir/SAindex" -ot "$ref_fas" ]; then
       mkdir -p $ref_dir
       fopt="" 
       if [ -s "$annotation" ]; then
           fopt="--sjdbOverhang $readlen1down" 
           fopt=" $fopt --sjdbGTFfile $annotation "
           isgff3=`expr "$annotation" : ".*gff[3]*$"`
           if [ "$isgff3" -gt 0 ]; then
               fopt=" $fopt --sjdbGTFtagExonParentTranscript Parent"
           fi
       fi

       echo "if [ -d \"$tmp_star\" ]; then"
       echo "  rm -rf $tmp_star" 
       echo "fi"
      
       echo "$mapper_addr  --outTmpDir $tmp_star --runMode genomeGenerate --genomeDir $ref_dir --genomeFastaFiles $ref_fas --runThreadN 4 $fopt"
       printverifycom "IMRREF_SUCC" "IMRFAILED"
      
       if [ -f "$annotation" ]; then
           echo "if [ ! -s \"$ref_dir/sjdbInfo.txt\" ]; then"
           echo "echo IMRSJDBFAILED"
           echo "exit 1"
           echo "fi"
       fi    
   fi
   printverifycom
}

function print_bowtie_init {
   if [ "$ref_file.1.bt2" -ot "$ref_fas" ]; then
       echo "bowtie2-build $ref_fas $ref_file"
   fi
   printverifycom
}

function print_smalt_init {
    if [ "$ref_file.sma" -ot "$ref_fas" ]; then
	echo "$mapper_addr index -k 13 -s 6 $ref_file $ref_fas"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    fi
    printverifycom
}
function print_stampy_init {
    if [ "$ref_file.sthash" -ot "$ref_fas" ]; then
	echo "if [ -a \"$ref_file.sthash\" ]; then"
	echo "    rm $ref_file.sthash "
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    	echo "fi"
	echo "if [ -a \"$ref_file.stidx\" ]; then"
	echo "    rm $ref_file.stidx"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    	echo "fi"
        echo "$mapper_addr --species=$(basename $ref_file) --assembly=$(basename $ref_file) -G $ref_file $ref_fas" 
	printverifycom "IMRREF_SUCC" "IMRFAILED"
	echo "$mapper_addr -g $ref_file -H $ref_file"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    fi
    mapper_tmp=$mapper_addr
    mapper_addr=$bwa_addr
    print_bwa_init
    mapper_addr=$mapper_tmp
}


function print_maq_init {
    if [ "$ref_file" -ot "$ref_fas" ]; then
        echo  "$mapper_addr fasta2bfa $ref_fas $ref_file"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    fi     

    if [ "$ref_fas.fai" -ot "$ref_fas" ]; then
    	echo "$samtools_addr faidx $ref_fas"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    fi
    printverifycom
}

function print_bwa_init {
    if [ "$ref_fas.bwt" -ot "$ref_fas" ]; then 
        echo "$mapper_addr index -a bwtsw $ref_fas" 
	echo "zztt=\$?; if [ \"\$zztt\" != 0 ]; then "
	echo "            $mapper_addr index -a is $ref_fas "
	     printverifycom "IMRREF_SUCC" "IMRFAILED" 
	echo "else echo \"IMRREF_SUCC\"; fi"
    fi    
    if [ "$ref_fas.fai" -ot "$ref_fas" ]; then
    	echo "$samtools_addr faidx $ref_fas"
	printverifycom "IMRREF_SUCC" "IMRFAILED"
    fi
    printverifycom
}




function printverifycom {
    if [ "$#" -lt 1 ]; then
    	ver_succ="IMRSUCCESSFUL"
    	ver_fail="IMRFAILED"
    else
    	ver_succ="$1"
    	ver_fail="$2"
    fi
    echo "zztt=\$?; if [ \"\$zztt\" != 0 ]; then echo \"$ver_fail\" \$zztt; exit 1; else echo \"$ver_succ\"; fi"
}

### below is the old one, not used any more
function verifylastcommand_print {
    if [ "$#" -lt 1 ]; then
	echo "echo need summary file name" >&2 
    fi
    tracefile=$1
    ver_keyword="$2"
    echo "zztt=\$?; if [ \"\$zztt\" != 0 ]; then echo "IMRFAILED: " $ver_keyword \$zztt >>$tracefile; exit 1; fi"

}

function sam2sortedbam_print {
    if [ "$#" -lt 2 ]; then
	echo "echo something wrong happen" >&2
    fi

    sampart_file=$1
    bampart_file=$2	

    tmps=${bampart_file%.bam}
    TempLanebam=$tmps"_x1tmp".bam
    Tem2Lanebam=$tmps"_x2tmp".bam
    Tem3Lanebam=$tmps"_x3tmp".bam

   # TOBam="$samtools_addr import"
   # echo "$TOBam $ref_fas.fai $sampart_file $TempLanebam"
    echo "$samtools_addr view -bT $ref_fas -o $TempLanebam $sampart_file"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_view"
    echo "rm $sampart_file"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_rm"
    #Tem2prefix=$tmps"_x2tmp"
    #echo "$samtools_addr sort -n $TempLanebam $Tem2prefix"
    echo "$samtools_addr sort -n -o $Tem2Lanebam $TempLanebam"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_sort"
    echo "$samtools_addr fixmate $Tem2Lanebam $Tem3Lanebam" 
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_fixmate"
    #echo "$samtools_addr sort $Tem3Lanebam $tmps" 
    echo "$samtools_addr sort -o $bampart_file $Tem3Lanebam" 
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_sort2"
    echo "rm $TempLanebam  $Tem2Lanebam $Tem3Lanebam"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_rm2"

  # echo "java -jar $PD_PATH/MarkDuplicates.jar I=$sampart_file O=$bampart_file VALIDATION_STRINGENCY=SILENT >> $trace_file 2>&1 "  	
  # echo "rm $sampart_file"
    printverifycom
    sleep 1   ##network storage 
}


function print_smalt_run {
    echo "echo $scriptname"
    echo "echo \"$mapper_addr map $this_map_para -f samsoft -o $mappart_file $ref_file $read_file 2>&1\""
    printverifycom "IMR_SMALT_SUCC" "IMRFAILED"
    echo "$mapper_addr map $this_map_para -f samsoft -o $mappart_file $ref_file $read_file 2>&1"
    printverifycom "IMR_SMALT_SUCC" "IMRFAILED"

    if [ -n "$RGname" ]; then 
	echo "echo -e \"$groupseq\" >$sampart_file"
	echo "echo -e \"@PG\tID:IMR\tVN:$IMRVERSION\" >>$sampart_file"
        printverifycom "IMR_SMALT_SUCC" "IMRFAILED"
	echo -e "awk '/^@/ {print \$0} /^[^@]/ {print \$0\"\\\tRG:Z:$RGname\"}'  $mappart_file >> $sampart_file"
        printverifycom "IMR_SMALT_SUCC" "IMRFAILED"
    else
	echo "echo -e \"@PG\tID:IMR\tVN:$IMRVERSION\" >$sampart_file"
	echo "cat $mappart_file >> $sampart_file"
        printverifycom "IMR_SMALT_SUCC" "IMRFAILED"
    fi
    
    sam2sortedbam_print $sampart_file $bampart_file
}

function print_STAR_run {
    extra_opt=""
    if [ -n "$RGname" ]; then 
         extra_opt=" --outSAMattrRGline '$groupseq'"
    fi

    echo "if [ -d \"$tmp_star\" ]; then"
    echo "  rm -rf $tmp_star" 
    echo "fi"

    ref_dir=$ref_file"_sj_$readlen1down"
    echo "$mapper_addr $extra_opt --outTmpDir $tmp_star --genomeDir $ref_dir $this_map_para --readFilesIn $read_file >$sampart_file"
    printverifycom "IMR_TOPHAT_SUCC" "IMRFAILED"
    sam2sortedbam_print $sampart_file $bampart_file
}

function print_tophat_run {
   if [ -s "$annotation" ]; then
       fopt=" -G $annotation "
   fi
   echo $mapper_addr $this_map_para -o $ofolder $ref_file $read_file
   printverifycom "IMR_TOPHAT_SUCC" "IMRFAILED"
   
   tmps=${bampart_file%.bam}
   TempLanebam=$tmps"_x1tmp".bam
   Tem2Lanebam=$tmps"_x2tmp".bam
   Tem3Lanebam=$tmps"_x3tmp".bam
    
   if [ "$numReads" -eq 2 ]; then
       echo $samtools_addr merge -f $TempLanebam $ofolder/accepted_hits.bam $ofolder/unmapped.bam
       printverifycom "IMR_MERGE_SUCC" "IMRFAILED"
       #echo java -jar -Xmx2g $PD_PATH/FixMateInformation.jar I=$TempLanebam O=$bampart_file VALIDATION_STRINGENCY=SILENT SO=coordinate
       #printverifycom "IMR_FIXMATE_SUCC" "IMRFAILED"

       #Tem2prefix=$tmps"_x2tmp"
       #echo "$samtools_addr sort -n $TempLanebam $Tem2prefix"
       echo "$samtools_addr sort -n -o $Tem2Lanebam $TempLanebam"
       printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_sort"
       echo "$samtools_addr fixmate $Tem2Lanebam $Tem3Lanebam" 
       printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_fixmate"
       #echo "$samtools_addr sort $Tem3Lanebam $tmps" 
       echo "$samtools_addr sort -o $bampart_file $Tem3Lanebam" 
       printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_sort2"
       echo "rm $TempLanebam $Tem2Lanebam $Tem3Lanebam"
   else
       echo $samtools_addr merge -f $TempLanebam $ofolder/accepted_hits.bam $ofolder/unmapped.bam
       printverifycom "IMR_MERGE_SUCC" "IMRFAILED"
       #echo "$samtools_addr sort $TempLanebam $tmps" 
       echo "$samtools_addr sort -n $bampart_file $TempLanebam" 
       printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_sort2"
       echo "rm $TempLanebam"
   fi    
   printverifycom
   sleep 1   ##network storage 
}

function print_stampy_run {
    if [ "$PARALLELCMD" == 4 ]; then
	mkdir -p $tdir/tmp
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	zz=`mktemp -p $tdir/tmp/`
        echo "cp $ref_file.sthash $zz.sthash"
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	echo "cp $ref_file.stidx $zz.stidx"
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	ref_file=$zz
    fi
####### stampy's overwrite does not work well in network storage
    echo "echo $scriptname"
    echo -e 'echo Running on host: `hostname`. '

    stampyrgopt=""
    if [ -n "$RGname" ]; then 
	#rgkeywd=`echo -e "$groupseq" |sed "s/^@RG[[:space:]]//g" | sed "s/[[:space:]]/,/g" `
	rgline=`echo "$groupseq" |sed "s/[[:space:]]/,/g"`
        stampyrgopt="--readgroup='$rgkeywd'"
    fi 	
    #echo -e "echo -e \"$mapper_addr --keepreforder --bwa=$bwa_addr --overwrite -g $ref_file -h $ref_file $this_map_para $stampyrgopt --bwaoptions=\"-q10 $ref_fas\" -o $sampart_file -M $read_file   2>&1\""
    #echo -e "$mapper_addr --keepreforder --bwa=$bwa_addr --overwrite -g $ref_file -h $ref_file $this_map_para $stampyrgopt --bwaoptions=\"-q10 $ref_fas\" -o $sampart_file -M $read_file  2>&1"
    mapper_temp=$mapper_addr
    para_temp="$this_map_para"

    mapper_addr=$bwa_addr
    this_map_para=" -q10 "
    print_bwa_run_core

    echo "$samtools_addr view -bT $ref_fas -o $bampart_file $sampart_file"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_view"
    
    echo -e "$mapper_temp -g $ref_file -h $ref_file $stampyrgopt $para_temp --overwrite --bamkeepgoodreads -M $bampart_file  -o $sampart_file 2>&1"
    printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"

    if [ "$PARALLELCMD" == 4 ]; then
        echo "rm $zz.sthash"
        printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	echo "rm $zz.stidx"
        printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
    fi

    sam2sortedbam_print $sampart_file $bampart_file
}

function print_stampypost_run {
    if [ "$PARALLELCMD" == 4 ]; then
	mkdir -p $tdir/tmp
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	zz=`mktemp -p $tdir/tmp/`
        echo "cp $ref_file.sthash $zz.sthash"
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	echo "cp $ref_file.stidx $zz.stidx"
	printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	ref_file=$zz
    fi
####### stampy's overwrite does not work well in network storage
    echo "echo $scriptname"
    echo -e 'echo Running on host: `hostname`. '

    stampyrgopt=""
    if [ -n "$RGname" ]; then 
	#rgkeywd=`echo -e "$groupseq" |sed "s/^@RG[[:space:]]//g" | sed "s/[[:space:]]/,/g" `
	rgline=`echo "$groupseq" |sed "s/[[:space:]]/,/g"`
        stampyrgopt="--readgroup='$rgkeywd'"
    fi 	
    mapper_temp=$mapper_addr
    para_temp="$this_map_para"

    mapper_addr=$bwa_addr
    this_map_para=" -M "
    print_bwamem_run_core

    echo "$samtools_addr view -bT $ref_fas -o $bampart_file $sampart_file"
    printverifycom "IMR_SAM2BAM_SUCC" "IMRFAILED_view"
    
    echo -e "$mapper_temp -g $ref_file -h $ref_file $stampyrgopt $para_temp --overwrite --bamkeepgoodreads -M $bampart_file  -o $sampart_file 2>&1"
    printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"

    if [ "$PARALLELCMD" == 4 ]; then
        echo "rm $zz.sthash"
        printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
	echo "rm $zz.stidx"
        printverifycom "IMR_STAMPY_SUCC" "IMRFAILED"
    fi

    sam2sortedbam_print $sampart_file $bampart_file
}


function print_maq_run {
    echo "echo $scriptname"
    echo "echo \"$mapper_addr map $this_map_para -u $unmap_file $mappart_file $ref_file $read_file 2>&1\""
    echo "$mapper_addr map $this_map_para -u $unmap_file $mappart_file $ref_file $read_file 2>&1"
    printverifycom "IMR_MAQ_SUCC" "IMRFAILED"

    if [ "$groupseq" ]; then
	echo "echo -e \"$groupseq\" >$sampart_file"
	echo "echo -e \"@PG\tID:IMR\tVN:$IMRVERSION\" >>$sampart_file"
    else
	echo "echo -e \"@PG\tID:IMR\tVN:$IMRVERSION\" >$sampart_file"
    fi

    TOSam=maq2sam-long	
    echo "$TOSam $mappart_file $RGname >> $sampart_file"
    printverifycom "IMR_MAQ_SUCC" "IMRFAILED"

    if [ "$numReads" -eq 2 ]; then
	echo -e "if [ -s '$unmap_file' ]; then 
	unmap2sam.pl $unmap_file $RGname >>$sampart_file"
    	printverifycom "IMR_MAQ_SUCC" "IMRFAILED"
	echo "fi"
    else
	echo -e  "if [ -s '$unmap_file' ]; then 
	unmap2sam.pl -s $unmap_file $RGname >>$sampart_file"
    	printverifycom "IMR_MAQ_SUCC" "IMRFAILED"
	echo "fi"
    fi
    
    sam2sortedbam_print $sampart_file $bampart_file
}


function print_bwa_run_core {
    echo "echo $scriptname"
    tmps=${bampart_file%.bam}
    alntemp_filf=$tmps"_left.sai"	
    alntemp_filb=$tmps"_right.sai"	

    echo "echo bwa align"
    echo -e 'echo Running on host: `hostname`. '

    bwargopt=""
    if [ -n "$RGname" ]; then 
        rgtline=`echo "@RG $groupseq" |sed "s/[[:space:]]/\\\\\t/g" `
	bwargopt=" -r '$rgtline' " 
    fi

    if [ "$numReads" -eq 2 ]; then
	zz=0
	for ff in $read_file 
	do
	    if [ $zz -eq 1 ]; then
		read_file_b=$ff
	    else	
		read_file_f=$ff
	    fi
	    let zz++
	done
	echo "$mapper_addr aln $this_map_para $ref_fas $read_file_f > $alntemp_filf" 
    	printverifycom "IMR_BWA_SUCC" "IMRFAILED"
	echo "$mapper_addr aln $this_map_para $ref_fas $read_file_b > $alntemp_filb" 
    	printverifycom "IMR_BWA_SUCC" "IMRFAILED"
	echo "$mapper_addr sampe $bwargopt $BWASAMPE_PARA $ref_fas $alntemp_filf $alntemp_filb $read_file >$sampart_file "
    	printverifycom "IMR_BWA_SUCC" "IMRFAILED"
        echo "rm $alntemp_filf $alntemp_filb"
        printverifycom "IMR_BWA_SUCC" "IMRFAILED_rm"
    else
	echo "$mapper_addr aln $this_map_para $ref_fas $read_file > $alntemp_filf" 
    	printverifycom "IMR_BWA_SUCC" "IMRFAILED"
	echo "$mapper_addr samse $bwargopt $ref_fas $alntemp_filf $read_file >$sampart_file"
    	printverifycom "IMR_BWA_SUCC" "IMRFAILED"
        echo "rm $alntemp_filf"
        printverifycom "IMR_BWA_SUCC" "IMRFAILED_rm"
    fi
}    

function print_bwa_run {
    print_bwa_run_core
    sam2sortedbam_print $sampart_file $bampart_file
}


function print_bwamem_run_core {
    echo "echo $scriptname"
    echo "echo bwamem align"
    echo -e 'echo Running on host: `hostname`. '

    bwargopt=""
    if [ -n "$RGname" ]; then 
        rgtline=`echo "@RG $groupseq" |sed "s/[[:space:]]/\\\\\t/g" `
	bwargopt=" -R '$rgtline' " 
    fi

    echo "$mapper_addr mem $this_map_para $bwargopt $ref_fas $read_file > $sampart_file" 
    printverifycom "IMR_BWA_SUCC" "IMRFAILED"
}    
function print_bwamem_run {
    print_bwamem_run_core
    sam2sortedbam_print $sampart_file $bampart_file
}


if [ "$#" -gt 0 ]; then
   eval "$1 $2 $3 $4 $5 $6 $7 $8 $9"
fi
