#!/usr/bin/env python


# Copyright 2011(c) The Ontario Institute for Cancer Research. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the GNU Public License v3.0.
#
# You should have received a copy of the GNU General Public License along with
# this program.  If not, see <http://www.gnu.org/licenses/>.


import capsid


def configure_(args):
    capsid.configure.main(args)

def gbloader_(args):
    capsid.gbloader.main(args)

def taxonomy_(args):
    capsid.taxonomy.main(args)

def fasta_(args):
    capsid.fasta.main(args)

def subtraction_(args):
    capsid.subtraction.main(args)

def qfilter_(args):
    capsid.qfilter.main(args)

def intersect_(args):
    capsid.intersect.main(args)

def statistics_(args):
    capsid.statistics.main(args)

def project_(args):
    capsid.project.main(args)

def sample_(args):
    capsid.sample.main(args)
    
def alignment_(args):
    capsid.alignment.main(args)

if __name__ == '__main__':
    import argparse
    import getpass

    ### CaPSID Pipeline #####################################################
    parser = argparse.ArgumentParser(description='CaPSID Pipeline')
    parser.add_argument('--version', action="version", version='CaPSID {0}'.format(capsid.__version__), help='show version and exit')
    subparsers = parser.add_subparsers(title='Actions')

    ### Configure #################################################################
    configure_parser = subparsers.add_parser('configure',
                                             formatter_class=argparse.RawDescriptionHelpFormatter,
                                             description='CaPSID Configuration\n\nExample\n\tcapsid configure',
                                             help='Configure CaPSID')
    # MongoDB settings
    mongo = configure_parser.add_argument_group('MongoDB Settings', 'Values set through the commandline will not be prompted for during setup')
    mongo.add_argument('--host', metavar='h', default=None, help='MongoDB Server address')
    mongo.add_argument('--port', metavar='p', default=None, help='Port used to connect to MongoDB')
    mongo.add_argument('--database', metavar='db', default=None, help='Database name used for capsid')
    mongo.add_argument('--username', metavar='user', default=None, help='Set Username if needed')
    mongo.add_argument('--password', metavar='pass', default=None, help='Set Password')
    # Logging Options
    verbose_debug = configure_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    configure_parser.set_defaults(func=configure_)

    ### GenBank Loader ########################################################
    gbloader_parser = subparsers.add_parser('gbloader',
                                            formatter_class=argparse.RawDescriptionHelpFormatter,
                                            description='GenBank Loader\n\nExample:\n\tcapsid gbloader gb1.gbff gb2.gbff',
                                            help='GenBank Loader')
    gbloader_parser.add_argument('files', metavar='F', nargs='+', help='List of GenBank files')
    gbloader_parser.add_argument('--repair', action='store_true', default=False, help='Overwrite existing Genomes instead of skipping them')
    ## Logging Options
    verbose_debug = gbloader_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to WARNING')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    gbloader_parser.set_defaults(func=gbloader_)

    ### Taxonomy Loader ########################################################
    taxonomy_parser = subparsers.add_parser('taxonomy',
                                            formatter_class=argparse.RawDescriptionHelpFormatter,
                                            description='Taxonomy Loader\n\nExample:\n\tcapsid taxonomy taxon_directory',
                                            help='Taxonomy Loader')
    taxonomy_parser.add_argument('directory', metavar='F', help='Taxonomy data directory')
    taxonomy_parser.add_argument('--repair', action='store_true', default=False, help='Overwrite existing taxa instead of skipping them')
    ## Logging Options
    verbose_debug = taxonomy_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to WARNING')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    taxonomy_parser.set_defaults(func=taxonomy_)

    ### Fasta Generator #######################################################
    fasta_parser = subparsers.add_parser('fasta',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Generate Fasta File\n\nExample\n\tcapsid fasta',
                                         help='Fasta Generator')
    # Query options
    query = fasta_parser.add_argument_group('Query Options')
    query.add_argument('--organism', nargs='+', metavar='O', default=None, help='List of organisms to look up')
    query.add_argument('--taxonomy', nargs='+', metavar='T', default=None, help='List of taxonomy descriptors')
    query.add_argument('--ref', metavar='R', default=None, help='ReqSeq Accession')
    query.add_argument('--gi', metavar='G', default=None, help='GenInfo Identifier')
    query.add_argument('--output', metavar='F', default='genomes.fa', help='Path of the created fasta file [./genomes.fa]')
    # Logging Options
    verbose_debug = fasta_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')

    # AutoRun
    fasta_parser.set_defaults(func=fasta_)

    ### BAM Subtraction #######################################################
    subtract_parser = subparsers.add_parser('subtraction',
                                             formatter_class=argparse.RawDescriptionHelpFormatter,
                                             description='BAM Alignment Loader\n\nExample:\n\tcapsid subtraction xeno_file.bam ref_file.bam alignmentName',
                                             help='BAM Subtraction')
    subtract_parser.add_argument('xeno', help='Xeno BAM File')
    subtract_parser.add_argument('ref', help='Reference BAM File')
    subtract_parser.add_argument('align', help='Alignment Name from Database')
    # Process Mapped/Unmapped/Both
    subtract_parser.add_argument('-p', '--process', choices=['both', 'mapped', 'unmapped'], default='mapped', help='save mapped, unmapped or both')
    # MapQ score filter
    subtract_parser.add_argument('-f', '--filter', metavar='mapq', default=0, help='filter out alignments with lower mapq value')
    # Temp directory for processing 
    subtract_parser.add_argument('-t', '--temp', metavar='DIR', default='./', help='temp dir used for sorting and digital subtraction')
    subtract_parser.add_argument('-gra', action='store_true', default=False, help='calculate genome relative abundances (gra)')
    # Lookup Options
    lookupf = subtract_parser.add_argument_group()
    lookupf.add_argument('-l', '--lookup', metavar=('file', 'column'), nargs=2, default=None, help='lookup file and genome identifier(gi, accession) for both xeno and reference.')
    lookupf.add_argument('-xl', '--xeno_lookup', metavar=('file', 'column'), nargs=2, default=[None, None], help='lookup file and genome identifier(gi, accession) for xeno.')
    lookupf.add_argument('-rl', '--ref_lookup', metavar=('file', 'column'), nargs=2, default=[None, None], help='lookup file and genome identifier(gi, accession) for reference.')
    # Auto Create P/S
    subtract_parser.add_argument('--sample', help='Sample Name')
    subtract_parser.add_argument('--project', help='Project Label')
    
    # Logging Options
    verbose_debug = subtract_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='set logging output to DEBUG')
    # AutoRun
    subtract_parser.set_defaults(func=subtraction_)

    ### qFilter  ###########################################################
    qfilter_parser = subparsers.add_parser('qfilter',
                                          formatter_class=argparse.RawDescriptionHelpFormatter,
                                          description='Quality Filter\n\nExample\n\tcapsid qfilter single_end.fastq 20\n\tcapsid qfilter pair_end1.fastq pair_end2.fastq 20',
                                          help='Quality Filter')
    qfilter_parser.add_argument('single', help='single-end or first pair-end fastq file')
    qfilter_parser.add_argument('pair',  nargs='?', help='second pair-end fastq file')
    qfilter_parser.add_argument('threshold', help='quality threshold')
    qfilter_parser.add_argument('-l', '--limit', metavar='int', dest='limit', default=3, help='Maximum number of bases allowed under quality threshold [default is 3]')
    qfilter_parser.add_argument('-f', '--format', metavar='fastq_format', dest='format', choices=['illumina', 'sanger'], default='sanger', help='Sanger style FASTQ files which encode PHRED qualities using an ASCII offset of 33. Solexa/Illumina style FASTQ files (from pipeline version 1.3 to 1.7) which encode PHRED qualities using an ASCII offset of 64 {[sanger], illumina}')
    # Temp DIR for sorting
    qfilter_parser.add_argument('-t', '--temp', metavar='DIR', default='.', help='temp dir used for sorting')
    # Logging Options
    verbose_debug = qfilter_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='set logging output to DEBUG')
    # AutoRun
    qfilter_parser.set_defaults(func=qfilter_)

    ### Statistics  ###########################################################
    stats_parser = subparsers.add_parser('statistics',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Statistics\n\nExample\n\tcapsid statistics proj_label_one proj_label_two',
                                         help='Statistics')
    # Logging Options
    verbose_debug = stats_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # Project Select
    project = stats_parser.add_argument_group('Project Select', 'Select which project(s) to update by passing the project label(s)')
    project.add_argument('projects', nargs='+', metavar="P", help="Project Label from Database")
    # Background
    background = stats_parser.add_mutually_exclusive_group()
    background.add_argument('-bg', action='store_true', default=False, help='Calculate stats for background models to be used within a project(s) the project label for this option should be "background"')
    background.add_argument('-bgm', dest='bgm', default=False, help='Select the background model for the project(s) (a model is a sample within the "background" project)')
    # AutoRun
    stats_parser.set_defaults(func=statistics_)

    ### Intersection  ########################################################
    int_parser = subparsers.add_parser('intersect',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Intersection\n\nExample\n\tcapsid intersect f1.fastq f2.fastq f3.fastq',
                                         help='Intersection')

    # Fastq Files
    int_parser.add_argument('files', metavar='F', nargs='+', help='list of fastq files')
    # Temp DIR for sorting
    int_parser.add_argument('-t', '--temp', metavar='DIR', default='.', help='temp dir used for sorting')
    # Logging Options
    verbose_debug = int_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    int_parser.set_defaults(func=intersect_)

    ### Project ########################################################
    prj_parser = subparsers.add_parser('project',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Create Project\n\nExample\n\tcapsid project PRJ1',
                                         help='Project')

    # Project Req Atter
    prj_parser.add_argument('project', metavar='LABEL', help='Project Label')
    prj_parser.add_argument('--name', dest="pname", help='Project Name')
    prj_parser.add_argument('--desc', dest="pdesc", help='Project Description')
    prj_parser.add_argument('--link', dest="link", help='Project Link')

    # Logging Options
    verbose_debug = prj_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    prj_parser.set_defaults(func=project_)

    ### Sample ########################################################
    smpl_parser = subparsers.add_parser('sample',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Create Sample\n\nExample\n\tcapsid sample SAMP001 PRJ1',
                                         help='Project')

    # Project Req Atter
    smpl_parser.add_argument('sample', metavar='NAME', help='Sample Name')
    smpl_parser.add_argument('project', metavar='PROJECT',help='Project Label')
    smpl_parser.add_argument('--desc', dest="sdesc", help='Description')
    smpl_parser.add_argument('--role', help='Role')
    smpl_parser.add_argument('--source', help='Source')
    smpl_parser.add_argument('--cancer', help='Cancer Type')

    # Logging Options
    verbose_debug = smpl_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    smpl_parser.set_defaults(func=sample_)
    
    ### Alignment ########################################################
    aln_parser = subparsers.add_parser('alignment',
                                         formatter_class=argparse.RawDescriptionHelpFormatter,
                                         description='Create Alignment\n\nExample\n\tcapsid alignment ALN1 SAMP001 PRJ1',
                                         help='Project')

    # Project Req Atter
    aln_parser.add_argument('align', metavar='NAME', help='Alignment Name')
    aln_parser.add_argument('sample', metavar='SAMPLE', help='Sample Name')
    aln_parser.add_argument('project', metavar='PROJECT',help='Project Label')
    aln_parser.add_argument('--aligner', help='Aligner')
    aln_parser.add_argument('--platform', help='Platform')
    aln_parser.add_argument('--type', help='Type')
    aln_parser.add_argument('--infile', help='Alignment Input file')
    aln_parser.add_argument('--outfile', help='Alignment Outfile file')

    # Logging Options
    verbose_debug = aln_parser.add_mutually_exclusive_group()
    verbose_debug.add_argument('-q', '--quiet', action='store_const', dest='logging', const="WARNING", default='INFO', help='Set logging output to ERROR')
    verbose_debug.add_argument('-d', '--debug', action='store_const', dest='logging', const="DEBUG", default='INFO', help='Set logging output to DEBUG')
    # AutoRun
    aln_parser.set_defaults(func=alignment_)
    
    ### Run ###
    args = parser.parse_args()
    args.logging = capsid.log(args)
    args.func(args)
