#!/usr/bin/env python
# -*- coding: utf-8
"""A script to export coverage values across samples of a given split in an anvi'o contigs db"""

import sys
import argparse

import anvio
import anvio.dbops as dbops
import anvio.utils as utils
import anvio.terminal as terminal
import anvio.filesnpaths as filesnpaths
import anvio.auxiliarydataops as auxiliarydataops

from anvio.errors import ConfigError, FilesNPathsError


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


run = terminal.Run()

def main(args):
    dbops.is_profile_db(args.profile_db)

    profile_db = dbops.ProfileSuperclass(args)

    if args.list_splits:
        print('\n'.join(sorted(list(profile_db.split_names))))
        sys.exit(0)

    if not args.output_file:
        raise ConfigError("You must declare an output file name. Because.")

    if not args.split_name:
        raise ConfigError("Please declare a split name. Like, the one you are interested in. If you\
                           would like to see the split names in the profile db, use the --list-splits\
                           flag. But there are like %d of them in there, so brace yourself for that." % \
                           (len(profile_db.split_names)))

    filesnpaths.is_output_file_writable(args.output_file)

    if not profile_db.auxiliary_profile_data_available:
        raise ConfigError("In order to get what you want from this program, you need the auxiliary\
                           data file associated with this profile to be present. Now this program\
                           will quit gracefully, and will let you imagine what might have gone\
                           wrong.")

    if args.split_name not in profile_db.split_names:
        raise ConfigError("The split '%s' does not seem to be in your profile database :/" % args.split_name)
    else:
        run.info('Split name', args.split_name)

    sample_names = profile_db.p_meta['samples']
    run.info('Sample names', ', '.join(sample_names if len(sample_names) < 5 else (sample_names[:5] + ['(.. %d more ..)' % (len(sample_names) - 5)])))

    split_coverage_values = auxiliarydataops.AuxiliaryDataForSplitCoverages(profile_db.auxiliary_data_path, profile_db.p_meta['contigs_db_hash']).get(args.split_name)
    num_nucleotides = len(list(split_coverage_values.values())[0])

    run.info('Num nucleotide positions in split', num_nucleotides)

    d = {}
    for sample_name in sorted(sample_names):
        d[sample_name] = dict([(str(pos + 1), split_coverage_values[sample_name][pos]) for pos in range(0, num_nucleotides)])

    utils.store_dict_as_TAB_delimited_file(d, args.output_file, ['sample'] + [str(p + 1) for p in sorted([pos for pos in range(0, num_nucleotides)])])

    run.info('Coverage values', args.output_file, mc='green')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Export splits and the coverage table from database')

    parser.add_argument(*anvio.A('profile-db'), **anvio.K('profile-db'))
    parser.add_argument(*anvio.A('split-name'), **anvio.K('split-name'))
    parser.add_argument(*anvio.A('output-file'), **anvio.K('output-file'))
    parser.add_argument(*anvio.A('list-splits'), **anvio.K('list-splits'))

    args = parser.parse_args()

    try:
        main(args)
    except ConfigError as e:
        print(e)
        sys.exit(-1)
    except FilesNPathsError as e:
        print(e)
        sys.exit(-1)
