"""ATAC-seq pipeline

Affiliation: Institut Pasteur @ 2016

This pipeline is part of Sequana software (sequana.readthedocs.io)
"""
import os
import sequana
from sequana import snaketools as sm
sm.init("rnaseq.rules", globals())


# This must be defined before the include
configfile: "config.yaml"
__snakefile__ = srcdir(__snakefile__)

# Generic include of some dynamic modules
exec(open(sequana.modules["fastqc_dynamic"], "r").read())


manager = sm.PipelineManager("atac-seq", config)

__data__input = manager.getrawdata()


TODO = "todo"

# FASTQC on input data set
__fastqc_samples__input_fastq = __data__input
__fastqc_samples__output_done = manager.getname("fastqc_samples", ".done")
__fastqc_samples__wkdir       = manager.getwkdir("fastqc_samples")
include: fastqc_dynamic("samples", manager.sample)
expected_output.extend(expand(__fastqc_samples__output_done, sample=manager.samples))




adapter_tool = manager.config.adapter_removal.tool
# Clean NGS
if adapter_tool == "cutadapt":
    __cutadapt__input_fastq = __data__input
    __cutadapt__wkdir = manager.getwkdir("cutadapt")
    __cutadapt__output = [manager.getname("cutadapt", "_R1_.cutadapt.fastq.gz")]
    if manager.paired:
        __cutadapt__output += [manager.getname("cutadapt", "_R2_.cutadapt.fastq.gz")]
    if "adapter_fwd" in manager.config.adapter_removal.fwd :
       __cutadapt__fwd = ""
    else:
       __cutadapt__fwd = manager.config.adapter_removal.fwd

    if "adapter_rev" in manager.config.adapter_removal.rev:
        __cutadapt__rev = ""
    else:
        __cutadapt__rev = manager.config.adapter_removal.rev

    __cutadapt__design = manager.config.adapter_removal.design
    __cutadapt__design_adapter = manager.config.adapter_removal.adapter_type
    __cutadapt__options = manager.config.adapter_removal.options
    __cutadapt__mode = manager.config.adapter_removal.mode
    __cutadapt__log = "%s/logs/cutadapt/cutadapt.txt" % manager.sample
    __cutadapt__sample = manager.sample
    include: sm.modules["cutadapt"]

else:
    raise ValueError("Invalid choice of adapter_removal:tool in config file. Use either clean_ngs or cutadapt")


# FASTQC on input data set
__fastqc_filtered__input_fastq = __cutadapt__output
__fastqc_filtered__output_done = manager.getname("fastqc_filtered", ".done")
__fastqc_filtered__wkdir       = manager.getwkdir("fastqc_filtered")
include: fastqc_dynamic("filtered", manager.sample)
expected_output.extend(expand(__fastqc_filtered__output_done, sample=manager.samples))

# TODO prendre en compte le paired-end
if config["bowtie2_mapping"]["do"]:
    __bowtie2_mapping__input = __cutadapt__output
    __bowtie2_mapping__sort =
    __bowtie2_mapping__logs_out = "%s/logs/bowtie2/stdout.logs" % manager.sample
    __bowtie2_mapping__logs_err = "%s/logs/bowtie2/stderr.logs" % manager.sample


# Add Read group on BAM files
__add_read_group__input = __mapping_output
__add_read_group__output = manager.getname("add_read_group/", "_RG_sorted.bam")
__add_read_group__log_err = "%s/logs/AddOrReplaceReadGroups/stderr.logs" % manager.sample
__add_read_group__log_std ="%s/logs/AddOrReplaceReadGroups/stdout.logs" % manager.sample
__add_read_group__rg = "ID=%s LB=%s PL=%s PU=%s SM=%s" % (manager.sample, manager.sample, manager.config.sequencing.platform, manager.config.sequencing.flowcell, manager.sample)
include: sm.modules["add_read_group"]



# Mark duplicates
__mark_duplicates__input = __add_read_group__output
__mark_duplicates__output = manager.getname("mark_duplicates", ".bam")
__mark_duplicates__metrics = manager.getname("mark_duplicates", ".metrics")
__mark_duplicates__log_std = "%s/logs/mark_duplicates/stdout.logs" % manager.sample
__mark_duplicates__log_err =  "%s/logs/mark_duplicates/stderr.logs" % manager.sample
include: sm.modules["mark_duplicates"]
expected_output.extend(expand(__mark_duplicates__output, sample=manager.samples))


__CollectInsertSizeMetrics__input = __mark_duplicates__output
__CollectInsertSizeMetrics__output = manager.getname("CollectInsertSizeMetrics", "_insertSize.pdf")
__CollectInsertSizeMetrics__metrics = manager.getname("CollectInsertSizeMetrics", ".metrics")
__CollectInsertSizeMetrics__log_std = "%s/logs/InsertSizeMetrics/stdout.logs" % manager.sample
__CollectInsertSizeMetrics__log_err = "%s/logs/InsertSizeMetrics/stderr.logs" % manager.sample
include: sm.modules["CollectInsertSizeMetrics"]
expected_output.extend(expand(__CollectInsertSizeMetrics__output, sample=manager.samples))


# TODO prendre en compte le design experimental
__macs2__input = __mark_duplicates__output
__macs2__input_bam = ## relative to INPUT bam (or Control condition)
__macs2__log_std = "%s/logs/macs2/stdout.logs" % manager.sample
__macs2__log_err = "%s/logs/macs2/stderr.logs" % manager.sample
__macs2__output = #Be carefull, the output is a prefix
include: sm.modules["macs2"]
expected_output.extend(expand(__macs2__output, sample=manager.samples))


#Bam coverage
__bamCoverage__input = __mark_duplicates__output
__bamCoverage__output = manager.getname("BamCoverage", "_norm.bw")
__bamCoverage__log = "%s/logs/BamCoverage/stderr.logs" % manager.sample
include: sm.modules["bamCoverage"]
expected_output.extend(expand(__bamCoverage__output, sample=manager.samples))


# plot correlation
__multiBamSummary__input = expand(__mark_duplicates__output)
__multiBamSummary__log = "%s/logs/Correlation/BamSummaryErr.logs" % manager.sample
__multiBamSummary__output = "BamSummary.npz"
__plotCorrelation__input = __multiBamSummary__output
__plotCorrelation__output = "scatterplot_correlation.svg"
__plotCorrelation__log = "%s/logs/Correlation/plotCorrelationErr.logs" % manager.sample



# !!!!!!!!!!!!!!!!!!! Reset expected_output variable after multiqc
# Multiqc rule
__multiqc__input = expected_output
__multiqc__input_dir = "."
__multiqc__logs = "multiqc/multiqc.log"
__multiqc__output = config['multiqc']['output-directory'] + "/multiqc_report.html"
include: sm.modules["multiqc"]
expected_output = [__multiqc__output]


# Include rule graph for each sample
__rulegraph__input = __snakefile__
__rulegraph__output = "rulegraph/rulegraph.svg"
__rulegraph__mapper = {"fastqc_samples": "fastqc_samples/"}
include: sm.modules['rulegraph']
expected_output.extend([__rulegraph__output])


# Add Conda
__conda__output = "requirements.txt"
include: sm.modules['conda']   # Create requirements.txt(dependencies)
expected_output.extend([__conda__output])

# Those rules takes a couple of seconds so no need for a cluster
localrules:  conda, rulegraph

rule atacseq:
    input: expected_output


onsuccess:
    import os
    # Create plots about stats
    sm.plot_stats(N=len(manager.samples))

    # Main directory
    report_dir_format = "%(proj)s/report_atac-seq_%(proj)s"
    for proj in manager.samples.keys():
        report_dir = report_dir_format % {"proj": proj}
        try:os.mkdir(report_dir)
        except:pass

        shell("cp %s %s" % (__snakefile__, report_dir))
        shell("cp rulegraph.svg %s/rulegraph.svg" % (report_dir))
        shell("cp config.yaml %s" % report_dir)
        shell("cp requirements.txt %s" % report_dir)
        shell("cp snakemake_stats.png %s" % report_dir)

        shell('cp -r %s/fastqc_*/ %s' % (proj, report_dir))
        shell('cp -r %s/cutadapt/ %s' % (proj, report_dir))

        """
        # Commented by TC Avril 2017 since reporting package is now removed
        # and create_cleanup will be deprecated
        from sequana.reporting.report_summary import SequanaSummary
        summary = SequanaSummary(proj, directory=report_dir,
            output_filename="summary.html",
            snakefile=__snakefile__, configfile=report_dir+"/config.yaml",
            manager=manager)
        summary.create_report()

        # Create a cleanup python file to clean a sub-directory
        sm.create_cleanup(proj)
        """

    #sm.create_recursive_cleanup()
    #sm.message("Done. To further cleanup the directory, type \n python .sequana_cleanup.py")

onerror:
    print("An error occurred. See message above.")


