


import re
import sys

from .IDCounter import IDCounter

from .EnumLogLevel import EnumLogLevel
from .AbstractLogger import AbstractLogger
from .BufferLogger import BufferLogger
from .ConsoleLogger import ConsoleLogger
from .DetectionLogger_v0 import DetectionLogger_v0
from .DetectionLogger import DetectionLogger
from .FilterLogger import FilterLogger
from .MulticastLogger import MulticastLogger
from .NamedMulticastLogger import NamedMulticastLogger
from .NullLogger import NullLogger
#from .SimpleFileLogger import SimpleFileLogger
from .FileLogger import FileLogger
from .StringListLogger import StringListLogger
from .JSONLogger import JSONLogger

from .AbstractLogMessageFormatter import AbstractLogMessageFormatter
from .LogMessageFormatter import LogMessageFormatter, DEFAULT_LOG_MESSAGE_FORMATTER
from .ColoredLogMessageFormatter import ColoredLogMessageFormatter, COLOR_LOG_MESSAGE_FORMATTER





def instantiateLogMsgFormatter(cfg):
	if isinstance(cfg, dict):
		logMsgFormatterType = cfg["type"]
		if logMsgFormatterType == "default":
			if "extensitivity" in cfg:
				extensitivity = cfg["extensitivity"]
				if extensitivity == "full":
					DEFAULT_LOG_MESSAGE_FORMATTER.setOutputMode(DEFAULT_LOG_MESSAGE_FORMATTER.EnumOutputMode.FULL)
				elif extensitivity in [ "short", "shorted", "shortened" ]:
					DEFAULT_LOG_MESSAGE_FORMATTER.setOutputMode(DEFAULT_LOG_MESSAGE_FORMATTER.EnumOutputMode.SHORTED)
				elif extensitivity == "veryShort":
					DEFAULT_LOG_MESSAGE_FORMATTER.setOutputMode(DEFAULT_LOG_MESSAGE_FORMATTER.EnumOutputMode.VERY_SHORT)
				else:
					raise Exception("Unknown extensitivity: " + repr(extensitivity))
			return DEFAULT_LOG_MESSAGE_FORMATTER
		elif logMsgFormatterType == "color":
			if "extensitivity" in cfg:
				extensitivity = cfg["extensitivity"]
				if extensitivity == "full":
					COLOR_LOG_MESSAGE_FORMATTER.setOutputMode(COLOR_LOG_MESSAGE_FORMATTER.EnumOutputMode.FULL)
				elif extensitivity in [ "short", "shorted", "shortened" ]:
					COLOR_LOG_MESSAGE_FORMATTER.setOutputMode(COLOR_LOG_MESSAGE_FORMATTER.EnumOutputMode.SHORTED)
				elif extensitivity == "veryShort":
					COLOR_LOG_MESSAGE_FORMATTER.setOutputMode(COLOR_LOG_MESSAGE_FORMATTER.EnumOutputMode.VERY_SHORT)
				else:
					raise Exception("Unknown extensitivity: " + repr(extensitivity))
			return COLOR_LOG_MESSAGE_FORMATTER
		else:
			raise Exception("Unknown log message formatter: " + repr(cfg))
	else:
		if cfg == "default":
			return DEFAULT_LOG_MESSAGE_FORMATTER
		elif cfg == "color":
			return COLOR_LOG_MESSAGE_FORMATTER
		else:
			raise Exception("Unknown log message formatter: " + repr(cfg))
#



def instantiate(cfg):
	loggerType = cfg["type"]

	if loggerType == "BufferLogger":
		return BufferLogger.create()

	elif loggerType == "ConsoleLogger":
		logMsgFormatter = None
		if "logMsgFormatter" in cfg:
			logMsgFormatter = instantiateLogMsgFormatter(cfg["logMsgFormatter"])
		return ConsoleLogger.create(logMsgFormatter = logMsgFormatter)

	elif loggerType == "DetectionLogger_v0":
		return DetectionLogger_v0.create(instantiate(cfg["nested"]))

	elif loggerType == "DetectionLogger":
		return DetectionLogger.create(instantiate(cfg["nested"]))

	elif loggerType == "FilterLogger":
		if "minLogLevel" in cfg:
			logLevel = EnumLogLevel.parse(cfg["minLogLevel"])
		else:
			logLevel = EnumLogLevel.WARNING
		return FilterLogger.create(instantiate(cfg["nested"]), minLogLevel = logLevel)

	elif loggerType == "MulticastLogger":
		loggers = []
		for item in cfg["nested"]:
			loggers.append(instantiate(item))
		return MulticastLogger.create(*loggers)

	elif loggerType == "NamedMulticastLogger":
		loggers = {}
		for itemKey in cfg["nested"]:
			loggers[itemKey] = instantiate(cfg["nested"][itemKey])
		return NamedMulticastLogger.create(**loggers)

	elif loggerType == "NullLogger":
		return NullLogger.create()

	elif loggerType == "FileLogger":
		mode = cfg.get("fileMode", None)
		if mode != None:
			if isinstance(mode, int):
				mode = str(mode)
			if isinstance(mode, str):
				if re.match("^[0-7][0-7][0-7]$", mode):
					mode = int(mode, 8)
				else:
					raise Exception("Invalid mode specified for file logger!")
			else:
				raise Exception("Invalid mode specified for file logger!")
		return FileLogger.create(
			cfg["filePath"],
			cfg.get("rollOver", None),
			cfg.get("bAppendToExistingFile", True),
			cfg.get("bFlushAfterEveryLogMessage", True),
			mode)

	elif loggerType == "StringListLogger":
		return StringListLogger.create()

	elif loggerType == "JSONLogger":
		return JSONLogger.create(cfg["filePath"])

	else:
		raise Exception("Unknown logger type: " + loggerType)
#














