/*
========================================================================================
    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.
----------------------------------------------------------------------------------------
*/

def variant_caller = params.variant_caller
if (!variant_caller) { variant_caller = params.protocol == 'amplicon' ? 'ivar' : 'bcftools' }

def assemblers = params.assemblers ? params.assemblers.split(',').collect{ it.trim().toLowerCase() } : []

//
// Pre-processing and general configuration options
//

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

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

    withName: 'CAT_FASTQ' {
        publishDir = [
            path: { "${params.outdir}/fastq" },
            enabled: false
        ]
    }
}

if (!params.skip_fastqc) {
    process {
        withName: '.*:.*:FASTQC_FASTP:FASTQC_RAW' {
            ext.args = '--quiet'
            publishDir = [
                path: { "${params.outdir}/fastqc/raw" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
            ]
        }
    }
}

if (!params.skip_fastp) {
    process {
        withName: 'FASTP' {
            ext.args = '--cut_front --cut_tail --trim_poly_x --cut_mean_quality 30 --qualified_quality_phred 30 --unqualified_percent_limit 10 --length_required 50'
            publishDir = [
                [
                    path: { "${params.outdir}/fastp" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{json,html}"
                ],
                [
                    path: { "${params.outdir}/fastp/log" },
                    mode: params.publish_dir_mode,
                    pattern: "*.log"
                ],
                [
                    path: { "${params.outdir}/fastp" },
                    mode: params.publish_dir_mode,
                    pattern: "*.fail.fastq.gz",
                    enabled: params.save_trimmed_fail
                ]
            ]
        }

        withName: 'MULTIQC_TSV_FAIL_READS' {
            publishDir = [
                path: { "${params.outdir}/multiqc" },
                enabled: false
            ]
        }
    }

    if (!params.skip_fastqc) {
        process {
            withName: '.*:.*:FASTQC_FASTP:FASTQC_TRIM' {
                ext.args = '--quiet'
                publishDir = [
                    path: { "${params.outdir}/fastqc/trim" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }
}

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

        withName: 'KRAKEN2_KRAKEN2' {
            ext.args = '--report-zero-counts'
            publishDir = [
                path: { "${params.outdir}/kraken2" },
                mode: params.publish_dir_mode,
                pattern: "*.txt"
            ]
        }
    }
}

//
// Variant calling configuration options
//

if (!params.skip_variants) {
    process {
        withName: 'BOWTIE2_BUILD' {
            ext.args = '--seed 1'
            publishDir = [
                path: { "${params.outdir}/genome" },
                mode: params.publish_dir_mode,
                saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
                enabled: params.save_reference
            ]
        }

        withName: 'BOWTIE2_ALIGN' {
            ext.args = '--local --very-sensitive-local --seed 1'
            ext.args2 = '-F4'
            publishDir = [
                [
                    path: { "${params.outdir}/variants/bowtie2/log" },
                    mode: params.publish_dir_mode,
                    pattern: "*.log"
                ],
                [
                    path: { "${params.outdir}/variants/bowtie2/unmapped" },
                    mode: params.publish_dir_mode,
                    pattern: "*.fastq.gz",
                    enabled: params.save_unaligned
                ]
            ]
        }

        withName: '.*:.*:ALIGN_BOWTIE2:.*:SAMTOOLS_SORT' {
            ext.prefix = { "${meta.id}.sorted" }
            publishDir = [
                path: { "${params.outdir}/variants/bowtie2" },
                mode: params.publish_dir_mode,
                pattern: "*.bam"
            ]
        }

        withName: '.*:.*:ALIGN_BOWTIE2:.*:SAMTOOLS_INDEX' {
            publishDir = [
                path: { "${params.outdir}/variants/bowtie2" },
                mode: params.publish_dir_mode,
                pattern: "*.bai"
            ]
        }

        withName: '.*:.*:ALIGN_BOWTIE2:.*:BAM_STATS_SAMTOOLS:.*' {
            publishDir = [
                path: { "${params.outdir}/variants/bowtie2/samtools_stats" },
                mode: params.publish_dir_mode,
                pattern: "*.{stats,flagstat,idxstats}"
            ]
        }

        withName: 'MULTIQC_TSV_FAIL_MAPPED' {
            publishDir = [
                path: { "${params.outdir}/multiqc" },
                enabled: false
            ]
        }
    }

    if (params.protocol == 'amplicon' || !params.skip_asciigenome) {
        process {
            withName: 'CUSTOM_GETCHROMSIZES' {
                publishDir = [
                    path: { "${params.outdir}/genome" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
                    enabled: params.save_reference
                ]
            }
        }
    }

    if (!params.skip_ivar_trim && params.protocol == 'amplicon') {
        process {
            withName: 'IVAR_TRIM' {
                ext.args = [
                    '-m 30 -q 20',
                    params.ivar_trim_noprimer ? '' : '-e',
                    params.ivar_trim_offset   ? "-x ${params.ivar_trim_offset}" : ''
                ].join(' ').trim()
                ext.prefix = { "${meta.id}.ivar_trim" }
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.log'
                ]
            }

            withName: '.*:.*:PRIMER_TRIM_IVAR:.*:SAMTOOLS_SORT' {
                ext.prefix = { "${meta.id}.ivar_trim.sorted" }
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2" },
                    mode: params.publish_dir_mode,
                    pattern: "*.bam",
                    enabled: params.skip_markduplicates
                ]
            }

            withName: '.*:.*:PRIMER_TRIM_IVAR:.*:SAMTOOLS_INDEX' {
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2" },
                    mode: params.publish_dir_mode,
                    pattern: "*.bai",
                    enabled: params.skip_markduplicates
                ]
            }

            withName: '.*:.*:PRIMER_TRIM_IVAR:.*:BAM_STATS_SAMTOOLS:.*' {
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2/samtools_stats" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{stats,flagstat,idxstats}"
                ]
            }
        }
    }

    if (!params.skip_markduplicates) {
        process {
            withName: 'PICARD_MARKDUPLICATES' {
                ext.args = [
                    'ASSUME_SORTED=true VALIDATION_STRINGENCY=LENIENT TMP_DIR=tmp',
                    params.filter_duplicates ? 'REMOVE_DUPLICATES=true' : ''
                ].join(' ').trim()
                ext.prefix = { "${meta.id}.markduplicates.sorted" }
                publishDir = [
                    [
                        path: { "${params.outdir}/variants/bowtie2/picard_metrics" },
                        mode: params.publish_dir_mode,
                        pattern: '*metrics.txt'
                    ],
                    [
                        path: { "${params.outdir}/variants/bowtie2" },
                        mode: params.publish_dir_mode,
                        pattern: '*.bam'
                    ]
                ]
            }

            withName: '.*:MARK_DUPLICATES_PICARD:SAMTOOLS_INDEX' {
                ext.prefix = { "${meta.id}.markduplicates.sorted" }
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2" },
                    mode: params.publish_dir_mode,
                    pattern: '*.bai'
                ]
            }

            withName: '.*:MARK_DUPLICATES_PICARD:BAM_STATS_SAMTOOLS:.*' {
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2/samtools_stats" },
                    mode: params.publish_dir_mode,
                    pattern: '*.{stats,flagstat,idxstats}'
                ]
            }
        }
    }

    if (!params.skip_picard_metrics) {
        process {
            withName: 'PICARD_COLLECTMULTIPLEMETRICS' {
                ext.args = 'VALIDATION_STRINGENCY=LENIENT TMP_DIR=tmp'
                publishDir = [
                    [
                        path: { "${params.outdir}/variants/bowtie2/picard_metrics" },
                        mode: params.publish_dir_mode,
                        pattern: '*metrics'
                    ],
                    [
                        path: { "${params.outdir}/variants/bowtie2/picard_metrics/pdf" },
                        mode: params.publish_dir_mode,
                        pattern: '*.pdf'
                    ]
                ]
            }
        }
    }

    if (!params.skip_mosdepth) {
        process {
            withName: 'MOSDEPTH_GENOME' {
                ext.args = '--fast-mode'
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2/mosdepth/genome" },
                    mode: params.publish_dir_mode,
                    pattern: "*.summary.txt"
                ]
            }

            withName: 'PLOT_MOSDEPTH_REGIONS_GENOME' {
                ext.args = '--input_suffix .regions.bed.gz'
                publishDir = [
                    path: { "${params.outdir}/variants/bowtie2/mosdepth/genome" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{tsv,pdf}"
                ]
            }
        }

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

                withName: 'MOSDEPTH_AMPLICON' {
                    ext.args = '--fast-mode --use-median --thresholds 0,1,10,50,100,500'
                    publishDir = [
                        path: { "${params.outdir}/variants/bowtie2/mosdepth/amplicon" },
                        mode: params.publish_dir_mode,
                        pattern: "*.summary.txt"
                    ]
                }

                withName: 'PLOT_MOSDEPTH_REGIONS_AMPLICON' {
                    ext.args = '--input_suffix .regions.bed.gz'
                    publishDir = [
                        path: { "${params.outdir}/variants/bowtie2/mosdepth/amplicon" },
                        mode: params.publish_dir_mode,
                        pattern: "*.{tsv,pdf}"
                    ]
                }
            }
        }
    }

    if (variant_caller == 'ivar') {
        process {
            withName: 'IVAR_VARIANTS' {
                ext.args = '-t 0.25 -q 20 -m 10'
                ext.args2 = '--ignore-overlaps --count-orphans --no-BAQ --max-depth 0 --min-BQ 0'
                publishDir = [
                    path: { "${params.outdir}/variants/ivar" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: 'IVAR_VARIANTS_TO_VCF' {
                ext.args = params.protocol == 'amplicon' ? '--ignore_strand_bias' : ''
                publishDir = [
                    path: { "${params.outdir}/variants/ivar/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.log'
                ]
            }

            withName: '.*:.*:VARIANTS_IVAR:.*:TABIX_BGZIP' {
                publishDir = [
                    path: { "${params.outdir}/variants/ivar" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:VARIANTS_IVAR:.*:.*:TABIX_TABIX' {
                ext.args = '-p vcf -f'
                publishDir = [
                    path: { "${params.outdir}/variants/ivar" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:VARIANTS_IVAR:.*:.*:BCFTOOLS_STATS' {
                publishDir = [
                    path: { "${params.outdir}/variants/ivar/bcftools_stats" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (variant_caller == 'bcftools') {
        process {
            withName: 'BCFTOOLS_MPILEUP' {
                ext.args = '--ignore-overlaps --count-orphans --no-BAQ --max-depth 0 --min-BQ 20 --annotate FORMAT/AD,FORMAT/ADF,FORMAT/ADR,FORMAT/DP,FORMAT/SP,INFO/AD,INFO/ADF,INFO/ADR'
                ext.args2 = '--ploidy 1 --keep-alts --keep-masked-ref --multiallelic-caller --variants-only'
                ext.args3 = "--include 'INFO/DP>=10'"
                ext.prefix = { "${meta.id}.orig" }
                publishDir = [
                    path: { "${params.outdir}/variants/bcftools" },
                    mode: params.publish_dir_mode,
                    pattern: '*.mpileup',
                    enabled: params.save_mpileup
                ]
            }

            withName: 'BCFTOOLS_NORM' {
                ext.args = '--do-not-normalize --output-type z --multiallelics -any'
                publishDir = [
                    path: { "${params.outdir}/variants/bcftools" },
                    mode: params.publish_dir_mode,
                    pattern: "*.vcf.gz"
                ]
            }

            withName: '.*:.*:VARIANTS_BCFTOOLS:.*:TABIX_TABIX' {
                ext.args = '-p vcf -f'
                publishDir = [
                    path: { "${params.outdir}/variants/bcftools" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:VARIANTS_BCFTOOLS:.*:BCFTOOLS_STATS' {
                publishDir = [
                    path: { "${params.outdir}/variants/bcftools/bcftools_stats" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_asciigenome) {
        process {
            withName: 'ASCIIGENOME' {
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/asciigenome/${meta.id}" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

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

            withName: 'SNPEFF_ANN' {
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/snpeff" },
                    mode: params.publish_dir_mode,
                    pattern: "*.{csv,txt,html}"
                ]
            }

            withName: '.*:.*:.*:.*:SNPEFF_SNPSIFT:.*:TABIX_BGZIP' {
                ext.prefix = { "${meta.id}.snpeff" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/snpeff" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:.*:.*:SNPEFF_SNPSIFT:.*:.*:TABIX_TABIX' {
                ext.args = '-p vcf -f'
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/snpeff" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:.*:.*:SNPEFF_SNPSIFT:.*:.*:BCFTOOLS_STATS' {
                ext.prefix = { "${meta.id}.snpeff" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/snpeff/bcftools_stats" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:.*:.*:SNPEFF_SNPSIFT:SNPSIFT_EXTRACTFIELDS' {
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/snpeff" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }

        if (!params.skip_variants_long_table) {
            process {
                withName: 'BCFTOOLS_QUERY' {
                    ext.args = [
                        variant_caller == 'ivar'     ? "-H -f '%CHROM\\t%POS\\t%REF\\t%ALT\\t%FILTER\\t[%DP\\t]\\t[%REF_DP\\t]\\t[%ALT_DP\\t]\\n'" : '',
                        variant_caller == 'bcftools' ? "-H -f '%CHROM\\t%POS\\t%REF\\t%ALT\\t%FILTER\\t[%DP\\t]\\t[%AD\\t]\\n'" : '',
                    ].join(' ').trim()
                    ext.prefix = { "${meta.id}.bcftools_query" }
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}" },
                        enabled: false
                    ]
                }

                withName: 'MAKE_VARIANTS_LONG_TABLE' {
                    ext.args = "--variant_caller ${variant_caller}"
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }

    if (!params.skip_consensus && params.consensus_caller == 'ivar') {
        process {
            withName: 'IVAR_CONSENSUS' {
                ext.args = '-t 0.75 -q 20 -m 10 -n N'
                ext.args2 = '--count-orphans --no-BAQ --max-depth 0 --min-BQ 0 -aa'
                ext.prefix = { "${meta.id}.consensus" }
                publishDir = [
                    [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/ivar" },
                        mode: params.publish_dir_mode,
                        pattern: "*.{fa,txt}",
                    ],
                    [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/ivar" },
                        mode: params.publish_dir_mode,
                        pattern: "*.mpileup",
                        enabled: params.save_mpileup
                    ]
                ]
            }
        }
    }

    if (!params.skip_consensus && params.consensus_caller == 'bcftools') {
        process {
            withName: 'BCFTOOLS_FILTER' {
                ext.args   = [
                    '--output-type z',
                    variant_caller == 'ivar'     ? "--include 'FORMAT/ALT_FREQ >= 0.75'"           : '',
                    variant_caller == 'bcftools' ? "--include 'FORMAT/AD[:1] / FORMAT/DP >= 0.75'" : '',
                ].join(' ').trim()
                ext.prefix = { "${meta.id}.filtered" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: '.*:.*:CONSENSUS_BCFTOOLS:TABIX_TABIX' {
                ext.args = '-p vcf -f'
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }

            withName: 'MAKE_BED_MASK' {
                ext.args = "-a --ignore-overlaps --count-orphans --no-BAQ --max-depth 0 --min-BQ 0"
                ext.args2 = 10
                ext.prefix = { "${meta.id}.coverage.masked" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    mode: params.publish_dir_mode,
                    pattern: "*.mpileup",
                    enabled: params.save_mpileup
                ]
            }

            withName: 'BEDTOOLS_MERGE' {
                ext.prefix = { "${meta.id}.coverage.merged" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    enabled: false
                ]
            }

            withName: 'BEDTOOLS_MASKFASTA' {
                ext.prefix = { "${meta.id}.masked" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    enabled: false
                ]
            }

            withName: 'BCFTOOLS_CONSENSUS' {
                ext.prefix = { "${meta.id}" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    enabled: false
                ]
            }

            withName: 'RENAME_FASTA_HEADER' {
                ext.prefix = { "${meta.id}.consensus" }
                publishDir = [
                    path: { "${params.outdir}/variants/${variant_caller}/consensus/bcftools" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }
    }

    if (!params.skip_consensus) {
        if (!params.skip_pangolin) {
            process {
                withName: 'PANGOLIN' {
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/${params.consensus_caller}/pangolin" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_nextclade) {
            process {
                withName: 'NEXTCLADE_RUN' {
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/${params.consensus_caller}/nextclade" },
                        mode: params.publish_dir_mode,
                        pattern: "*.csv"
                    ]
                }

                withName: 'MULTIQC_TSV_NEXTCLADE' {
                    publishDir = [
                        path: { "${params.outdir}/multiqc" },
                        enabled: false
                    ]
                }
            }
        }

        if (!params.skip_variants_quast) {
            process {
                withName: '.*:.*:CONSENSUS_.*:.*:QUAST' {
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/${params.consensus_caller}" },
                        mode: params.publish_dir_mode,
                        pattern: "quast"
                    ]
                }
            }
        }

        if (!params.skip_consensus_plots) {
            process {
                withName: 'PLOT_BASE_DENSITY' {
                    ext.prefix = { "${meta.id}.consensus" }
                    publishDir = [
                        path: { "${params.outdir}/variants/${variant_caller}/consensus/${params.consensus_caller}/base_qc" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }
}

if (!params.skip_assembly) {
    if (!params.skip_blast) {
        process {
            withName: 'BLAST_MAKEBLASTDB' {
                ext.args = '-parse_seqids -dbtype nucl'
                publishDir = [
                    path: { "${params.outdir}/genome" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
                    enabled: params.save_reference
                ]
            }
        }
    }

    if (params.protocol == 'amplicon' && !params.skip_cutadapt) {
        process {
            withName: 'BEDTOOLS_GETFASTA' {
                ext.args = '-s -nameOnly'
                publishDir = [
                    path: { "${params.outdir}/genome" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
                    enabled: params.save_reference
                ]
            }

            withName: 'CUTADAPT' {
                ext.args = '--overlap 5 --minimum-length 30 --error-rate 0.1'
                ext.prefix = { "${meta.id}.primer_trim" }
                publishDir = [
                    path: { "${params.outdir}/assembly/cutadapt/log" },
                    mode: params.publish_dir_mode,
                    pattern: '*.log'
                ]
            }
        }

        if (!params.skip_fastqc) {
            process {
                withName: '.*:.*:FASTQC' {
                    ext.args = '--quiet'
                    ext.prefix = { "${meta.id}.primer_trim" }
                    publishDir = [
                        path: { "${params.outdir}/assembly/cutadapt/fastqc" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }

    if ('spades' in assemblers) {
        process {
            withName: 'SPADES' {
                ext.args = params.spades_mode ? "--${params.spades_mode}" : ''
                publishDir = [
                    [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}" },
                        mode: params.publish_dir_mode,
                        pattern: '*.{fa.gz,gfa.gz}'
                    ],
                    [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/log" },
                        mode: params.publish_dir_mode,
                        pattern: '*.log'
                    ]
                ]
            }

            withName: '.*:.*:ASSEMBLY_SPADES:GUNZIP_SCAFFOLDS' {
                publishDir = [
                    path: { "${params.outdir}/assembly/spades/${params.spades_mode}" },
                    enabled: false
                ]
            }

            withName: '.*:.*:ASSEMBLY_SPADES:GUNZIP_GFA' {
                publishDir = [
                    path: { "${params.outdir}/assembly/spades/${params.spades_mode}" },
                    enabled: false
                ]
            }
        }

        if (!params.skip_bandage) {
            process {
                withName: '.*:.*:ASSEMBLY_SPADES:BANDAGE_IMAGE' {
                    ext.args = '--height 1000'
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/bandage" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_blast) {
            process {
                withName: '.*:.*:ASSEMBLY_SPADES:.*:BLAST_BLASTN' {
                    ext.args = "-outfmt '6 stitle std slen qlen qcovs'"
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }

                withName: '.*:.*:ASSEMBLY_SPADES:.*:FILTER_BLASTN' {
                    ext.prefix = { "${meta.id}.filter.blastn" }
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_assembly_quast) {
            process {
                withName: '.*:.*:ASSEMBLY_SPADES:.*:QUAST' {
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}" },
                        mode: params.publish_dir_mode,
                        pattern: "quast"
                    ]
                }
            }
        }

        if (!params.skip_abacas) {
            process {
                withName: '.*:.*:ASSEMBLY_SPADES:.*:ABACAS' {
                    ext.args = '-m -p nucmer'
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/abacas" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_plasmidid) {
            process {
                withName: '.*:.*:ASSEMBLY_SPADES:.*:PLASMIDID' {
                    ext.args = '--only-reconstruct -C 47 -S 47 -i 60 --no-trim -k 0.80'
                    publishDir = [
                        path: { "${params.outdir}/assembly/spades/${params.spades_mode}/plasmidid" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }

    if ('unicycler' in assemblers) {
        process {
            withName: 'UNICYCLER' {
                publishDir = [
                    [
                        path: { "${params.outdir}/assembly/unicycler" },
                        mode: params.publish_dir_mode,
                        pattern: '*.{fa.gz,gfa.gz}'
                    ],
                    [
                        path: { "${params.outdir}/assembly/unicycler/log" },
                        mode: params.publish_dir_mode,
                        pattern: '*.log'
                    ]
                ]
            }

            withName: '.*:.*:ASSEMBLY_UNICYCLER:GUNZIP_SCAFFOLDS' {
                publishDir = [
                    path: { "${params.outdir}/assembly/unicycler" },
                    enabled: false
                ]
            }

            withName: '.*:.*:ASSEMBLY_UNICYCLER:GUNZIP_GFA' {
                publishDir = [
                    path: { "${params.outdir}/assembly/unicycler" },
                    enabled: false
                ]
            }
        }

        if (!params.skip_bandage) {
            process {
                withName: '.*:.*:ASSEMBLY_UNICYCLER:BANDAGE_IMAGE' {
                    ext.args = '--height 1000'
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler/bandage" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_blast) {
            process {
                withName: '.*:.*:ASSEMBLY_UNICYCLER:.*:BLAST_BLASTN' {
                    ext.args = "-outfmt '6 stitle std slen qlen qcovs'"
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }

                withName: '.*:.*:ASSEMBLY_UNICYCLER:.*:FILTER_BLASTN' {
                    ext.prefix = { "${meta.id}.filter.blastn" }
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_assembly_quast) {
            process {
                withName: '.*:.*:ASSEMBLY_UNICYCLER:.*:QUAST' {
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler" },
                        mode: params.publish_dir_mode,
                        pattern: "quast"
                    ]
                }
            }
        }

        if (!params.skip_abacas) {
            process {
                withName: '.*:.*:ASSEMBLY_UNICYCLER:.*:ABACAS' {
                    ext.args = '-m -p nucmer'
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler/abacas" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_plasmidid) {
            process {
                withName: '.*:.*:ASSEMBLY_UNICYCLER:.*:PLASMIDID' {
                    ext.args = '--only-reconstruct -C 47 -S 47 -i 60 --no-trim -k 0.80'
                    publishDir = [
                        path: { "${params.outdir}/assembly/unicycler/plasmidid" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }

    if ('minia' in assemblers) {
        process {
            withName: 'MINIA' {
                ext.args = '-kmer-size 31 -abundance-min 20'
                publishDir = [
                    path: { "${params.outdir}/assembly/minia" },
                    mode: params.publish_dir_mode,
                    saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                ]
            }
        }

        if (!params.skip_blast) {
            process {
                withName: '.*:.*:ASSEMBLY_MINIA:.*:BLAST_BLASTN' {
                    ext.args = "-outfmt '6 stitle std slen qlen qcovs'"
                    publishDir = [
                        path: { "${params.outdir}/assembly/minia/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }

                withName: '.*:.*:ASSEMBLY_MINIA:.*:FILTER_BLASTN' {
                    ext.prefix = { "${meta.id}.filter.blastn" }
                    publishDir = [
                        path: { "${params.outdir}/assembly/minia/blastn" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_assembly_quast) {
            process {
                withName: '.*:.*:ASSEMBLY_MINIA:.*:QUAST' {
                    publishDir = [
                        path: { "${params.outdir}/assembly/minia" },
                        mode: params.publish_dir_mode,
                        pattern: "quast"
                    ]
                }
            }
        }

        if (!params.skip_abacas) {
            process {
                withName: '.*:.*:ASSEMBLY_MINIA:.*:ABACAS' {
                    ext.args = '-m -p nucmer'
                    publishDir = [
                        path: { "${params.outdir}/assembly/minia/abacas" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }

        if (!params.skip_plasmidid) {
            process {
                withName: '.*:.*:ASSEMBLY_MINIA:.*:PLASMIDID' {
                    ext.args = '--only-reconstruct -C 47 -S 47 -i 60 --no-trim -k 0.80'
                    publishDir = [
                        path: { "${params.outdir}/assembly/minia/plasmidid" },
                        mode: params.publish_dir_mode,
                        saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
                    ]
                }
            }
        }
    }
}

if (!params.skip_multiqc) {
    process {
        withName: 'MULTIQC' {
            ext.args = params.multiqc_title ? "--title \"$params.multiqc_title\"" : ''
            publishDir = [
                [
                    path: { "${params.outdir}/multiqc" },
                    mode: params.publish_dir_mode,
                    pattern: 'multiqc*'
                ],
                [
                    path: { "${params.outdir}/multiqc" },
                    mode: params.publish_dir_mode,
                    pattern: '*variants_metrics_mqc.csv',
                    enabled: !params.skip_variants
                ],
                [
                    path: { "${params.outdir}/multiqc" },
                    mode: params.publish_dir_mode,
                    pattern: '*assembly_metrics_mqc.csv',
                    enabled: !params.skip_assembly
                ]
            ]
        }
    }
}
