#!/usr/bin/env python2.7
# encoding: utf-8
'''

SCRAM - Small Complementary RnA Mapper

Command line module


@author:     Stephen Fletcher

@copyright:  2016 Stephen Fletcher. All rights reserved.

@license:    MIT

@contact:    s.fletcher@uq.edu.au
@deffield    updated: Updated
'''

import sys 
#import os
import analysis

from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from sets import Set

__all__ = []
__version__ = 0.51
__date__ = '2016-08-30'
__updated__ = '2016-08-30'

# DEBUG = 1
# TESTRUN = 0
# PROFILE = 0

class CLIError(Exception):
    '''Generic exception to raise and log different fatal errors.'''
    def __init__(self, msg):
        super(CLIError).__init__(type(self))
        self.msg = "E: %s" % msg
    def __str__(self):
        return self.msg
    def __unicode__(self):
        return self.msg

def main(argv=None): 
    '''Command line options.'''
    ana_accepted=Set(['den', 'mnt3dm','CDP','sCDP'])   
    if argv is None:
        argv = sys.argv
    else:
        sys.argv.extend(argv)

    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version, 
                                                     program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s

  SCRAM - Small Complementary RnA Mapper
  
  Created by Stephen Fletcher on %s.
  Copyright 2016 Stephen Fletcher. All rights reserved.

  Licensed under the MIT licence

  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.

USAGE
''' % (program_shortdesc, str(__date__))

    try:
        # Setup argument parser
        parser = ArgumentParser(description=program_license, 
                                formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('analysis_type', type = str, help = "den \
        (single read length), mnt3dm (21, 22 and 24nt read lengths), \
        CDP (single read length)")
        parser.add_argument('reference_file', 
                            type = str, help = "Reference file (.fasta format)")     
        parser.add_argument('-s1', '--seq_file_1', 
                            type = str, help = "Sequence file 1",nargs='*')
        parser.add_argument('-s2', '--seq_file_2', 
                            type = str, help = "Sequence file 2",nargs='*')   
        parser.add_argument('-nt','--sRNA_len', 
                            type=int, default = 21)
        parser.add_argument('-f', '--file_name', 
                            type=str, default = "NO_PLOT", 
                            help= "Figure output file name.  'auto' \
                            will auto-generate a file name") 
        parser.add_argument('-p', '--processes',
                            type = int, help = 'No. of processes (CPU cores) for CDP', 
                            default = 4)
        parser.add_argument('-min_read', 
                            '--min_read_size', type = int, 
                            help = "Minimum length of sRNA reads analysed \
                            (default=18)", 
                            default=18)
        parser.add_argument('-max_read', '--max_read_size', type = int, 
                            help = "Maximum length of sRNA reads analysed \
                            (default=32)", 
                            default = 32)
        parser.add_argument('-min_count', '--min_read_count', type = int, 
                            help = "Minimum read count for an sRNA to be \
                            analysed (default=1)", 
                            default = 1)        
        parser.add_argument('-win', '--smooth_win_size', type = int, 
                            help = "Window size for smoothing (default=50)/ \
                            Must be above 5, or non-smoothed plot returned", 
                            default = 50)
        parser.add_argument('-ylim', '--ylim',
                            type = float, help = '+/- y axis limit', 
                            default = 0)
        parser.add_argument('-no_csv', '--no_csv', 
                            action='store_false', default=True, 
                            help = 'Do not generate an alignment csv')     
        parser.add_argument('-no_display', '--no_display', 
                            action='store_false', default=True, 
                            help = 'Do not display plot on screen')
        parser.add_argument('-split', '--split_reads', action='store_false', 
                            default=True, 
                            help = 'Split reads alignment counts based on no. \
                            of alignments')
        parser.add_argument('-pub','--publish', action='store_true', 
                            default=False, 
                            help='Remove all labels from density maps for \
                            publication')
        parser.add_argument('-V', '--version', 
                            action='version', version=program_version_message)
        # Process arguments
        args = parser.parse_args()

        ana = args.analysis_type
        ref = args.reference_file
        seq1 = args.seq_file_1
        seq2 = args.seq_file_2
        nt = args.sRNA_len
        f = args.file_name
        min_read=args.min_read_size
        max_read=args.max_read_size
        min_count=args.min_read_count
        win=args.smooth_win_size
        ylim=args.ylim
        no_csv=args.no_csv
        no_display=args.no_display
        split = args.split_reads
        pub = args.publish
        processes = args.processes
        #plot figure or not
        if ana not in ana_accepted:
            print "\nEXITING!\n\n{0} is not a recognized analysis type.\n"\
                .format(ana)
        
        
        if f == 'NO_PLOT': 
            fileFig=False
        else:
            fileFig=True        
 
        if ana == 'den':
            analysis.single_ref_coverage(seq1, 
                                         ref, 
                                         nt, 
                                         win, 
                                         fileFig, 
                                         f, 
                                         min_read, 
                                         max_read, 
                                         min_count, 
                                         no_display,
                                         no_csv,
                                         ylim, 
                                         pub,
                                         split) 
 
        elif ana == 'mnt3dm':
            analysis.single_ref_coverage_21_22_24(seq1, 
                                                  ref, 
                                                  win, 
                                                  fileFig, 
                                                  f, 
                                                  min_read, 
                                                  max_read, 
                                                  min_count, 
                                                  no_display,
                                                  no_csv, 
                                                  ylim, 
                                                  pub,
                                                  split)

        elif ana =='CDP':
            if split is False:
                analysis.CDP_split(seq1, 
                                   seq2, 
                                   ref, 
                                   nt, 
                                   fileFig, 
                                   f, 
                                   min_read, 
                                   max_read, 
                                   min_count, 
                                   no_display,
                                   no_csv,
                                   pub,
                                   processes)
            else:
                analysis.CDP(seq1, 
                             seq2, 
                             ref, 
                             nt, 
                             fileFig, 
                             f, 
                             min_read, 
                             max_read, 
                             min_count, 
                             no_display,
                             no_csv,
                             pub,
                             processes)

    except KeyboardInterrupt:
        ### handle keyboard interrupt ###
        return 0


if __name__ == "__main__":
    main()
