#!/usr/bin/env python

import logging
import argparse
import kombu
import socket
import sys
import datetime
import termcolor

from villas.controller import __version__ as version

from villas.controller.config import Config, ConfigType
from villas.controller.command import Command

LOGGER = logging.getLogger('villas.controller')

_LOG_LEVEL_STRINGS = ['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG']

def _log_level_string_to_int(log_level_string):
	if not log_level_string in _LOG_LEVEL_STRINGS:
		message = 'invalid choice: {0} (choose from {1})'.format(log_level_string, _LOG_LEVEL_STRINGS)
		raise argparse.ArgumentTypeError(message)

	log_level_int = getattr(logging, log_level_string, logging.INFO)

	# check the logging log_level_choices have not changed from our expected values
	assert isinstance(log_level_int, int)

	return log_level_int

def setup_logging(args):
	logging.basicConfig(level=args.log_level,
		format='%(asctime)s | %(levelname)s | %(name)s | %(message)s',
		datefmt='%Y-%m-%d %H:%M:%S'
	)

	root = logging.getLogger(__name__)
	root.setLevel(args.log_level)

	amqp = logging.getLogger('amqp')
	amqp.setLevel(logging.INFO)

	kombu = logging.getLogger('kombu')
	kombu.setLevel(args.log_level)

	villas = logging.getLogger('villas')
	villas.setLevel(args.log_level)

def setup_argparse():
	# Main parser
	parser = argparse.ArgumentParser(
		prog = 'villas-ctl',
		formatter_class = argparse.RawTextHelpFormatter,
		epilog = ("VILLAScontroller %s\n"
			  " Copyright 2014-%d, Institute for Automation of Complex Power Systems, EONERC\n"
 			  " Steffen Vogel <StVogel@eonerc.rwth-aachen.de>\n"
			% (
				termcolor.colored(version, "blue"),
				datetime.date.today().year
			)
		)
	)

	parser.add_argument('-b', '--broker',
		help = 'URL of AMQP broker'
	)

	parser.add_argument('-v', '--version',
		help = 'Show program version and exit',
		action = 'version',
		version = version
	)

	parser.add_argument('-c', '--config',
		help = 'Path of configuration file',
		type = ConfigType(),
		default = Config()
	)

	parser.add_argument('-d', '--log-level',
		default = 'INFO',
		dest = 'log_level',
		type = _log_level_string_to_int,
		nargs = '?',
		help = 'Set the logging output level. {0}'.format(_LOG_LEVEL_STRINGS)
	)

	# Add parsers for subcommands
	Command.register_subcommands(parser)

	return parser

if __name__ == '__main__':
	# Show log messages during parsing
	l = logging.getLogger('villas')
	l.setLevel(logging.DEBUG)

	parser = setup_argparse()
	args = parser.parse_args()

	setup_logging(args)

	if args.broker is not None:
		broker = args.broker
	elif args.config is not None and 'broker' in args.config.json and 'url' in args.config.json['broker']:
		broker = args.config.json['broker']['url']
	else:
		broker = 'amqp://guest:guest@localhost/%2F'

	try:
		with kombu.Connection(broker, connect_timeout=3) as c:
			LOGGER.info('Connecting to: %s' % broker)
			c.connect()

			args.func(c, args)

	except ConnectionRefusedError:
		LOGGER.error('Connection refused!')
	except socket.timeout:
		LOGGER.error('Connection timeout!')
	else:
		LOGGER.info('Goodbye')
