/*
 * -------------------------------------------------
 *  nf-core/mag Nextflow base config file
 * -------------------------------------------------
 * A 'blank slate' config file, appropriate for general
 * use on most high performace compute environments.
 * Assumes that all software is installed and available
 * on the PATH. Runs in `local` mode - all jobs will be
 * run on the logged in environment.
 */

process {

  cpus   = { check_max( 1    * task.attempt, 'cpus'   ) }
  memory = { check_max( 7.GB * task.attempt, 'memory' ) }
  time   = { check_max( 4.h  * task.attempt, 'time'   ) }

  errorStrategy = { task.exitStatus in [143,137,104,134,139] ? 'retry' : 'finish' }
  maxRetries    = 3
  maxErrors     = '-1'

  // Process-specific resource requirements
  withLabel:process_low {
    cpus   = { check_max( 2     * task.attempt, 'cpus'   ) }
    memory = { check_max( 12.GB * task.attempt, 'memory' ) }
    time   = { check_max( 4.h   * task.attempt, 'time'   ) }
  }
  withLabel:process_medium {
    cpus   = { check_max( 6     * task.attempt, 'cpus'   ) }
    memory = { check_max( 36.GB * task.attempt, 'memory' ) }
    time   = { check_max( 8.h   * task.attempt, 'time'   ) }
  }
  withLabel:process_high {
    cpus   = { check_max( 12    * task.attempt, 'cpus'   ) }
    memory = { check_max( 72.GB * task.attempt, 'memory' ) }
    time   = { check_max( 16.h  * task.attempt, 'time'   ) }
  }
  withLabel:process_long {
    time   = { check_max( 20.h  * task.attempt, 'time'   ) }
  }
  withLabel:error_ignore {
    errorStrategy = 'ignore'
  }
  withLabel:error_retry {
    errorStrategy = 'retry'
    maxRetries    = 2
  }

  withName: BOWTIE2_HOST_REMOVAL_BUILD {
    cpus   = { check_max (10    * task.attempt, 'cpus'   ) }
    memory = { check_max (20.GB * task.attempt, 'memory' ) }
    time   = { check_max (4.h   * task.attempt, 'time'   ) }
  }
  withName: BOWTIE2_HOST_REMOVAL_ALIGN {
    cpus   = { check_max (10    * task.attempt, 'cpus'   ) }
    memory = { check_max (10.GB * task.attempt, 'memory' ) }
    time   = { check_max (6.h   * task.attempt, 'time'   ) }
  }
  withName: BOWTIE2_PHIX_REMOVAL_ALIGN {
    cpus   = { check_max (4    * task.attempt, 'cpus'   ) }
    memory = { check_max (8.GB * task.attempt, 'memory' ) }
    time   = { check_max (6.h  * task.attempt, 'time'   ) }
  }
  withName: PORECHOP {
    cpus   = { check_max (4     * task.attempt, 'cpus'   ) }
    memory = { check_max (30.GB * task.attempt, 'memory' ) }
    time   = { check_max (4.h   * task.attempt, 'time'   ) }
  }
  withName: NANOLYSE {
    cpus   = { check_max (2     * task.attempt, 'cpus'   ) }
    memory = { check_max (10.GB * task.attempt, 'memory' ) }
    time   = { check_max (3.h   * task.attempt, 'time'   ) }
  }
  //filtlong: exponential increase of memory and time with attempts
  withName: FILTLONG {
    cpus   = { check_max (8     * task.attempt         , 'cpus'   ) }
    memory = { check_max (64.GB * (2**(task.attempt-1)), 'memory' ) }
    time   = { check_max (24.h  * (2**(task.attempt-1)), 'time'   ) }
  }
  withName: CENTRIFUGE {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (40.GB * task.attempt, 'memory' ) }
    time   = { check_max (12.h  * task.attempt, 'time'   ) }
  }
  withName: KRAKEN2 {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (40.GB * task.attempt, 'memory' ) }
    time   = { check_max (12.h  * task.attempt, 'time'   ) }
  }
  withName: KRONA {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (20.GB * task.attempt, 'memory' ) }
    time   = { check_max (12.h  * task.attempt, 'time'   ) }
  }
  withName: CAT_DB_GENERATE {
    memory = { check_max (200.GB * task.attempt, 'memory' ) }
    time   = { check_max (16.h   * task.attempt, 'time'   ) }
  }
  withName: CAT {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (40.GB * task.attempt, 'memory' ) }
    time   = { check_max (12.h  * task.attempt, 'time'   ) }
  }
  withName: GTDBTK_CLASSIFY {
    cpus   = { check_max (10     * task.attempt, 'cpus'   ) }
    memory = { check_max (128.GB * task.attempt, 'memory' ) }
    time   = { check_max (12.h   * task.attempt, 'time'   ) }
  }
  //MEGAHIT returns exit code 250 when running out of memory
  withName: MEGAHIT {
    cpus          = { check_megahit_cpus (8, task.attempt  ) }
    memory        = { check_max (40.GB * task.attempt, 'memory' ) }
    time          = { check_max (16.h  * task.attempt, 'time'   ) }
    errorStrategy = { task.exitStatus in [143,137,104,134,139,250] ? 'retry' : 'finish' }
  }
  //SPAdes returns error(1) if it runs out of memory (and for other reasons as well...)!
  //exponential increase of memory and time with attempts, keep number of threads to enable reproducibility
  withName: SPADES {
    cpus          = { check_spades_cpus (10, task.attempt) }
    memory        = { check_max (64.GB * (2**(task.attempt-1)), 'memory' ) }
    time          = { check_max (24.h  * (2**(task.attempt-1)), 'time'   ) }
    errorStrategy = { task.exitStatus in [143,137,1] ? 'retry' : 'finish' }
    maxRetries    = 5
  }
  withName: SPADESHYBRID {
    cpus          = { check_spadeshybrid_cpus (10, task.attempt) }
    memory        = { check_max (64.GB * (2**(task.attempt-1)), 'memory' ) }
    time          = { check_max (24.h  * (2**(task.attempt-1)), 'time'   ) }
    errorStrategy = { task.exitStatus in [143,137,1] ? 'retry' : 'finish' }
    maxRetries    = 5
  }
  //returns exit code 247 when running out of memory
  withName: BOWTIE2_ASSEMBLY_ALIGN {
    cpus          = { check_max (2    * task.attempt, 'cpus'   ) }
    memory        = { check_max (8.GB * task.attempt, 'memory' ) }
    time          = { check_max (8.h  * task.attempt, 'time'   ) }
    errorStrategy = { task.exitStatus in [143,137,104,134,139,247] ? 'retry' : 'finish' }
  }
  withName: METABAT2 {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (20.GB * task.attempt, 'memory' ) }
    time   = { check_max (8.h   * task.attempt, 'time'   ) }
  }
  withName: BUSCO {
    cpus   = { check_max (8     * task.attempt, 'cpus'   ) }
    memory = { check_max (20.GB * task.attempt, 'memory' ) }
  }
}
