""" UMCCR post-bcbio patient analysis workflow
"""
import os
import sys
from os.path import join, abspath, dirname, isfile, basename, splitext
from ngs_utils.file_utils import splitext_plus
from ngs_utils.bcbio import BcbioProject
from ngs_utils.file_utils import add_suffix, get_ungz_gz
from ngs_utils.logger import critical, info
from python_utils.hpc import get_ref_file, get_loc
from umccrise import package_path, get_key_genes_bed

shell.executable("bash")
shell.prefix("")


pcgr_url = config.get('pcgr_url', 'ec2-13-55-18-20')
cov_by_phenotype = config.get('cov_by_phenotype', {'tumor': 30, 'normal': 10})  # For goleft regions coverage, use minimum coverage 10 for normal, 30 for tumor
threads_max = 32  # Use up to 32 cores at once, if available

run = BcbioProject(config.get('run_dir', abspath(os.getcwd())))
project_id = splitext(basename(run.bcbio_yaml_fpath))[0]

ref_fa = get_ref_file(run.genome_build)
key_genes_bed = get_key_genes_bed(run.genome_build)

# Batch objects index by tumor sample names
batches = [b for b in run.batch_by_name.values() if not b.is_germline()]
include_names = config.get('batch') or config.get('sample')
if include_names:
    include_names = include_names.split(',')
    selected_batches = [b for b in batches if b.name in include_names
                                           or b.tumor.name in include_names
                                           or b.name + '__' + b.tumor.name in include_names]
    if len(selected_batches) == 0:
        critical(f'Error: could not find a batch or a sample with the name(s): {", ".join(include_names)}. '
                 f'Known batches: {list(b.name for b in batches)}, '
                 f'known samples: {list(b.tumor.name for b in batches)}')
    batches = selected_batches
exclude_names = config.get('exclude')
if exclude_names:
    exclude_names = exclude_names.split(',')
    selected_batches = [b for b in batches if b.name not in exclude_names
                                          and b.tumor.name not in exclude_names
                                          and b.name + '__' + b.tumor.name not in include_names]
    if len(selected_batches) == 0:
        critical(f'Error: no samples left with the exclusion of batch/sample name(s): {", ".join(exclude_names)}.')
    batches = selected_batches
    info(f'Excluding sample/batch name(s): {", ".join(exclude_names)}.')

batch_by_name = {b.name + '__' + b.tumor.name: b for b in batches}

is_spartan = get_loc().name == 'spartan'
is_raijin = get_loc().name == 'raijin'
is_hpc = is_spartan or is_raijin
upload_proxy = ''
if is_spartan:
    upload_proxy = 'HTTPS_PROXY=http://wwwproxy.unimelb.edu.au:8000 '


rule all:
    input: 'umccrised.done'
    # A trick to avoid duplicating all input paths in the top "all" rule which has to be defined on top.

# TODO: try subworkflows here? http://snakemake.readthedocs.io/en/stable/snakefiles/modularization.html#sub-workflows
"""
subworkflow small_variants:
    workdir: 'small_variants'
    snakefile: 'Snakefile.small_variants'

rule all:
    input:  small_variants('small_variants.done')
    output: ...
    shell:  ...
"""
# Or maybe it's not reasonable and not doable here since the input file is a phony .done, and also we depend on config in subworkflows


include: "small_variants.smk"
include: "coverage.smk"
include: "structural.smk"
include: "igv.smk"
include: "pcgr.smk"
include: "rmd.smk"


localrules: copy_multiqc, copy_logs, umccrise


rule copy_multiqc:  # {}
    input:
        join(run.date_dir, 'multiqc/multiqc_report.html')
    output:
        project_id + '-multiqc_report.html'
    shell:
        'cp {input} {output}'


## Additional information
# TODO: link it to MultiQC
rule copy_logs:  # {}
    input:
        join(run.date_dir, 'data_versions.csv'), 
        join(run.date_dir, 'programs.txt'), 
        run.config_dir
    output:
        'log/' + project_id + '-data_versions.csv',
        'log/' + project_id + '-programs.txt',
        'log/' + project_id + '-config'
    shell:
        'cp -r {input[0]} {output[0]} && cp -r {input[1]} {output[1]} && cp -r {input[2]} {output[2]}'


rule umccrise:
    input:  # Copy here inputs of the "milestone" rules (rules without output defined in the end of each Snakemake.* file)
        rules.copy_multiqc.output,
        rules.copy_logs.output,
        rules.coverage.output,
        rules.structural.output,
        rules.small_variants.output,
        rules.rmd.output,
        (rules.pcgr.output if is_hpc else rules.pcgr_prep.output),
        rules.igv.output
    output:
        temp(touch('umccrised.done'))
