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

import os
import sys
import pysam

import anvio
import anvio.terminal as terminal
import anvio.filesnpaths as filesnpaths

from anvio.errors import ConfigError
from anvio.errors import FilesNPathsError


__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__ = ['raw-bam-file',]
__provides__ = ['bam-file',]
__description__ = "Sort/Index BAM files"


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


def init_bam_file(input_file_path, output_file_path = None, num_threads = 1):
    """sort and index a BAM file"""

    input_file_path = os.path.abspath(input_file_path)

    if output_file_path:
        output_file_path = os.path.abspath(output_file_path)
        if not output_file_path.endswith('.bam'):
            raise ConfigError("The output file should end with extension '.bam'.")
    else:
        output_file_path = input_file_path + '-sorted.bam'

    filesnpaths.is_file_exists(input_file_path)
    filesnpaths.is_output_file_writable(output_file_path)

    progress.new('SORT')
    progress.update('Sorting BAM File... May take a while depending on the size.')

    # -@ is number of _additional_ threads (i.e the default is 0), so we subtract 1
    pysam.sort('-o', output_file_path, '-@', str(num_threads - 1), input_file_path)
    progress.end()

    run.info('Sorted BAM File', output_file_path)
    if not os.path.exists(output_file_path):
        raise ConfigError("Sorry. Something went wrong. Samtools thinks it generated the sorted output, yet it is not there :(")

    progress.new('INDEX')
    progress.update('Indexing BAM File...')
    pysam.index(output_file_path)
    progress.end()
    run.info('BAM File Index', output_file_path + '.bai', mc='green')


if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(description=__description__)
    parser.add_argument('input_file', metavar = 'BAM_FILE', help = 'BAM file to analyze')
    parser.add_argument(*anvio.A('output-file'), **anvio.K('output-file'))
    parser.add_argument(*anvio.A('num-threads'), **anvio.K('num-threads'))

    args = anvio.get_args(parser)

    if args.num_threads < 1:
        raise ConfigError("--num-threads should be at least 1.")

    try:
        init_bam_file(args.input_file, args.output_file, args.num_threads)
        sys.exit()
    except ConfigError as e:
        print(e)
        sys.exit(-1)
    except FilesNPathsError as e:
        print(e)
        sys.exit(-2)
