#!/usr/bin/env python
# -*- coding: utf-8

import sys
import argparse

import anvio
import anvio.utils as u
import anvio.dbops as dbops
import anvio.terminal as terminal
import anvio.clustering as clustering

from anvio.errors import ConfigError, FilesNPathsError
from anvio.clusteringconfuguration import ClusteringConfiguration


__author__ = "A. Murat Eren"
__copyright__ = "Copyright 2015, The anvio Project"
__credits__ = []
__license__ = "GPL 3.0"
__version__ = anvio.__version__
__maintainer__ = "A. Murat Eren"
__email__ = "a.murat.eren@gmail.com"
__status__ = "Development"


run = terminal.Run()
progress = terminal.Progress()

def experimental_organization(args):
    split_names = []

    if not args.skip_store_in_db and not args.profile_db:
        raise ConfigError, "OK. When you don't use the --skip-store-in-db flag, you need to define a\
                            profile database to be explicit about where to store the resulting tree."

    if args.profile_db:
        dbops.is_profile_db(args.profile_db)
    dbops.is_annotation_db(args.annotation_db)

    if not args.skip_store_in_db and not args.name:
        raise ConfigError, "Since you have not used the --skip-store-in-db flag, this program will attempt\
                            store resulting clustering into the profile database, and it needs a name for\
                            this tree. Please use the --name flag to provide one."

    if args.name:
        u.is_this_name_OK_for_database('--name', args.name)

    if args.profile_db:
        profile_db = dbops.ProfileDatabase(args.profile_db)
        if int(profile_db.meta['merged']):
            split_names = profile_db.db.get_single_column_from_table('mean_coverage_splits', 'contig')
        else:
            split_names = profile_db.db.get_single_column_from_table('metadata_splits', 'contig')
        profile_db.disconnect()

    db_paths = {'ANNOTATION.db': args.annotation_db}
    config = ClusteringConfiguration(args.config_file, args.input_directory, db_paths = db_paths, row_ids_of_interest = split_names)

    config.print_summary(run)
    
    if args.dry_run:
        sys.exit()
    
    newick = clustering.order_contigs_simple(config, progress = terminal.Progress(), debug = True)
    
    if args.output_file:
        open(args.output_file, 'w').write(newick + '\n')
        run.info('Output', args.output_file, mc='green')

    if args.profile_db:
        dbops.add_hierarchical_clustering_to_db(args.profile_db, args.name, newick, run = run)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='why yes we do stuff here.')
    parser.add_argument('config_file', metavar = 'PATH', default = None, type=str,
                        help = 'Config file for clustering of contigs. See documentation for help.')
    parser.add_argument('-i', '--input-directory', metavar = 'INPUT_DIR', default = None, type=str,
                        help = 'Input directory where the input files addressed from the configuration\
                                file can be found (i.e., the profile database, if PROFILE.db::TABLE\
                                notation is used in the configuration file).')
    parser.add_argument('-a', '--annotation-db', metavar = 'ANNOTATION_DB',
                        help = 'anvio annotation database.', required = True)
    parser.add_argument('-p', '--profile-db', default = None, metavar = 'PROFILE_DB',
                        help = 'anvio annotation database.', required = False)
    parser.add_argument('-N', '--name', default = None, metavar = 'NAME',
                        help = "The name to use when storing the resulting clustering in the database.\
                                This name will appear in the interactive interface and other relevant\
                                interfaces. Please consider using a short and descriptive single-word\
                                (if you do not do that you will make anvi'o complain).")
    parser.add_argument('--skip-store-in-db', default = False, action = 'store_true', 
                        help = 'By defaut, the resulting tree is stored in the profile database.\
                                When declared, this flag skips that step.')
    parser.add_argument('-o', '--output-file', metavar = 'FILE', default = None, type=str,
                        help = 'To store the newick output.')
    parser.add_argument('-D', '--dry-run', default = False, action = 'store_true', 
                        help = 'Do not do anything, just print out the configuration.')
    
    args = parser.parse_args()

    try:
        experimental_organization(args)
    except ConfigError, e:
        print e
        sys.exit(-1)
    except FilesNPathsError, e:
        print e
        sys.exit(-2)
