rule bowtie2_mapping:

    """
    Read mapping for either single end and paired end data using Bowtie2.

    Required input:
        __bowtie2_mapping__input: list with one or two fastq.gz

    Required output:
        __bowtie2_mapping__sort: output sorted bam file

    Config:

        __bowtie2_mapping__outdir: output directory
        __bowtie2_mapping__sam: output file in SAM format (temporary file)

        .. code-block:: yaml

            bowtie2_mapping:
                prefix_index: "" #path to the index file of reference genome
                options:  "" #options for bowtie1 you want use
    """

    input:
        fastq = __bowtie2_mapping__input,
        index = __bowtie2_mapping__index_done
    output:
        sort = __bowtie2_mapping__sort
    log:
        err = __bowtie2_mapping__logs_err,
        out = __bowtie2_mapping__logs_out
    params:
        outdir = __bowtie2_mapping__outdir,
        prefix_index = config["bowtie2_mapping"]["prefix_index"],
        options = config["bowtie2_mapping"]["options"],
        sam = temp(__bowtie2_mapping__sam)
    threads:
        config["bowtie2_mapping"]["threads"]
    run:
        unzip_file = [filename[:-3] for filename in input.fastq]
        cmd = "bowtie2 -p {threads} {params.options} -x {params.prefix_index}"
        # paired end or single end unzip
        if len(input.fastq) == 2:
            bowtie_input = "-1 " + unzip_file[0] + " -2 " + unzip_file[1]
        else:
            bowtie_input = unzip_file[0]
        cmd = cmd + " " + bowtie_input
        # sam to bam
        cmd = "%%s | samtools view -Sbh -> {output.bam}" %% cmd

        # logs
        cmd = "(%%s) > {log.out} 2> {log.err}" %% cmd

        # sort result
        cmd = "%%s && samtools sort -o {output.sort} {output.bam}" %% cmd
        cmd = "%%s && samtools index {output.sort}" %% cmd


        shell("unpigz -fk {input.fastq} -p {threads} && " + cmd )
