#!/usr/bin/env python3

import os
import sys

class cmd():
    '''
        help parse the apropriate command depending on the tools concerned and the input data types
        (i.e raw, QC , QCmerged, merged, single-end and paired-end)
    '''
    def __init__(self, wildcards , input , reads ,tools):
        self.src = wildcards # refere to sample id or cluster id (parse with wildcards.src, sometimes wildcards.sample)
        self.input = str(input) #refere to rule input. Might be sample reads  or a cluster_{clusterid}.txt file containing mulitple samples names
        self.reads = reads #reads to use for assembly and motus step (cf, resolvereads() and reads2use from configparser.py)
        self.tools = tools
        self.toolsyntax = {"megahit": ["-1","-2","-r"],"motus": ["-f","-r","-s"],"bowtie2": ["-1","-2","-U"]}
        self.cmd = self.getcmd()

    def is_paired_end(self):
        for sample in self.reads:
            for run in self.reads[sample]:
                if len(self.reads[sample][run]) > 1:
                    return True
                if len(self.reads[sample][run]) == 1:
                    return False
                else:
                    raise ValueError('No reads found !')

    def getcmd(self):
        '''
        '''
        if os.path.isfile(self.input) and self.input.endswith(".txt"):
        #then input is a file containing a list of sample
            return self.coa_cmd()
        else:
        #then input is a list of fastq refering to one sample
            return self.sa_cmd()

    def sa_cmd(self):
        '''
            build megahit / bowtie2 and motus command (input part)
        '''
        forward = self.toolsyntax.get(self.tools)[0]
        reverse = self.toolsyntax.get(self.tools)[1]
        single  = self.toolsyntax.get(self.tools)[2]
        sample = self.src

        r1 = []
        r2 = []
        singletons = []
        if self.is_paired_end():
            for run in self.reads[sample]:
                r1.append(self.reads[sample][run][0])
                r2.append(self.reads[sample][run][1])

                if self.reads[sample][run][2:]:
                 singletons.extend(self.reads[sample][run][2:])

            if len(singletons) == 0:
                cmd = "{} {} {} {}".format(forward, ','.join(r1), reverse, ','.join(r2))
            else:
                cmd = "{} {} {} {} {} {}".format(forward, ','.join(r1), reverse, ','.join(r2), single, ','.join(singletons))
        else:
            for run in self.reads[sample]:
                singletons.append(self.reads[sample][run][0])
            cmd = "{} {}".format(singletons, self.reads[sample][run][0])

        return cmd

    def coa_cmd(self):
        '''
            build megahit / bowtie2 command (input part) with all samples part of a cluster
            note:  not available for motus profiling because it's a per-sample tool
        '''
        forward = self.toolsyntax.get(self.tools)[0]
        reverse = self.toolsyntax.get(self.tools)[1]
        single  = self.toolsyntax.get(self.tools)[2]

        r1 = []
        r2 = []
        singletons = []

        with open(self.input,'r') as f_samp:
            if self.is_paired_end():
                for sample in f_samp:
                    sample = sample.strip()
                    for run in self.reads[sample]:
                        r1.append(self.reads[sample][run][0])
                        r2.append(self.reads[sample][run][1])
                        singletons.extend(self.reads[sample][run][2:])

            else:
                for sample in f_samp:
                    sample = sample.strip()
                    for run in self.reads[sample]:
                        singletons.append(self.reads[sample][run][0])

        if len(r1) > 0 and len(r2) > 0 and len(singletons) == 0:
                        cmd = "{} {} {} {}".format(forward, ",".join(r1), reverse, ",".join(r2))
        elif len(r1) > 0 and len(r2) > 0 and len(singletons) > 0:
                        cmd = "{} {} {} {} {} {}".format(forward, ",".join(r1), reverse, ",".join(r2), single, ",".join(singletons))
        elif len(r1) == 0 and len(r2) == 0 and len(singletons) > 0:
                        cmd = "{} {}".format(single, ",".join(singletons))
        else:
            print("Check file of reads !")
            raise ValueError("Some reads are missing !")

        return cmd
