executor {
  $k8s {
    submitRateLimit = '10sec'
    pollInterval = '1 sec'
  }
}

process {
  container = 'nextflow/bash:latest'
  
  // default resources
  memory = { 8.Gb * task.attempt }
  cpus = 8
  maxForks = 36

  // Retry for exit codes that have something to do with memory issues
  errorStrategy = { task.exitStatus in 137..140 ? 'retry' : 'terminate' }
  maxRetries = 3
  maxMemory = 192.GB

  // Resource labels
  withLabel: verylowcpu { cpus = 2 }
  withLabel: lowcpu { cpus = 8 }
  withLabel: midcpu { cpus = 16 }
  withLabel: highcpu { cpus = 32 }
  
  withLabel: verylowmem { memory = { get_memory( 4.GB * task.attempt ) } }
  withLabel: lowmem { memory = { get_memory( 8.GB * task.attempt ) } }
  withLabel: midmem { memory = { get_memory( 16.GB * task.attempt ) } }
  withLabel: highmem { memory = { get_memory( 64.GB * task.attempt ) } }

}

profiles {
  // detect tempdir
  tempDir = java.nio.file.Paths.get(
    System.getenv('NXF_TEMP') ?:
      System.getenv('VIASH_TEMP') ?: 
      System.getenv('TEMPDIR') ?: 
      System.getenv('TMPDIR') ?: 
      '/tmp'
  ).toAbsolutePath()

  mount_temp {
    docker.temp            = tempDir
    podman.temp            = tempDir
    charliecloud.temp      = tempDir
  }

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

  docker {
    docker.fixOwnership    = true
    docker.enabled         = true
    // docker.userEmulation   = true
    singularity.enabled    = false
    podman.enabled         = false
    shifter.enabled        = false
    charliecloud.enabled   = false
  }

  local {
    // This config is for local processing.
    process {
        maxMemory = 25.GB
        withLabel: verylowcpu { cpus = 2 }
        withLabel: lowcpu { cpus = 4 }
        withLabel: midcpu { cpus = 6 }
        withLabel: highcpu { cpus = 12 }
  
        withLabel: lowmem { memory = { get_memory( 8.GB * task.attempt ) } }
        withLabel: midmem { memory = { get_memory( 12.GB * task.attempt ) } }
        withLabel: highmem { memory = { get_memory( 20.GB * task.attempt ) } }
    }
  }
}

def get_memory(to_compare) {
    if (!process.containsKey("maxMemory") || !process.maxMemory) {
      return to_compare
    }

    try {
      if (process.containsKey("maxRetries") && process.maxRetries && task.attempt == (process.maxRetries as int)) {
        return process.maxMemory
      }
      else if (to_compare.compareTo(process.maxMemory as nextflow.util.MemoryUnit) == 1) {
        return max_memory as nextflow.util.MemoryUnit
      }
      else {
        return to_compare
      }  
    } catch (all) {
          println "Error processing memory resources. Please check that process.maxMemory '${process.maxMemory}' and process.maxRetries '${process.maxRetries}' are valid!"
          System.exit(1)
    }
  }
