# Path: base/rethink_io.py
# class rethink_io(object):
#     def __init__(self, **kwargs):
#         pass
# 
#     def assign_rethink(self, rethink_host, auth_key, local=False, **kwargs):
#         '''
#         Assign rethink_host, auth_key, return as tuple
#         '''
#         if local:
#             rethink_host = 'localhost'
#         elif rethink_host is not None:
#             rethink_host=rethink_host
#         else:
#             try:
#                 rethink_host = os.environ['RETHINK_HOST']
#             except:
#                 raise Exception("Missing rethink host - is $RETHINK_HOST set?")
#         if local:
#             auth_key = None
#         elif auth_key is not None:
#             auth_key = auth_key
#         else:
#             try:
#                 auth_key = os.environ['RETHINK_AUTH_KEY']
#             except:
#                 raise Exception("Missing rethink auth_key")
#         return rethink_host, auth_key
# 
#     def connect_rethink(self, db, rethink_host='localhost', auth_key=None, **kwargs):
#         '''
#         Connect to rethink database,
#         '''
#         if rethink_host == 'localhost':
#             try:
#                 conn = r.connect(host=rethink_host, port=28015, db=db).repl()
#                 print("Connected to the \"" + db + "\" database")
#                 return conn
#             except:
#                 raise Exception("Failed to connect to the database, " + db)
#         else:
#             try:
#                 conn = r.connect(host=rethink_host, port=28015, db=db, auth_key=auth_key).repl()
#                 print("Connected to the \"" + db + "\" database")
#                 return conn
#             except:
#                 raise Exception("Failed to connect to the database, " + db)
# 
#     def check_table_exists(self, database, table):
#         '''
#         Check for existing table
#         '''
#         existing_tables = r.db(database).table_list().run()
#         if table not in existing_tables:
#             raise Exception("No table exists yet for " + table + " available are " + str(existing_tables))
# 
#     def get_upload_date(self):
#         return str(datetime.datetime.strftime(datetime.datetime.utcnow(),'%Y-%m-%d'))
# 
#     def get_upload_timestamp(self):
#         return str(datetime.datetime.strftime(datetime.datetime.utcnow(),'%Y-%m-%d-%H-%M'))
# 
#     def check_optional_attributes(self, doc, optional_fields):
#         '''
#         Reassign unknowns from '?' or '' to 'None'
#         Create and assign 'None' to optional attributes that don't exist
#         '''
#         for key in doc.keys():
#             if doc[key] == '?' or doc[key] == '':
#                 doc[key] = None
#             if isinstance(doc[key], (str)):
#                 doc[key] = doc[key].strip()
#         for atr in optional_fields:
#             if atr not in doc:
#                 doc[atr] = None
# 
#     def check_required_attributes(self, doc, required_fields, index_fields, output=False):
#         '''
#         Checks that required upload attributes are present and not equal to None for given virus
#         :return: returns true if it has all required upload attributes, else returns false and prints missing attributes
#         '''
#         missing_attributes = []
#         for atr in required_fields:
#             if atr in doc and doc[atr] is not None:
#                 pass
#             else:
#                 missing_attributes.append(atr)
#         if len(missing_attributes) > 0:
#             if output:
#                 print("This document is missing a required attribute and will be removed from upload sequences")
#                 print([doc[index] for index in index_fields if index in doc])
#                 print("Missing attributes: " + str(missing_attributes))
#             return False
#         else:
#             return True
# 
#     def delete_extra_fields(self, doc, fields, index_fields):
#         '''
#         Delete attributes not defined as a field
#         '''
#         for key in doc.keys():
#             if key not in fields:
#                 print("Deleting document info " + key + ": " + doc[key] + " from " + str([doc[index] for index in index_fields if index in doc]))
#                 del doc[key]


import os, json, datetime, sys, re
import numpy as np
    import argparse
        import time
from rethinkdb import r
from Bio import SeqIO
from base.rethink_io import rethink_io
        from collections import defaultdict
    parser.add_argument('--relaxed_interval', action="store_true", help="Relaxed comparison to date interval, 2016-XX-XX in 2016-01-01 - 2016-03-01")

    def duplicate_resolver(resolve_method):
        method = str(resolve_method)
        accepted_methods = ('keep_duplicates', 'choose_longest', 'choose_genbank', 'split_passage')
        if method not in accepted_methods:
            msg = '"{}" is not a supported duplicate resolve method'.format(method)
            raise argparse.ArgumentTypeError(msg)
        return method

    parser.add_argument('--resolve_method', type=duplicate_resolver, default="choose_longest", help="Set method of resolving duplicates for the same locus, options are \'keep_duplicates\', \'choose_longest\', \'choose_genbank\' and \'split_passage\'")
    return parser


class download(object):
    def __init__(self, database, virus, **kwargs):
        '''
        parser for virus, fasta fields, output file names, output file format path, interval
        '''
        self.virus = virus.lower()
        self.viruses_table = virus + "_viruses"
        self.sequences_table = virus + "_sequences"
        self.database = database.lower()

    def connect_rethink(self, **kwargs):
        if self.database not in ['vdb', 'test_vdb', 'test']:
            raise Exception("Can't download from this database: " + self.database)
        self.rethink_io = rethink_io()
        self.rethink_host, self.auth_key = self.rethink_io.assign_rethink(**kwargs)
        self.rethink_io.connect_rethink(self.database, self.rethink_host, self.auth_key)

# Path: base/rethink_io.py
# class rethink_io(object):
#     def __init__(self, **kwargs):
#         pass
# 
#     def assign_rethink(self, rethink_host, auth_key, local=False, **kwargs):
#         '''
#         Assign rethink_host, auth_key, return as tuple
#         '''
#         if local:
#             rethink_host = 'localhost'
#         elif rethink_host is not None:
#             rethink_host=rethink_host
#         else:
#             try:
#                 rethink_host = os.environ['RETHINK_HOST']
#             except:
#                 raise Exception("Missing rethink host - is $RETHINK_HOST set?")
#         if local:
#             auth_key = None
#         elif auth_key is not None:
#             auth_key = auth_key
#         else:
#             try:
#                 auth_key = os.environ['RETHINK_AUTH_KEY']
#             except:
#                 raise Exception("Missing rethink auth_key")
#         return rethink_host, auth_key
# 
#     def connect_rethink(self, db, rethink_host='localhost', auth_key=None, **kwargs):
#         '''
#         Connect to rethink database,
#         '''
#         if rethink_host == 'localhost':
#             try:
#                 conn = r.connect(host=rethink_host, port=28015, db=db).repl()
#                 print("Connected to the \"" + db + "\" database")
#                 return conn
#             except:
#                 raise Exception("Failed to connect to the database, " + db)
#         else:
#             try:
#                 conn = r.connect(host=rethink_host, port=28015, db=db, auth_key=auth_key).repl()
#                 print("Connected to the \"" + db + "\" database")
#                 return conn
#             except:
#                 raise Exception("Failed to connect to the database, " + db)
# 
#     def check_table_exists(self, database, table):
#         '''
#         Check for existing table
#         '''
#         existing_tables = r.db(database).table_list().run()
#         if table not in existing_tables:
#             raise Exception("No table exists yet for " + table + " available are " + str(existing_tables))
# 
#     def get_upload_date(self):
#         return str(datetime.datetime.strftime(datetime.datetime.utcnow(),'%Y-%m-%d'))
# 
#     def get_upload_timestamp(self):
#         return str(datetime.datetime.strftime(datetime.datetime.utcnow(),'%Y-%m-%d-%H-%M'))
# 
#     def check_optional_attributes(self, doc, optional_fields):
#         '''
#         Reassign unknowns from '?' or '' to 'None'
#         Create and assign 'None' to optional attributes that don't exist
#         '''
#         for key in doc.keys():
#             if doc[key] == '?' or doc[key] == '':
#                 doc[key] = None
#             if isinstance(doc[key], (str)):
#                 doc[key] = doc[key].strip()
#         for atr in optional_fields:
#             if atr not in doc:
#                 doc[atr] = None
# 
#     def check_required_attributes(self, doc, required_fields, index_fields, output=False):
#         '''
#         Checks that required upload attributes are present and not equal to None for given virus
#         :return: returns true if it has all required upload attributes, else returns false and prints missing attributes
#         '''
#         missing_attributes = []
#         for atr in required_fields:
#             if atr in doc and doc[atr] is not None:
#                 pass
#             else:
#                 missing_attributes.append(atr)
#         if len(missing_attributes) > 0:
#             if output:
#                 print("This document is missing a required attribute and will be removed from upload sequences")
#                 print([doc[index] for index in index_fields if index in doc])
#                 print("Missing attributes: " + str(missing_attributes))
#             return False
#         else:
#             return True
# 
#     def delete_extra_fields(self, doc, fields, index_fields):
#         '''
#         Delete attributes not defined as a field
#         '''
#         for key in doc.keys():
#             if key not in fields:
#                 print("Deleting document info " + key + ": " + doc[key] + " from " + str([doc[index] for index in index_fields if index in doc]))
#                 del doc[key]


# Path: vdb/download.py
import os, json, datetime, sys, re
import numpy as np
    import argparse
        import time
from rethinkdb import r
from Bio import SeqIO
from base.rethink_io import rethink_io
        from collections import defaultdict

    parser.add_argument('--relaxed_interval', action="store_true", help="Relaxed comparison to date interval, 2016-XX-XX in 2016-01-01 - 2016-03-01")

    def duplicate_resolver(resolve_method):
        method = str(resolve_method)
        accepted_methods = ('keep_duplicates', 'choose_longest', 'choose_genbank', 'split_passage')
        if method not in accepted_methods:
            msg = '"{}" is not a supported duplicate resolve method'.format(method)
            raise argparse.ArgumentTypeError(msg)
        return method

    parser.add_argument('--resolve_method', type=duplicate_resolver, default="choose_longest", help="Set method of resolving duplicates for the same locus, options are \'keep_duplicates\', \'choose_longest\', \'choose_genbank\' and \'split_passage\'")
    return parser


class download(object):
    def __init__(self, database, virus, **kwargs):
        '''
        parser for virus, fasta fields, output file names, output file format path, interval
        '''
        self.virus = virus.lower()
        self.viruses_table = virus + "_viruses"
        self.sequences_table = virus + "_sequences"
        self.database = database.lower()

    def connect_rethink(self, **kwargs):
        if self.database not in ['vdb', 'test_vdb', 'test']:
            raise Exception("Can't download from this database: " + self.database)
        self.rethink_io = rethink_io()
        self.rethink_host, self.auth_key = self.rethink_io.assign_rethink(**kwargs)
        self.rethink_io.connect_rethink(self.database, self.rethink_host, self.auth_key)

        self.rethink_io.check_table_exists(self.database, self.viruses_table)