//
//  XTPrefsItem.m
//  XTads
//
//  Created by Rune Berg on 31/03/2018.
//  Copyright © 2018 Rune Berg. All rights reserved.
//

#import "XTPrefsItem.h"
#import "XTPrefsItem_private.h"
#import "XTLogger.h"


@interface XTPrefsItem ()

@end


@implementation XTPrefsItem

static XTLogger* logger;

+ (void)initialize
{
	logger = [XTLogger loggerForClass:[XTPrefsItem class]];
}

+ (instancetype)itemWithDefaultValue:(id)defaultValue
					 userDefaultsKey:(NSString *)userDefaultsKey;
{
	return [XTPrefsItem itemWithDefaultValue:defaultValue userDefaultsKey:userDefaultsKey valueTransformer:nil];
}

+ (instancetype)itemWithDefaultValue:(id)defaultValue
					 userDefaultsKey:(NSString *)userDefaultsKey
					valueTransformer:(XTPrefsValueTransformer *)valueTransformer
{
	XTPrefsItem *item = [XTPrefsItem new];
	item.defaultValue = [defaultValue copy]; // make .defaultValue immutable
	item.userDefaultsKey = userDefaultsKey;
	item.valueTransformer = valueTransformer;
	item.value = [item copyOfDefaultValue];
	item.skipResetToDefault = NO;
	return item;
}

- (void)resetToDefaultValue
{
	if (! self.skipResetToDefault) {
		if (! [self.defaultValue isEqual:self.value]) {
			self.value = [self copyOfDefaultValue];
		}
	}
}

- (id)copyOfDefaultValue
{
	id res = [self.defaultValue copy];
	return res;
}

- (void)persist
{
	XT_DEF_SELNAME;

	if (self.value == nil) {
		XT_WARN_1(@"nil value for %@ - resetting to default", self.userDefaultsKey);
		self.value = [self copyOfDefaultValue];
	}
	
	id persistedValue;
	if (self.valueTransformer == nil) {
		persistedValue = self.value;
	} else {
		persistedValue = [self.valueTransformer toPersistedValue:self.value];
	}
	[self internalPersist:persistedValue];
}

- (void)internalPersist:(id)persistedValue
{
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	[userDefaults setObject:persistedValue forKey:self.userDefaultsKey];
}

- (void)restoreFromPersisted
{
	XT_DEF_SELNAME;
	
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	
	id persistedValue = nil;
	if ([self valueExistsForKey:self.userDefaultsKey inUserDefaults:userDefaults]) {
		persistedValue = [self internalRestoreFromPersisted];
		if (persistedValue == nil) {
			XT_WARN_1(@"nil for key %@ after internalRestoreFromPersisted - using default", self.userDefaultsKey);
		}
	} else {
		// This will happen on very first XTads launch 
		//XT_WARN_1(@"nil for key %@ (no persisted value) - using default", self.userDefaultsKey);
	}

	id prefsValue;
	if (persistedValue == nil) {
		prefsValue = [self copyOfDefaultValue];
	} else if (self.valueTransformer == nil) {
		prefsValue = persistedValue;
	} else {
		prefsValue = [self.valueTransformer toPrefsValue:persistedValue];
		if (prefsValue == nil) {
			XT_WARN_1(@"nil for key %@ after calling valueTransformer - using default", self.userDefaultsKey);
			prefsValue = [self copyOfDefaultValue];
		}
	}
	
	self.value = prefsValue;
}

- (id)internalRestoreFromPersisted
{
	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
	id persistedValue = [userDefaults objectForKey:self.userDefaultsKey];
	return persistedValue;
}

- (BOOL)valueExistsForKey:(NSString *)key inUserDefaults:(NSUserDefaults *)userDefaults
{
	id value = [userDefaults objectForKey:key];
	return (value != nil);
}

- (void) addObserver:(NSObject *)observer
{
	[self addObserver:observer forKeyPath:NSStringFromSelector(@selector(value)) options:0 context:NULL];
}

- (void) removeObserver:(NSObject *)observer
{
	[self removeObserver:observer forKeyPath:NSStringFromSelector(@selector(value))];
}

@end
