/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    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 {

    //default: do not publish into the results folder
    publishDir = [
        path: { "${params.outdir}/${task.process.tokenize(':')[-1].tokenize('_')[0].toLowerCase()}" },
        mode: params.publish_dir_mode,
        saveAs: { filename -> filename.equals('versions.yml') ? null : filename },
        enabled: false
    ]

    withName: FASTQC_RAW {
        ext.args = '--quiet'
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/fastqc" },
            mode: params.publish_dir_mode,
            pattern: "*.html"
        ]
    }

    withName: FASTP {
        ext.args = [
            "-q ${params.fastp_qualified_quality}",
            "--cut_front",
            "--cut_tail",
            "--cut_mean_quality ${params.fastp_cut_mean_quality}",
            "--length_required ${params.reads_minlength}"
        ].join(' ').trim()
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/fastp/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{html,json}"
        ]
    }

    withName: ADAPTERREMOVAL_PE {
        ext.args = [
            "--minlength ${params.reads_minlength}",
            "--adapter1 ${params.adapterremoval_adapter1} --adapter2 ${params.adapterremoval_adapter2}",
            "--minquality ${params.adapterremoval_minquality} --trimns",
            params.adapterremoval_trim_quality_stretch ? "--trim_qualities" : "--trimwindows 4"
        ].join(' ').trim()
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/adapterremoval/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{log}"
        ]
        ext.prefix = { "${meta.id}_ar2" }
    }

    withName: ADAPTERREMOVAL_SE {
        ext.args = [
            "--minlength ${params.reads_minlength}",
            "--adapter1 ${params.adapterremoval_adapter1}",
            "--minquality ${params.adapterremoval_minquality} --trimns",
            params.adapterremoval_trim_quality_stretch ? "--trim_qualities" : "--trimwindows 4"
        ].join(' ').trim()
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/adapterremoval/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{log}"
        ]
        ext.prefix = { "${meta.id}_ar2" }
    }

    withName: BOWTIE2_PHIX_REMOVAL_ALIGN {
        ext.prefix = { "${meta.id}.phix_removed" }
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/remove_phix" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: BOWTIE2_HOST_REMOVAL_ALIGN {
        ext.args = params.host_removal_verysensitive ? "--very-sensitive" : "--sensitive"
        ext.args2 = params.host_removal_save_ids ? "--host_removal_save_ids" : ''
        ext.prefix = { "${meta.id}.host_removed" }
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/remove_host" },
            mode: params.publish_dir_mode,
            pattern: "*{.log,read_ids.txt}"
        ]
    }

    withName: FASTQC_TRIMMED {
        ext.args = '--quiet'
        ext.prefix = { "${meta.id}.trimmed" }
        publishDir = [
            path: { "${params.outdir}/QC_shortreads/fastqc" },
            mode: params.publish_dir_mode,
            pattern: "*.html"
        ]
    }

    withName: NANOLYSE {
        publishDir = [
            path: { "${params.outdir}/QC_longreads/NanoLyse" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: NANOPLOT_RAW {
        ext.prefix = 'raw'
        publishDir = [
            path: { "${params.outdir}/QC_longreads/NanoPlot/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{png,html,txt}"
        ]
    }

    withName: NANOPLOT_FILTERED {
        ext.prefix = 'filtered'
        publishDir = [
            path: { "${params.outdir}/QC_longreads/NanoPlot/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{png,html,txt}"
        ]
    }

    withName: CENTRIFUGE {
        publishDir = [
            path: { "${params.outdir}/Taxonomy/centrifuge/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.txt"
        ]
    }

    withName: KRAKEN2 {
        ext.args = '--quiet'
        publishDir = [
            path: { "${params.outdir}/Taxonomy/kraken2/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.txt"
        ]
    }

    withName: KRONA {
        publishDir = [
            path: { "${params.outdir}/Taxonomy/${meta.classifier}/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.html"
        ]
    }

    //pattern: "*.{fa.gz,log}" //'pattern' didnt work, probably because the output is in a folder, solved with 'saveAs'
    withName: MEGAHIT {
        ext.args = params.megahit_options ?: ''
        publishDir = [
            path: { "${params.outdir}/Assembly" },
            mode: params.publish_dir_mode,
            saveAs: {
                filename -> filename.equals('versions.yml') ? null :
                filename.indexOf('.contigs.fa.gz') > 0      ? filename :
                filename.indexOf('.log') > 0                ? filename : null }
        ]
    }

    withName: SPADES {
        ext.args = params.spades_options ?: ''
        publishDir = [
            path: { "${params.outdir}/Assembly/SPAdes" },
            mode: params.publish_dir_mode,
            pattern: "*.{fasta.gz,gfa.gz,log}"
        ]
    }

    withName: SPADESHYBRID {
        ext.args = params.spades_options ?: ''
        publishDir = [
            path: { "${params.outdir}/Assembly/SPAdesHybrid" },
            mode: params.publish_dir_mode,
            pattern: "*.{fasta.gz,gfa.gz,log}"
        ]
    }

    withName: QUAST {
        publishDir = [
            path: { "${params.outdir}/Assembly/${meta.assembler}/QC/${meta.id}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: BOWTIE2_ASSEMBLY_ALIGN {
        ext.args = params.bowtie2_mode ? params.bowtie2_mode : params.ancient_dna ? '--very-sensitive-local -N 1' : ''
        publishDir = [
            path: { "${params.outdir}/Assembly/${assembly_meta.assembler}/QC/${assembly_meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.log"
        ]
    }

    withName: 'MAG_DEPTHS_PLOT|MAG_DEPTHS_SUMMARY|MAG_DEPTHS_PLOT_REFINED' {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/depths/bins" },
            mode: params.publish_dir_mode,
            pattern: "*.{png,tsv}"
        ]
    }

    withName: 'MAG_DEPTHS_SUMMARY_REFINED' {
        ext.prefix = "bin_refined_depths_summary"
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/depths/bins" },
            mode: params.publish_dir_mode,
            pattern: "*.{tsv}"
        ]
    }

    withName: 'BIN_SUMMARY' {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning" },
            mode: params.publish_dir_mode,
            pattern: "*.{png,tsv}"
        ]
    }

    withName: BUSCO_DB_PREPARATION {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/QC/BUSCO" },
            mode: params.publish_dir_mode,
            pattern: "*.tar.gz"
        ]
    }

    withName: 'BUSCO' {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/QC/BUSCO" },
            mode: params.publish_dir_mode,
            pattern: "*.{log,err,faa.gz,fna.gz,gff,txt}"
        ]
    }

    withName: BUSCO_SAVE_DOWNLOAD {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/QC/BUSCO" },
            mode: params.publish_dir_mode,
            overwrite: false,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'BUSCO_PLOT' {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/QC/BUSCO" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: 'BUSCO_SUMMARY|QUAST_BINS|QUAST_BINS_SUMMARY' {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/QC" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: CAT_DB_GENERATE {
        publishDir = [
            path: { "${params.outdir}/Taxonomy/CAT" },
            mode: params.publish_dir_mode,
            pattern: "*.tar.gz"
        ]
    }

    withName: CAT {
        publishDir = [
            path: { "${params.outdir}/Taxonomy/CAT/${meta.assembler}/${meta.binner}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: GTDBTK_CLASSIFY {
        ext.args   = "--extension fa"
        publishDir = [
            path: { "${params.outdir}/Taxonomy/GTDB-Tk/${meta.assembler}/${meta.binner}/${meta.id}" },
            mode: params.publish_dir_mode,
            pattern: "*.{log,tasv,tree.gz,fasta,fasta.gz}"
        ]
    }

    withName: GTDBTK_SUMMARY {
        ext.args   = "--extension fa"
        publishDir = [
            path: { "${params.outdir}/Taxonomy/GTDB-Tk" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

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

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

    withName: PRODIGAL {
        ext.args   = "-p meta"
        publishDir = [
            path: { "${params.outdir}/Prodigal/${meta.assembler}/${meta.id}" },
            mode: params.publish_dir_mode,
            saveAs: { filename -> filename.equals('versions.yml') ? null : filename }
        ]
    }

    withName: FREEBAYES {
        ext.args   = "-p ${params.freebayes_ploidy} -q ${params.freebayes_min_basequality} -F ${params.freebayes_minallelefreq}"
        publishDir = [
            path: { "${params.outdir}/Ancient_DNA/variant_calling/freebayes" },
            mode: params.publish_dir_mode,
            pattern: "*.vcf.gz"
        ]
    }

    withName: BCFTOOLS_VIEW {
        ext.args   = "-v snps,mnps -i 'QUAL>=${params.bcftools_view_high_variant_quality} || (QUAL>=${params.bcftools_view_medium_variant_quality} && FORMAT/AO>=${params.bcftools_view_minimal_allelesupport})'"
        ext.prefix = { "${meta.id}.filtered" }
        publishDir = [
            path: { "${params.outdir}/Ancient_DNA/variant_calling/filtered" },
            mode: params.publish_dir_mode,
            pattern: "*.vcf.gz"
        ]
    }

    withName: BCFTOOLS_CONSENSUS {
        publishDir = [
            path: {"${params.outdir}/Ancient_DNA/variant_calling/consensus" },
            mode: params.publish_dir_mode,
            pattern: "*.fa"
        ]
    }

    withName: BCFTOOLS_INDEX {
        ext.args   = "-t"
        publishDir = [
            path: {"${params.outdir}/Ancient_DNA/variant_calling/index" },
            mode: params.publish_dir_mode,
            enabled: false
        ]
    }

    withName: PYDAMAGE_ANALYZE {
        publishDir = [
            path: {"${params.outdir}/Ancient_DNA/pydamage/analyze/${meta.id}" },
            mode: params.publish_dir_mode
        ]
    }

    withName: PYDAMAGE_FILTER {
        ext.args   = "-t ${params.pydamage_accuracy}"
        publishDir = [
            path: {"${params.outdir}/Ancient_DNA/pydamage/filter/${meta.id}" },
            mode: params.publish_dir_mode
        ]
    }

    withName: SAMTOOLS_FAIDX {
        publishDir = [
            path: {"${params.outdir}/Ancient_DNA/samtools/faidx" },
            mode: params.publish_dir_mode,
            enabled: false
        ]
    }
    withName: METABAT2_JGISUMMARIZEBAMCONTIGDEPTHS {
        publishDir = [
            path: { "${params.outdir}/GenomeBinning/depths/contigs" },
            mode: params.publish_dir_mode,
            pattern: '*-depth.txt.gz'
        ]
        ext.prefix = { "${meta.assembler}-${meta.id}-depth" }
    }

    withName: METABAT2_METABAT2 {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/MetaBAT2/" },
                mode: params.publish_dir_mode,
                pattern: 'bins/*.fa.gz'
            ],
            [
                path: { "${params.outdir}/GenomeBinning/MetaBAT2/discarded" },
                mode: params.publish_dir_mode,
                pattern: '*tooShort.fa.gz'
            ],
            [
                path: { "${params.outdir}/GenomeBinning/MetaBAT2/discarded" },
                mode: params.publish_dir_mode,
                pattern: '*lowDepth.fa.gz'
            ]
        ]
        ext.prefix = { "${meta.assembler}-MetaBAT2-${meta.id}" }
        ext.args = [
            "-m ${params.min_contig_size}",
            "--unbinned",
            "--seed ${params.metabat_rng_seed}"
        ].join(' ').trim()
    }

    withName: MAXBIN2 {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/MaxBin2/discarded" },
                mode: params.publish_dir_mode,
                pattern: '*.tooshort.gz'
            ],
        ]
        ext.prefix = { "${meta.assembler}-MaxBin2-${meta.id}" }
        // if no gene found, will crash so allow ignore so rest of pipeline
        // completes but without MaxBin2 results
    }

    withName: ADJUST_MAXBIN2_EXT {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/MaxBin2/bins/" },
                mode: params.publish_dir_mode,
                pattern: '*.fa.gz'
            ],
        ]
    }

    withName: SPLIT_FASTA {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/${meta.binner}/unbinned" },
                mode: params.publish_dir_mode,
                pattern: '*.*[0-9].fa.gz'
            ],
            [
                path: { "${params.outdir}/GenomeBinning/${meta.binner}/unbinned/discarded" },
                mode: params.publish_dir_mode,
                pattern: '*.pooled.fa.gz'
            ],
            [
                path: { "${params.outdir}/GenomeBinning/${meta.binner}/unbinned/discarded" },
                mode: params.publish_dir_mode,
                pattern: '*.remaining.fa.gz'
            ]
        ]
    }

    withName: DASTOOL_FASTATOCONTIG2BIN_METABAT2 {
        ext.prefix = { "${meta.assembler}-MetaBAT2-${meta.id}" }
    }

    withName: DASTOOL_FASTATOCONTIG2BIN_MAXBIN2 {
        ext.prefix = { "${meta.assembler}-MaxBin2-${meta.id}" }
    }

    withName: DASTOOL_DASTOOL {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/DASTool" },
                mode: params.publish_dir_mode,
                pattern: '*.{tsv,log,eval,seqlength}'
            ],
        ]
        ext.prefix = { "${meta.assembler}-DASTool-${meta.id}" }
        ext.args = "--write_bins --write_unbinned --write_bin_evals --score_threshold ${params.refine_bins_dastool_threshold}"
    }

    withName: RENAME_POSTDASTOOL {
        publishDir = [
            [
                path: { "${params.outdir}/GenomeBinning/DASTool/unbinned" },
                mode: params.publish_dir_mode,
                pattern: '*-DASToolUnbinned-*.fa'
            ],
            [
                path: { "${params.outdir}/GenomeBinning/DASTool/bins" },
                mode: params.publish_dir_mode,
                // pattern needs to be updated in case of new binning methods
                pattern: '*-{MetaBAT2,MaxBin2}Refined-*.fa'
            ]
        ]
    }

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

}
