/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Config file for defining DSL2 per module options and publishing paths
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Available keys to override module options:
        ext.args   = Additional arguments appended to command in module.
        ext.args2  = Second set of arguments appended to command in module (multi-tool modules).
        ext.args3  = Third set of arguments appended to command in module (multi-tool modules).
        ext.prefix = File name prefix for output files.
----------------------------------------------------------------------------------------
*/

process {

    publishDir = [
        path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
        mode: params.publish_dir_mode,
        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
    ]

    withName: 'NFCORE_RNAVAR:RNAVAR:INPUT_CHECK:SAMPLESHEET_CHECK' {
        publishDir = [
            path: { "${params.outdir}/pipeline_info" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: CUSTOM_DUMPSOFTWAREVERSIONS {
        publishDir = [
            path: { "${params.outdir}/pipeline_info" },
            mode: params.publish_dir_mode,
            pattern: '*_versions.yml'
        ]
    }
}

// PREPARE GENOME

process {

    withName: CAT_FASTQ {
        publishDir = [
            path: { "${params.outdir}/fastq" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_merged_fastq
        ]
    }

    withName: 'GUNZIP_.*' {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: 'UNTAR_.*' {
        ext.args2 = '--no-same-owner'
    }

    withName: STAR_GENOMEGENERATE {
        ext.args   = params.read_length ? "--sjdbOverhang ${params.read_length - 1}" : ''
    }

    withName: 'UNTAR_.*|STAR_GENOMEGENERATE' {
        publishDir = [
            path: { "${params.outdir}/genome/index" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: GFFREAD {
        ext.args    = '--keep-exon-attrs -F -T'
        publishDir  = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ?null : filename },
            enabled: params.save_reference
        ]
    }

    withName: GTF2BED {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: SAMTOOLS_FAIDX {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }

    withName: GATK4_CREATESEQUENCEDICTIONARY {
        publishDir = [
            path: { "${params.outdir}/genome" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: params.save_reference
        ]
    }
}

// READ QC AND QC REPORT

process {

    withName: MULTIQC {
        ext.args   = params.multiqc_title ? "--title \"$params.multiqc_title\"" : ''
        publishDir = [
            path: { "${params.outdir}/reports"},
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
            enabled: !params.skip_multiqc
        ]
    }

    withName: FASTQC {
        ext.args    = '--quiet'
        publishDir  = [
            enabled: false
        ]
    }
}

// ALIGNMENT
process {

    // ALIGN_STAR

    withName: STAR_ALIGN {
        ext.args   = [
            '--outSAMtype BAM SortedByCoordinate',
            '--readFilesCommand zcat',
            params.save_unaligned ? '--outReadsUnmapped Fastx' : '',
            params.read_length ? "--sjdbOverhang ${params.read_length - 1}" : '',
            params.star_twopass ? '--twopassMode Basic' : '',
            params.star_max_memory_bamsort > 0 ? "--limitBAMsortRAM ${params.star_max_memory_bamsort}" : "",
            params.star_bins_bamsort > 0 ? "--outBAMsortingBinsN ${params.star_bins_bamsort}" : "",
            params.star_max_collapsed_junc > 0 ? "--limitOutSJcollapsed ${params.star_max_collapsed_junc}" : ""
        ].join(' ').trim()
        publishDir = [
            [
                path: { "${params.outdir}/reports/stats/${meta.id}/STAR_log" },
                mode: params.publish_dir_mode,
                pattern: '*.{out,tab}'
            ],
            [
                path: { "${params.outdir}/preprocessing/${meta.id}" },
                mode: params.publish_dir_mode,
                pattern: '*.bam',
                enabled: false
            ],
            [
                path: { "${params.outdir}/preprocessing/${meta.id}/unmapped" },
                mode: params.publish_dir_mode,
                pattern: '*.fastq.gz',
                enabled: params.save_unaligned
            ]
        ]
    }
}

// POST ALIGNMENT AND PREPROCESSING BAM

process {

    withName: '.*:ALIGN_STAR:BAM_SORT_SAMTOOLS:SAMTOOLS_SORT' {
        ext.prefix = {"${meta.id}.aligned"}
        publishDir = [
            path: { "${params.outdir}/preprocessing/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.bam",
            enabled: params.save_align_intermeds
        ]
    }

    withName: '.*:ALIGN_STAR:BAM_SORT_SAMTOOLS:SAMTOOLS_INDEX' {
        ext.args   = params.bam_csi_index ? '-c' : ''
        ext.prefix = {"${meta.id}.aligned"}
        publishDir = [
            path: { "${params.outdir}/preprocessing/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{bai,csi}",
            enabled: params.save_align_intermeds
        ]
    }

    withName: GATK4_BEDTOINTERVALLIST {
        publishDir  = [ enabled: false ]
    }

    withName: GATK4_INTERVALLISTTOOLS {
        ext.args   = [
            '--SUBDIVISION_MODE BALANCING_WITHOUT_INTERVAL_SUBDIVISION_WITH_OVERFLOW',
            '--UNIQUE true',
            '--SORT true',
            params.gatk_interval_scatter_count ? "--SCATTER_COUNT $params.gatk_interval_scatter_count" : ''
        ].join(' ').trim()
        publishDir  = [ enabled: false ]
    }

    withName: '.*:MARKDUPLICATES:GATK4_MARKDUPLICATES' {
        ext.args   = [
            '--ASSUME_SORTED true',
            '--VALIDATION_STRINGENCY LENIENT',
            params.remove_duplicates ? '--REMOVE_DUPLICATES true' : ''
        ].join(' ').trim()
        ext.prefix = {"${meta.id}.markdup.sorted"}
        publishDir  = [
            [
                path: { "${params.outdir}/preprocessing/${meta.id}" },
                mode: params.publish_dir_mode,
                enabled: true,
                pattern: "*.{bam}"
            ],
            [
                path: { "${params.outdir}/reports/stats/${meta.id}" },
                mode: params.publish_dir_mode,
                enabled: true,
                pattern: "*.{metrics}"
            ]
        ]
    }

    withName: '.*:MARKDUPLICATES:SAMTOOLS_INDEX' {
        ext.args    = params.bam_csi_index ? '-c' : ''
        ext.prefix  = {"${meta.id}.markdup.sorted"}
        publishDir  = [
            path: { "${params.outdir}/preprocessing/${meta.id}" },
            mode: params.publish_dir_mode,
            enabled: true,
            pattern: "*.{bai,csi}"
        ]
    }

    withName: '.*:SPLITNCIGAR:GATK4_SPLITNCIGARREADS' {
        ext.args    =  '--create-output-bam-index false'
    }

    withName: '.*:SPLITNCIGAR:SAMTOOLS_INDEX' {
        ext.args    =  params.bam_csi_index ? '-c' : ''
    }

    withName: '.*:SPLITNCIGAR:.*' {
        publishDir  = [ enabled: false ]
    }

    withName: 'SAMTOOLS_STATS|SAMTOOLS_FLAGSTAT|SAMTOOLS_IDXSTATS' {
            publishDir  = [
                path: { "${params.outdir}/reports/stats/${meta.id}" },
                mode: params.publish_dir_mode,
                enabled: !params.skip_multiqc,
                pattern: "*.{stats,flagstat}"
            ]
    }

}

// BASE RECALIBRATION PROCESS
if(!params.skip_baserecalibration) {
    process {

        withName: GATK4_BASERECALIBRATOR {
            ext.args    =  '--use-original-qualities'
            publishDir  = [ enabled: false ]
        }

        withName: '.*:RECALIBRATE:APPLYBQSR' {
            ext.args    = [
                '--use-original-qualities',
                '--add-output-sam-program-record'
            ].join(' ').trim()
            ext.prefix = {"${meta.id}.recal"}
            publishDir  = [
                path: { "${params.outdir}/preprocessing/${meta.id}" },
                mode: params.publish_dir_mode,
                enabled: true,
                pattern: "*.{bam}"
            ]
        }

        withName: '.*:RECALIBRATE:SAMTOOLS_INDEX' {
            ext.args    = params.bam_csi_index ? '-c' : ''
            ext.prefix = {"${meta.id}.recal"}
            publishDir  = [
                path: { "${params.outdir}/preprocessing/${meta.id}" },
                mode: params.publish_dir_mode,
                enabled: true,
                pattern: "*.{bai,csi}"
            ]
        }
    }
}

// VARIANT CALLING AND FILTERING

process {

    withName: GATK4_HAPLOTYPECALLER {
        ext.args    = [
            '--dont-use-soft-clipped-bases',
            params.gatk_hc_call_conf ? "--standard-min-confidence-threshold-for-calling $params.gatk_hc_call_conf" : '',
            params.bam_csi_index ? "--create-output-variant-index false" : ""
        ].join(' ').trim()
        publishDir  = [ enabled: false ]
    }

    withName: GATK4_MERGEVCFS {
        ext.prefix  = {"${meta.id}.haplotypecaller"}
        ext.args    = params.bam_csi_index ? '--CREATE_INDEX false' : ''
        publishDir  = [
            path: { "${params.outdir}/variant_calling/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{vcf.gz}"
        ]
    }

    withName: TABIX_TABIX {
        ext.args    = params.bam_csi_index ? '--csi' : ''
        ext.prefix = {"${meta.id}.haplotypecaller"}
        publishDir  = [
            path: { "${params.outdir}/variant_calling/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{vcf.gz.tbi,vcf.gz.csi}"
        ]
    }

    withName: GATK4_VARIANTFILTRATION {
        ext.prefix = {"${meta.id}.haplotypecaller.filtered"}
        ext.args    = [
            params.gatk_vf_window_size ? "--window $params.gatk_vf_window_size" : '',
            params.gatk_vf_cluster_size ? "--cluster $params.gatk_vf_cluster_size" : '',
            params.gatk_vf_fs_filter ? "--filter-name \"FS\" --filter \"FS > $params.gatk_vf_fs_filter\" " : '',
            params.gatk_vf_qd_filter ? "--filter-name \"QD\" --filter \"QD < $params.gatk_vf_qd_filter\" " : '',
        ].join(' ').trim()
        publishDir  = [
            path: { "${params.outdir}/variant_calling/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{vcf.gz,vcf.gz.tbi}"
        ]
    }
}

// VARIANT ANNOTATION

process {

    withName: 'ENSEMBLVEP' {
        ext.args    = '--everything --filter_common --per_gene --total_length --offline'
        if(!params.vep_cache){
            container   = { params.genome ? "nfcore/vep:104.3.${params.genome}" : "nfcore/vep:104.3.${params.vep_genome}" }
        }
        publishDir  = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/EnsemblVEP/${meta.id}" },
            pattern: "*html",
            enabled: !params.skip_multiqc
        ]
    }

    withName: 'SNPEFF' {
        ext.args    = '-nodownload -canon -v'
        if(!params.snpeff_cache){
            container   = { params.genome ? "nfcore/snpeff:5.0.${params.genome}" : "nfcore/snpeff:5.0.${params.snpeff_db.split('\\.')[0]}" }
        }
        publishDir  = [
            mode: params.publish_dir_mode,
            path: { "${params.outdir}/reports/SnpEff/${meta.id}" },
            pattern: "*.{csv,html,txt}",
            saveAs: { params.annotate_tools.contains('snpeff') ? it : null },
            enabled: !params.skip_multiqc
        ]
    }

    withName: 'TABIX_BGZIPTABIX' {
        publishDir  = [
            path: { "${params.outdir}/variant_annotation/${meta.id}" },
            enabled: true,
            mode: params.publish_dir_mode,
            pattern: "*.{gz,gz.tbi}"
        ]
    }
}

if( (params.annotate_tools) && (params.annotate_tools.contains('snpeff')) ) {
    process {
        withName: 'NFCORE_RNAVAR:RNAVAR:ANNOTATE:SNPEFF_ANNOTATE:TABIX_BGZIPTABIX' {
            ext.prefix = {"${meta.id}_snpEff.ann.vcf"}
        }
    }
}

if( (params.annotate_tools) && (params.annotate_tools.contains('vep')) ) {
    process {
        withName: 'NFCORE_RNAVAR:RNAVAR:ANNOTATE:ENSEMBLVEP_ANNOTATE:TABIX_BGZIPTABIX' {
            ext.prefix = {"${meta.id}_VEP.ann.vcf"}
        }
    }
}

if( (params.annotate_tools) && (params.annotate_tools.contains('merge')) ) {
    process {
        withName: 'NFCORE_RNAVAR:RNAVAR:ANNOTATE:MERGE_ANNOTATE:TABIX_BGZIPTABIX' {
            ext.prefix = {"${meta.id}_snpEff_VEP.ann.vcf"}
        }
    }

    withName: FASTQC {
        ext.args = '--quiet'
    }

    withName: CUSTOM_DUMPSOFTWAREVERSIONS {
        publishDir = [
            path: { "${params.outdir}/pipeline_info" },
            mode: params.publish_dir_mode,
            pattern: '*_versions.yml'
        ]
    }

}
