//
//  XTLogConfig.m
//  TadsTerp
//
//  Created by Rune Berg on 16/04/14.
//  Copyright (c) 2014 Rune Berg. All rights reserved.
//

#import "XTLoggerLevel.h"
#import "XTLogConfig.h"
#import "XTLogger.h"
#import "XTLogAppenderULS.h"
#import "XTPrefs.h"
#import "XTLoggingClassesInitializer.h"


@implementation XTLogConfig

static XTLogger* logger;

static BOOL hasBeenInitialized = NO;
static NSMutableDictionary *levelByName; // "logger name" -> NSNumber(XTLoggerLevel)
static NSMutableDictionary *loggerByName;  // "logger name" -> XTLogger
static NSArray *defaultAppenders;

+ (void)initialize
{
	if (hasBeenInitialized) {
		// we can be called more than once
		return;
	}
	hasBeenInitialized = YES;

	levelByName = [NSMutableDictionary dictionary];
	levelByName[@"XTLogConfig"] = [NSNumber numberWithInteger:XT_DEFAULT_LOG_LEVEL];
		// because we don't register our own logger until after calling updateAndPersistPrefs

	loggerByName = [NSMutableDictionary dictionary];
	
	defaultAppenders = [NSArray arrayWithObject:[XTLogAppenderULS new]];
	
	[XTLoggingClassesInitializer initialize]; // will indirectly call our restoreFromPrefs
	
	[XTLogConfig updateAndPersistPrefs];

	logger = [XTLogger loggerForClass:[XTLogConfig class]];
}

+ (XTLogger *)loggerForName:(NSString *)name
{
	[XTLogConfig initialize]; // because we might get called too early

	XTLogger *res = loggerByName[name];
	if (res == nil) {
		[XTLogConfig registerLoggerForName:name];
		res = loggerByName[name];
	}
	return res;
}

+ (void)registerLoggerForClass:(Class)aClass
{
	[XTLogConfig initialize]; // because we might get called too early

	NSString *className = NSStringFromClass(aClass);
	[XTLogConfig registerLoggerForName:className];
}

+ (void)registerLoggerForName:(NSString *)name
{
	[XTLogConfig initialize]; // because we might get called too early

	XTLogger *logger = [[XTLogger alloc] initWithName:name];
	loggerByName[name] = logger;
	
	if (levelByName[name] == nil) {
		// There'll be a couple of early birds...
		levelByName[name] = [NSNumber numberWithInteger:XT_DEFAULT_LOG_LEVEL];
	}
}

+ (XTLoggerLevel)levelForName:(NSString *)name
{
	[XTLogConfig initialize]; // because we might get called too early

	if (levelByName[name] == nil) {
		XT_DEF_SELNAME;
		XT_WARN_1(@"had no level for logger named %@", name);
		levelByName[name] = [NSNumber numberWithInteger:XT_DEFAULT_LOG_LEVEL];
	}
	NSNumber *level = levelByName[name];
	XTLoggerLevel res = level.integerValue;
	return res;
}

+ (NSArray *)appendersForName:(NSString *)name
{
	[XTLogConfig initialize]; // because we might get called too early
	
	return defaultAppenders;
}

+ (void)restoreFromPrefs
{
	XTPrefs *prefs = [XTPrefs prefs];
	[levelByName addEntriesFromDictionary:prefs.logLevelByName.value];
}

+ (void)updateAndPersistPrefs
{
	XTPrefs *prefs = [XTPrefs prefs];
	[prefs updateLogLevelsFromDict:levelByName];
	[prefs persist];
}

@end
