#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import time
import logging
import argparse
from hichub.Constants import *

########################################################################
# HiCHub Modules
########################################################################

def main():
	"""The Main function/pipeline for hichub.
	"""
	# Parse options...
	argparser = prepare_argparser()
	args = argparser.parse_args()
	
	logging.basicConfig(level=logging.DEBUG,
						format='[%(asctime)s]: %(message)s ',
						datefmt='%Y-%m-%d %H:%M:%S',
						stream=sys.stdout,
						filemode="w"
						)    
	print("welcome")
	print("The python env is: " + sys.version)
	print("usage: hichub [-h] [-v] {test,diff,convert} ...")
	print("hichub -- A toolset to detect and analyze differential Hubs")
	print("positional arguments:")
	print("  {test,diff,convert}  sub-command help")
	print("    test               Output for test parser")
	print("    diff               Parser for diff hubs")
	print("    convert            Convert multi .hic to txt format --> Format should be:")
	print("                       #chr bin1 bin2 Count")
	print("optional arguments:")
	print("  -h, --help           show this help message and exit")
	print("  -v, --version        show program's version number and exit")

	if (hasattr(args, 'outdir')):  # use a output directory to store HicHub output
		if not os.path.exists( args.outdir ):
			try:
				os.makedirs( args.outdir )
			except:
				sys.exit( "Output directory (%s) could not be created. Terminating program." % args.outdir )

## subcommand
	subcommand  = args.subcommand
	
	if subcommand == "convert":
		from hichub.convert_multi_hic_to_txt import run
		logging.info("This module can convert multiple .hic files into a txt")
		print('-' * 50)
		start_time = time.time()
		run( args )
		end_time = time.time()
		print('-' * 50)
		logging.info("Run complete: %s elapsed" % elapsed_time(start_time, end_time))

	elif subcommand == "diff":
		logging.info("Beginning HicHub diff hubs calling")
		print('-' * 50)
		start_time = time.time()
		from hichub.call_diff import run
		run( args )
		end_time = time.time()
		print('-' * 50)
		logging.info("Run complete: %s elapsed" % elapsed_time(start_time, end_time))


	elif subcommand == "test":
		logging.info("Beginning Test run")
		print('-' * 50)
		start_time = time.time()
		from hichub.test import run
		run( )
		end_time = time.time()
		print('-' * 50)
		logging.info("Run complete: %s elapsed" % elapsed_time(start_time, end_time))
	return argparser


def prepare_argparser():
	"""
	Prepare optparser object. New options will be added in this function first.
	"""
	description = "%(prog)s -- A toolset to detect and analyze differential Hubs"
	epilog = "For command line options of each command, type: %(prog)s COMMAND -h"
	# top-level parser
	parser = argparse.ArgumentParser( description = description, epilog = epilog)
	parser.add_argument("-v", "--version", action="version", version="%(prog)s "+ hichub_VERSION)
	
	subparsers = parser.add_subparsers( dest = 'subcommand', 
	help='sub-command help' 
	)

	# command for 'test'
	add_test_parser( subparsers )
	# command for 'diff'
	add_diff_parser( subparsers )
	# command for 'convert'
	add_convert_parser( subparsers )
	
	return parser

def add_outdir_option( parser ):
	parser.add_argument("--outdir", dest = "outdir", type = str, default = '',
						help = "If specified all output files will be written to that directory. Default: the current working directory")


def add_test_parser( subparsers ):
	"""
	Add test function 'test' argument parsers.
	"""
	parser_test = subparsers.add_parser("test", help = "Output for test parser")
	## detail in subparser
	test_parser_group = parser_test.add_argument_group( "general arguments" )
	test_parser_group.add_argument( "-g", "--GTF-file", dest = "inputfile",
	metavar = "GTFFILE", type = str, required = True, help = "Input annotation GTF filename. REQUIRED." )
	return

def add_convert_parser( subparsers ):
	"""
	Convert multi .hic to txt format --> Format should be: #chr	bin1	bin2	Count"
	"""
	parser_tem = subparsers.add_parser("convert", help = "Convert multi .hic to txt format --> Format should be: #chr	bin1	bin2	Count")
	## detail in subparser
	parser_tem_group = parser_tem.add_argument_group( "general arguments" )
	
	parser_tem_group.add_argument("-i", "--in", action="store", type=str, required = True,
		dest="input_path", help="Path to Input HiC file in .hic format", metavar="<file>")
	
	parser_tem_group.add_argument("-n", "--norm", action="store", type=str, 
		dest="norm_hic", help="Norm of .hic file you are going to apply.", metavar="<str>")
		
	parser_tem_group.add_argument("-f", "--file_name", action="store", type=str, required = True,
		dest="file_name", help="Name of File. Delimiter ',', for example 'file1,file2' ", metavar="<str>")
		
	parser_tem_group.add_argument("-l", "--file_label", action="store", type=str, required = True,
		dest="res", help="Name of File.Delimiter ',', for example 'label1,label2'", metavar="<str>")
		
	parser_tem_group.add_argument("-r", "--resolution", action="store", type=int, required = True,
		dest="res", help="Resolution of HiC txt", metavar="<int>")
	
	return 


def add_diff_parser( subparsers ):
	"""
	Module for Diff Hubs argument parsers.
	"""
	parser_diff = subparsers.add_parser("diff", help = "Parser for diff hubs")
	## detail in subparser
	diff_parser_group = parser_diff.add_argument_group( "general arguments" )
	
	diff_parser_group.add_argument("-i", "--in", action="store", type=str, required = True,
		dest="input_path", help="Path to Input HiC file in txt format", metavar="<file>")
	
	diff_parser_group.add_argument("-f", "--foreground_name", action="store", type=str, required = True,
		dest="fore_name", help="Name of condition as foreground.", metavar="<str>")
		
	diff_parser_group.add_argument("-b", "--background_name", action="store", type=str, required = True,
		dest="back_name", help="Name of condition as background.", metavar="<str>")
		
	diff_parser_group.add_argument("-r", "--resolution", action="store", type=int, required = True,
		dest="res", help="Resolution of HiC txt", metavar="<int>")
	
	diff_parser_group.add_argument("-p", "--pvalue", action="store", type=float, required = False,
		default=0.00001, dest="pvalue", help="Optional: pvalue cutoff for output (diff hub)", metavar="<float>")
		
	diff_parser_group.add_argument("-t", "--num_threads", action="store", type=int, required = False,
		default=1, dest="thread", help="Optional: Number of threads to run, default=1", metavar="<int>")
	
	return 


def elapsed_time(start_time, end_time):
	elapsed_sec = end_time - start_time
	h = int(elapsed_sec / (60 * 60))
	m = int((elapsed_sec % (60 * 60)) / 60)
	s = int(elapsed_sec % 60)
	return "{}:{:>02}:{:>02}".format(h, m, s)


if __name__ == '__main__':
	try:
		main()
	except KeyboardInterrupt:
		sys.stderr.write("User interrupted me!\n")
		sys.exit(0)
