#!/usr/bin/env python
# -*- coding: utf-8
"""Fetches information from the variable positions table"""

import sys
import argparse

import anvio

from anvio.errors import ConfigError, FilesNPathsError
from anvio.variabilityops import variability_engines


__author__ = "Developers of anvi'o (see AUTHORS.txt)"
__copyright__ = "Copyleft 2015-2018, the Meren Lab (http://merenlab.org/)"
__credits__ = []
__license__ = "GPL 3.0"
__version__ = anvio.__version__
__maintainer__ = "A. Murat Eren"
__email__ = "a.murat.eren@gmail.com"
__requires__ = ['contigs-db', 'profile-db', 'structure-db', 'bin']
__provides__ = ['variability-profile']


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Extract information for variable positions')

    groupA = parser.add_argument_group('DATABASES', "Declaring relevant anvi'o databases. First things first. Some\
                                                     are mandatory, some are optional.")
    groupA.add_argument(*anvio.A('profile-db'), **anvio.K('profile-db'))
    groupA.add_argument(*anvio.A('contigs-db'), **anvio.K('contigs-db'))
    groupA.add_argument(*anvio.A('structure-db'), **anvio.K('structure-db', {"required": False}))

    groupB = parser.add_argument_group('FOCUS :: BIN', "You need to pick someting to focus. You can ask anvi'o\
                                                             to work with a bin in a collection.")
    groupB.add_argument(*anvio.A('collection-name'), **anvio.K('collection-name'))
    groupB.add_argument(*anvio.A('bin-id'), **anvio.K('bin-id'))

    groupC = parser.add_argument_group('FOCUS :: SPLIT NAMES', 'Alternatively you can declare split names to focus.')
    groupC.add_argument(*anvio.A('splits-of-interest'), **anvio.K('splits-of-interest'))

    groupD = parser.add_argument_group('FOCUS :: GENE CALLER IDs', 'Alternatively you can declare gene caller IDs to focus.')
    groupD.add_argument(*anvio.A('genes-of-interest'), **anvio.K('genes-of-interest'))
    groupD.add_argument(*anvio.A('gene-caller-ids'), **anvio.K('gene-caller-ids'))
    groupD.add_argument(*anvio.A('only-if-structure'), **anvio.K('only-if-structure'))

    groupE = parser.add_argument_group('SAMPLES', "You can ask anvi'o to focus only on a subset of samples.")
    groupE.add_argument(*anvio.A('samples-of-interest'), **anvio.K('samples-of-interest'))

    groupF = parser.add_argument_group('ENGINE', "Set your engine. This is important as it will define the output\
                                                  profile you will get from this program. The engine can focus on\
                                                  nucleotides (NT), codons (CDN), or an amino acids (AA).")
    groupF.add_argument(*anvio.A('engine'), **anvio.K('engine'))
    groupF.add_argument(*anvio.A('skip-synonymity'), **anvio.K('skip-synonymity'))

    groupG = parser.add_argument_group('FILTERS', 'Parameters that will help you to do a very precise analysis.\
                                                  If you declare nothing from this bunch, you will get "everything"\
                                                  to play with, which is not necessarily a good thing...')
    groupG.add_argument(*anvio.A('num-positions-from-each-split'), **anvio.K('num-positions-from-each-split'))
    groupG.add_argument(*anvio.A('min-departure-from-reference'), **anvio.K('min-departure-from-reference'))
    groupG.add_argument(*anvio.A('max-departure-from-reference'), **anvio.K('max-departure-from-reference'))
    groupG.add_argument(*anvio.A('min-departure-from-consensus'), **anvio.K('min-departure-from-consensus'))
    groupG.add_argument(*anvio.A('max-departure-from-consensus'), **anvio.K('max-departure-from-consensus'))
    groupG.add_argument(*anvio.A('min-occurrence-of-variable-positions'), **anvio.K('min-occurrence-of-variable-positions'))
    groupG.add_argument(*anvio.A('min-coverage-in-each-sample'), **anvio.K('min-coverage-in-each-sample'))
    groupG.add_argument(*anvio.A('quince-mode'), **anvio.K('quince-mode'))

    groupH = parser.add_argument_group('OUTPUT', 'Output file and style')
    groupH.add_argument(*anvio.A('output-file'), **anvio.K('output-file', {'default': 'variability.txt', 'metavar': 'VARIABILITY_PROFILE'}))
    groupH.add_argument(*anvio.A('include-contig-names'), **anvio.K('include-contig-names'))
    groupH.add_argument(*anvio.A('include-split-names'), **anvio.K('include-split-names'))
    groupH.add_argument(*anvio.A('compute-gene-coverage-stats'), **anvio.K('compute-gene-coverage-stats'))

    args = anvio.get_args(parser)

    try:
        if args.engine not in variability_engines:
            raise ConfigError("You are doing something wrong :/ Focus '%s' does not correspond to an available engine." % args.engine)

        variability_engine = variability_engines[args.engine](args)
        variability_engine.process()
        variability_engine.report()
    except ConfigError as e:
        print(e)
        sys.exit(1)
    except FilesNPathsError as e:
        print(e)
        sys.exit(2)
