/*	CFApplicationPreferences.c
	Copyright (c) 1998-2017, Apple Inc. and the Swift project authors
 
	Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors
	Licensed under Apache License v2.0 with Runtime Library Exception
	See http://swift.org/LICENSE.txt for license information
	See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
	Responsibility: David Smith
*/

#include <CoreFoundation/CFPreferences.h>
#include "CFInternal.h"
#include <CoreFoundation/CFUniChar.h>
#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFLocale.h>
#include <CoreFoundation/CFNumberFormatter.h>
#include <CoreFoundation/CFDateFormatter.h>
#include <sys/types.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
#include <unistd.h>
#endif

static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self);
void _CFPreferencesDomainSetMultiple(CFPreferencesDomainRef domain, CFDictionaryRef dict);
static void updateDictRep(_CFApplicationPreferences *self);
static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList);
Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain);
static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName);

// Right now, nothing is getting destroyed pretty much ever.  We probably don't want this to be the case, but it's very tricky - domains live in the cache as well as a given application's preferences, and since they're not CFTypes, there's no reference count.  Also, it's not clear we ever want domains destroyed.  When they're synchronized, they clear their internal state (to force reading from the disk again), so they're not very big.... REW, 12/17/98

CFPropertyListRef CFPreferencesCopyAppValue(CFStringRef key, CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    
    standardPrefs = _CFStandardApplicationPreferences(appName);
    return standardPrefs ? _CFApplicationPreferencesCreateValueForKey2(standardPrefs, key) : NULL;
}

CF_EXPORT Boolean CFPreferencesAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    Boolean result, valid;
    CFTypeID typeID = 0;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    value = CFPreferencesCopyAppValue(key, appName);
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return false;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        if (CFStringCompare((CFStringRef)value, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = true;
        } else if (CFStringCompare((CFStringRef)value, CFSTR("false"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)value, CFSTR("NO"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            *keyExistsAndHasValidFormat = true;
            result = false;
        } else {
            *keyExistsAndHasValidFormat = false;
            result = false;
        }
    } else if (typeID == CFNumberGetTypeID()) {
        if (CFNumberIsFloatType((CFNumberRef)value)) {
            *keyExistsAndHasValidFormat = false;
            result = false;
        } else {
            int i;
            *keyExistsAndHasValidFormat = true;
            CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &i);
            result = (i == 0) ? false : true;
        }
    } else if (typeID == CFBooleanGetTypeID()) {
        result = (value == kCFBooleanTrue);
        *keyExistsAndHasValidFormat = true;
    } else {
        // Unknown type
        result = false;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}

CF_PRIVATE CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFPropertyListRef value;
    CFIndex result;
    CFTypeID typeID = 0;
    Boolean valid;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    value = CFPreferencesCopyAppValue(key, appName);
    if (!keyExistsAndHasValidFormat) {
        keyExistsAndHasValidFormat = &valid;
    }
    if (!value) {
        *keyExistsAndHasValidFormat = false;
        return 0;
    }
    typeID = CFGetTypeID(value);
    if (typeID == CFStringGetTypeID()) {
        SInt32 charIndex = 0;
        SInt32 intVal;
        CFStringInlineBuffer buf;
        Boolean success;
        CFStringInitInlineBuffer((CFStringRef)value, &buf, CFRangeMake(0, CFStringGetLength((CFStringRef)value)));
        success = __CFStringScanInteger(&buf, NULL, &charIndex, false, &intVal);
        *keyExistsAndHasValidFormat = (success && charIndex == CFStringGetLength((CFStringRef)value));
        result = (*keyExistsAndHasValidFormat) ? intVal : 0;
    } else if (typeID == CFNumberGetTypeID()) {
        *keyExistsAndHasValidFormat = !CFNumberIsFloatType((CFNumberRef)value);
        if (*keyExistsAndHasValidFormat) {
            CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &result);
        } else {
            result = 0;
        }
    } else {
        // Unknown type
        result = 0;
        *keyExistsAndHasValidFormat = false;
    }
    CFRelease(value);
    return result;
}

Boolean CFPreferencesGetAppBooleanValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    return CFPreferencesAppBooleanValue(key, appName, keyExistsAndHasValidFormat);
}

CFIndex CFPreferencesGetAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);
    return CFPreferencesAppIntegerValue(key, appName, keyExistsAndHasValidFormat);
}

void CFPreferencesSetAppValue(CFStringRef key, CFTypeRef value, CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    CFAssert1(key != NULL, __kCFLogAssertion, "%s(): Cannot access preferences with a NULL key", __PRETTY_FUNCTION__);

    standardPrefs = _CFStandardApplicationPreferences(appName);
    if (standardPrefs) {
        if (value) _CFApplicationPreferencesSet(standardPrefs, key, value);
        else _CFApplicationPreferencesRemove(standardPrefs, key);
    }
}


static CFLock_t __CFApplicationPreferencesLock = CFLockInit; // Locks access to __CFStandardUserPreferences
static CFMutableDictionaryRef __CFStandardUserPreferences = NULL; // Mutable dictionary; keys are app names, values are _CFApplicationPreferences 

Boolean CFPreferencesAppSynchronize(CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    Boolean result;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    
    // Do not call _CFStandardApplicationPreferences(), as we do not want to create the preferences only to synchronize
    __CFLock(&__CFApplicationPreferencesLock);
    if (__CFStandardUserPreferences)  {
        standardPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
    } else {
        standardPrefs = NULL;
    }

    result = standardPrefs ? _CFApplicationPreferencesSynchronizeNoLock(standardPrefs) : _CFSynchronizeDomainCache();
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

void CFPreferencesFlushCaches(void) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    __CFLock(&__CFApplicationPreferencesLock);
    if (__CFStandardUserPreferences)  {
        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
        if (count < 32) {
            prefsArray = prefsBuf;
        } else {
            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
        }
        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);

        __CFUnlock(&__CFApplicationPreferencesLock);
        // DeallocateApplicationPreferences needs the lock
        for (idx = 0; idx < count; idx ++) {
            _CFApplicationPreferences *appPrefs = prefsArray[idx];
            _CFApplicationPreferencesSynchronize(appPrefs);
            _CFDeallocateApplicationPreferences(appPrefs);
        }
        __CFLock(&__CFApplicationPreferencesLock);

        CFRelease(__CFStandardUserPreferences);
        __CFStandardUserPreferences = NULL;
        if(prefsArray != prefsBuf) CFAllocatorDeallocate(alloc, prefsArray);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
    _CFPreferencesPurgeDomainCache();
}

// quick message to indicate that the given domain has changed, and we should go through and invalidate any dictReps that involve this domain.
void _CFApplicationPreferencesDomainHasChanged(CFPreferencesDomainRef changedDomain) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    __CFLock(&__CFApplicationPreferencesLock);
    if(__CFStandardUserPreferences) {  // only grovel over the prefs if there's something there to grovel
        _CFApplicationPreferences **prefsArray, *prefsBuf[32];
        CFIndex idx, count = CFDictionaryGetCount(__CFStandardUserPreferences);
        if(count < 32) {
            prefsArray = prefsBuf;
        } else {
            prefsArray = (_CFApplicationPreferences **)CFAllocatorAllocate(alloc, count * sizeof(_CFApplicationPreferences *), 0);
        }
        CFDictionaryGetKeysAndValues(__CFStandardUserPreferences, NULL, (const void **)prefsArray);
        // For this operation, giving up the lock is the last thing we want to do, so use the modified flavor of _CFApplicationPreferencesContainsDomain
        for(idx = 0; idx < count; idx++) {
            _CFApplicationPreferences *appPrefs = prefsArray[idx];
            if(_CFApplicationPreferencesContainsDomainNoLock(appPrefs, changedDomain)) {
                updateDictRep(appPrefs);
            }
        }
        if(prefsArray != prefsBuf) CFAllocatorDeallocate(alloc, prefsArray);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}


// Begin ported code from NSUserDefaults.m


static void updateDictRep(_CFApplicationPreferences *self) {
    if (self->_dictRep) {
        CFRelease(self->_dictRep);
        self->_dictRep = NULL;
    }
}

static void __addKeysAndValues(const void *key, const void *value, void *context) {
    CFDictionarySetValue((CFMutableDictionaryRef)context, key, value);
}

static CFMutableDictionaryRef computeDictRep(_CFApplicationPreferences *self, Boolean skipC0C0A) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    CFMutableArrayRef searchList = self->_search;
    CFIndex idx;
    CFIndex cnt = CFArrayGetCount(searchList);
    CFDictionaryRef subdomainDict;
    CFMutableDictionaryRef dictRep;
    
    dictRep = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
    _CFDictionarySetCapacity(dictRep, 260);	// avoid lots of rehashing
    
    // For each subdomain triplet in the domain, iterate over dictionaries, adding them if necessary to the dictRep
    for (idx = cnt; idx--;) {
        CFPreferencesDomainRef domain = (CFPreferencesDomainRef)CFArrayGetValueAtIndex(searchList, idx);

        if (!domain) continue;

        subdomainDict = _CFPreferencesDomainDeepCopyDictionary(domain);
        if (subdomainDict) {
            CFDictionaryApplyFunction(subdomainDict, __addKeysAndValues, dictRep);
            CFRelease(subdomainDict);
        }
    }
    return dictRep;
}

CFTypeRef _CFApplicationPreferencesSearchDownToDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef stopper, CFStringRef key) {
    return NULL;
}


void _CFApplicationPreferencesUpdate(_CFApplicationPreferences *self) {
    __CFLock(&__CFApplicationPreferencesLock);
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

CF_EXPORT CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self);

CF_PRIVATE CFDictionaryRef __CFApplicationPreferencesCopyCurrentState(void) {
    _CFApplicationPreferences *self = _CFStandardApplicationPreferences(kCFPreferencesCurrentApplication);
    CFDictionaryRef result = _CFApplicationPreferencesCopyRepresentation(self);
    return result;
}

// CACHING here - we will only return a value as current as the last time computeDictRep() was called
static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFTypeRef result;
    __CFLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    result = (self->_dictRep) ? (CFTypeRef )CFDictionaryGetValue(self->_dictRep, defaultName) : NULL;
    if (result) {
        CFRetain(result);
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}


void _CFApplicationPreferencesSet(_CFApplicationPreferences *self, CFStringRef defaultName, CFTypeRef value) {
    CFPreferencesDomainRef applicationDomain;

    __CFLock(&__CFApplicationPreferencesLock);
    applicationDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(applicationDomain) {
        _CFPreferencesDomainSet(applicationDomain, defaultName, value);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), applicationDomain)) {
            // Expensive; can't we just check the relevant value throughout the appropriate sets of domains? -- REW, 7/19/99
            updateDictRep(self);
        }
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void _CFApplicationPreferencesRemove(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFPreferencesDomainRef appDomain;

    __CFLock(&__CFApplicationPreferencesLock);
    appDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(appDomain) {
        _CFPreferencesDomainSet(appDomain, defaultName, NULL);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), appDomain)) {
            // If key exists, it will be in the _dictRep (but possibly overridden)
            updateDictRep(self);
        }
    }
    __CFUnlock(&__CFApplicationPreferencesLock);
}

static Boolean _CFApplicationPreferencesSynchronizeNoLock(_CFApplicationPreferences *self) {
    Boolean success = _CFSynchronizeDomainCache();
    updateDictRep(self);
    return success;
}

Boolean _CFApplicationPreferencesSynchronize(_CFApplicationPreferences *self) {
    Boolean result;
    __CFLock(&__CFApplicationPreferencesLock);
    result = _CFApplicationPreferencesSynchronizeNoLock(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

// appName should not be kCFPreferencesCurrentApplication going in to this call
_CFApplicationPreferences *_CFApplicationPreferencesCreateWithUser(CFStringRef userName, CFStringRef appName) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    _CFApplicationPreferences *self = (_CFApplicationPreferences*)CFAllocatorAllocate(alloc, sizeof(_CFApplicationPreferences), 0);
    if (self) {
        self->_dictRep = NULL;
        self->_appName = (CFStringRef)CFRetain(appName);
        self->_search = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
        if (!self->_search) {
            CFAllocatorDeallocate(alloc, self);
            CFRelease(appName);
            self = NULL;
        }
    }
    return self;
}

// Do NOT release the domain after adding it to the array; domain_expression should not return a retained object  -- REW, 8/26/99 
#define ADD_DOMAIN(domain_expression) domain = domain_expression; if (domain) {CFArrayAppendValue(search, domain);}
void _CFApplicationPreferencesSetStandardSearchList(_CFApplicationPreferences *appPreferences) {
    /* Here is how the domains end up in priority order in a search list.  Only a subset of these are setup by default.
	argument domain
	this app, this user, managed
	this app, any user, managed
        this app, this user, this host
        this app, this user, any host (AppDomain)
	suiteN, this user, this host
	suiteN, this user, any host
        ...
	suite0, this user, this host
	suite0, this user, any host
        any app, this user, this host
        any app, this user, any host (GlobalDomain)
        NSUserDefaults backwards-compat ICU domain
        this app, any user, this host
        this app, any user, any host
	suiteN, any user, this host
	suiteN, any user, any host
        ...
	suite0, any user, this host
	suite0, any user, any host
        any app, any user, this host
        any app, any user, any host
	registration domain
    */
    CFPreferencesDomainRef domain;
    CFMutableArrayRef search = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
    if (!search) {
        // couldn't allocate memory!
        return;
    }

    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(appPreferences->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesCurrentHost));
    ADD_DOMAIN(_CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesAnyUser, kCFPreferencesAnyHost));

    _CFApplicationPreferencesSetSearchList(appPreferences, search);
    CFRelease(search);
}
#undef ADD_DOMAIN


CF_PRIVATE _CFApplicationPreferences *_CFStandardApplicationPreferences(CFStringRef appName) {
    _CFApplicationPreferences *appPreferences;
//    CFAssert(appName != kCFPreferencesAnyApplication, __kCFLogAssertion, "Cannot use any of the CFPreferences...App... functions with an appName of kCFPreferencesAnyApplication");
    __CFLock(&__CFApplicationPreferencesLock);
    if (!__CFStandardUserPreferences)  {
        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, & kCFTypeDictionaryKeyCallBacks, NULL);
    }
    if (!__CFStandardUserPreferences) {
        // Couldn't create
        __CFUnlock(&__CFApplicationPreferencesLock);
        return NULL;
    }
    if ((appPreferences = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName)) == NULL ) {
        appPreferences = _CFApplicationPreferencesCreateWithUser(kCFPreferencesCurrentUser, appName);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPreferences);
        __CFUnlock(&__CFApplicationPreferencesLock);
        _CFApplicationPreferencesSetStandardSearchList(appPreferences);
    } else {
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    return appPreferences;
}

// Exclusively for Foundation's use
void _CFApplicationPreferencesSetCacheForApp(_CFApplicationPreferences *appPrefs, CFStringRef appName) {
    __CFLock(&__CFApplicationPreferencesLock);
    if (!__CFStandardUserPreferences) {
        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFUnlock(&__CFApplicationPreferencesLock);
    } else {
        _CFApplicationPreferences *oldPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFUnlock(&__CFApplicationPreferencesLock);
        if (oldPrefs) {
            _CFDeallocateApplicationPreferences(oldPrefs);
        }
    }
}


void _CFDeallocateApplicationPreferences(_CFApplicationPreferences *self) {
    CFAllocatorRef alloc = __CFPreferencesAllocator();
    _CFApplicationPreferences *cachedPrefs = NULL;
    __CFLock(&__CFApplicationPreferencesLock);

    // Get us out of the cache before destroying!
    if (__CFStandardUserPreferences)  {
        cachedPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, self->_appName);
    }
    if (cachedPrefs == self) {
        CFDictionaryRemoveValue(__CFStandardUserPreferences, self->_appName);
    }
    
    if (self->_dictRep) CFRelease(self->_dictRep);
    CFRelease(self->_search);
    CFRelease(self->_appName);
    CFAllocatorDeallocate(alloc, self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}


CF_EXPORT
CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self) {
    CFDictionaryRef dict;
    __CFLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    if (self->_dictRep) {
        CFRetain(self->_dictRep);
    }
    dict = self->_dictRep;
    __CFUnlock(&__CFApplicationPreferencesLock);
    return dict;
}

static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList) {
    CFIndex idx, count;
    __CFLock(&__CFApplicationPreferencesLock);
    CFArrayRemoveAllValues(self->_search);
    count = CFArrayGetCount(newSearchList);
    for (idx = 0; idx < count; idx ++) {
        CFArrayAppendValue(self->_search, CFArrayGetValueAtIndex(newSearchList, idx));
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void CFPreferencesAddSuitePreferencesToApp(CFStringRef appName, CFStringRef suiteName) {
    _CFApplicationPreferences *appPrefs;
    
    appPrefs = _CFStandardApplicationPreferences(appName);
    _CFApplicationPreferencesAddSuitePreferences(appPrefs, suiteName);
}

void _CFApplicationPreferencesAddSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
    CFPreferencesDomainRef domain; 
    CFIndex idx;
    CFRange range;

    // Find where to insert the new suite
    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    range.location = 0;
    range.length = CFArrayGetCount(appPrefs->_search);
    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
    __CFUnlock(&__CFApplicationPreferencesLock);
    idx ++; // We want just below the app domain.  Coincidentally, this gives us the top of the list if the app domain has been removed.
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
        range.length ++;
    }
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
        range.length ++;
    }

    // Now the AnyUser domains
    domain = _CFPreferencesStandardDomain(appPrefs->_appName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
    if (idx == kCFNotFound) {
        // Someone blew away the app domain. For the any user case, we look for right below the global domain
        domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
        idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
        if (idx == kCFNotFound) {
            // Try the "any host" choice
            domain = _CFPreferencesStandardDomain(kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
            idx = domain ? CFArrayGetFirstIndexOfValue(appPrefs->_search, range, domain) : kCFNotFound;
            if (idx == kCFNotFound) {
                // We give up; put the new domains at the bottom
                idx = CFArrayGetCount(appPrefs->_search) - 1;
            }
        }
    }
    idx ++;
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
    if (domain) {
        __CFLock(&__CFApplicationPreferencesLock);
        CFArrayInsertValueAtIndex(appPrefs->_search, idx, domain);
        __CFUnlock(&__CFApplicationPreferencesLock);
    }
    __CFLock(&__CFApplicationPreferencesLock);
    updateDictRep(appPrefs);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

void CFPreferencesRemoveSuitePreferencesFromApp(CFStringRef appName, CFStringRef suiteName) {
    _CFApplicationPreferences *appPrefs;

    appPrefs = _CFStandardApplicationPreferences(appName);
    
    _CFApplicationPreferencesRemoveSuitePreferences(appPrefs, suiteName);
}

void _CFApplicationPreferencesRemoveSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
    CFPreferencesDomainRef domain;

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
    __CFUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
}

void _CFApplicationPreferencesAddDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain, Boolean addAtTop) {
    __CFLock(&__CFApplicationPreferencesLock);
    if (addAtTop) {
        CFArrayInsertValueAtIndex(self->_search, 0, domain);
    } else {
        CFArrayAppendValue(self->_search, domain);
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}

Boolean _CFApplicationPreferencesContainsDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    Boolean result;

    if (!domain) {
        return false;
    }

    __CFLock(&__CFApplicationPreferencesLock);
    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
    __CFUnlock(&__CFApplicationPreferencesLock);
    return result;
}

Boolean _CFApplicationPreferencesContainsDomainNoLock(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    Boolean result;
    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
    return result;
}

void _CFApplicationPreferencesRemoveDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    CFIndex idx;
    CFRange range;
    __CFLock(&__CFApplicationPreferencesLock);
    range.location = 0;
    range.length = CFArrayGetCount(self->_search);
    while ((idx = CFArrayGetFirstIndexOfValue(self->_search, range, domain)) != kCFNotFound) {
        CFArrayRemoveValueAtIndex(self->_search, idx);
        range.location = idx;
        range.length  = range.length - idx - 1;
    }
    updateDictRep(self);
    __CFUnlock(&__CFApplicationPreferencesLock);
}
