import os
import yaml
import logging
import logging.config

from parallels.core.registry import Registry
from parallels.core.utils.config_utils import get_option
from parallels.core.logging_context import InfoLogFormatter
from parallels.core.logging_context import DebugLogFormatter
from parallels.core.logging_context import IndentFilter


class Log(object):
	@staticmethod
	def configure(options):
		logging.captureWarnings(True)

		parallels_logger = logging.getLogger('parallels')
		paramiko_logger = logging.getLogger('paramiko')

		# clean up handlers list to prevent log entries duplicating
		parallels_logger.handlers = []
		paramiko_logger.handlers = []

		# load logging configuration from config, if present
		if options.panel_migrator_config is not None and os.path.exists(options.panel_migrator_config):
			with open(options.panel_migrator_config) as f:
				config = yaml.load(f)
				if 'logging' in yaml:
					logging.config.dictConfig(config['logging'])
					return

		registry = Registry.get_instance()

		if get_option('GLOBAL', 'use-separate-log', False):
			# write log into current session directory
			context = registry.get_context()
			info_log_path = context.session_files.get_path_to_info_log()
			debug_log_path = context.session_files.get_path_to_debug_log()
		else:
			# write log into common place
			var_dir = registry.get_var_dir()
			logs_dir = os.path.join(var_dir, 'logs')
			if not os.path.exists(os.path.join(logs_dir)):
				os.mkdir(logs_dir)
			info_log_path = os.path.join(logs_dir, 'panel-migrator.log')
			debug_log_path = os.path.join(logs_dir, 'panel-migrator.debug.log')

		parallels_logger.setLevel(logging.DEBUG)
		paramiko_logger.setLevel(logging.WARNING)

		info_file_handler = logging.FileHandler(info_log_path)
		info_file_handler.setLevel(logging.INFO)
		info_file_handler.setFormatter(InfoLogFormatter())
		info_file_handler.addFilter(IndentFilter())
		parallels_logger.addHandler(info_file_handler)

		debug_file_handler = logging.FileHandler(debug_log_path)
		debug_file_handler.setLevel(logging.NOTSET)
		debug_file_handler.setFormatter(DebugLogFormatter())
		debug_file_handler.addFilter(IndentFilter())
		parallels_logger.addHandler(debug_file_handler)
		paramiko_logger.addHandler(debug_file_handler)

		if not options.async and not options.quiet:
			# display log entries in console if is not async or quiet mode
			console_handler = logging.StreamHandler()
			console_handler.setLevel(logging.INFO)
			console_handler.setFormatter(InfoLogFormatter())
			console_handler.addFilter(IndentFilter())
			parallels_logger.addHandler(console_handler)