/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFPlugIn_Factory.c
	Copyright (c) 1999-2007 Apple Inc.  All rights reserved.
	Responsibility: Doug Davidson
*/

#include "CFBundle_Internal.h"
#include "CFInternal.h"

static CFSpinLock_t CFPlugInGlobalDataLock = CFSpinLockInit;
static CFMutableDictionaryRef _factoriesByFactoryID = NULL; /* Value is _CFPFactory */
static CFMutableDictionaryRef _factoriesByTypeID = NULL; /* Value is array of _CFPFactory */

static void _CFPFactoryAddToTable(_CFPFactory *factory) {
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByFactoryID == NULL) {
        CFDictionaryValueCallBacks _factoryDictValueCallbacks = {0, NULL, NULL, NULL, NULL};
        // Use default allocator
        _factoriesByFactoryID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &_factoryDictValueCallbacks);
    }
    CFDictionarySetValue(_factoriesByFactoryID, factory->_uuid, factory);
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}

static void _CFPFactoryRemoveFromTable(_CFPFactory *factory) {
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByFactoryID != NULL) {
        CFDictionaryRemoveValue(_factoriesByFactoryID, factory->_uuid);
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}

__private_extern__ _CFPFactory *_CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
    _CFPFactory *result = NULL;
    
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByFactoryID != NULL) {
        result = (_CFPFactory *)CFDictionaryGetValue(_factoriesByFactoryID, factoryID);
        if (result && result->_enabled != enabled) {
            result = NULL;
        }
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
    return result;
}

static void _CFPFactoryDeallocate(_CFPFactory *factory) {
    CFAllocatorRef allocator = factory->_allocator;
    SInt32 c;
    
    _CFPFactoryRemoveFromTable(factory);

    if (factory->_plugIn) {
        _CFPlugInRemoveFactory(factory->_plugIn, factory);
    }

    /* Remove all types for this factory. */
    c = CFArrayGetCount(factory->_types);
    while (c--) {
        _CFPFactoryRemoveType(factory, (CFUUIDRef)CFArrayGetValueAtIndex(factory->_types, c));
    }
    CFRelease(factory->_types);

    if (factory->_funcName) {
        CFRelease(factory->_funcName);
    }

    if (factory->_uuid) {
        CFRelease(factory->_uuid);
    }

    CFAllocatorDeallocate(allocator, factory);
    CFRelease(allocator);
}

static _CFPFactory *_CFPFactoryCommonCreate(CFAllocatorRef allocator, CFUUIDRef factoryID) {
    _CFPFactory *factory;
    UInt32 size;
    size = sizeof(_CFPFactory);
    allocator = ((NULL == allocator) ? (CFAllocatorRef)CFRetain(__CFGetDefaultAllocator()) : (CFAllocatorRef)CFRetain(allocator));
    factory = (_CFPFactory *)CFAllocatorAllocate(allocator, size, 0);
    if (NULL == factory) {
        CFRelease(allocator);
        return NULL;
    }

    factory->_allocator = allocator;

    factory->_uuid = (CFUUIDRef)CFRetain(factoryID);
    factory->_enabled = true;
    factory->_instanceCount = 0;

    _CFPFactoryAddToTable(factory);

    factory->_types = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);

    return factory;
}

__private_extern__ _CFPFactory *_CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
    _CFPFactory *factory = _CFPFactoryCommonCreate(allocator, factoryID);

    factory->_func = func;
    factory->_plugIn = NULL;
    factory->_funcName = NULL;

    return factory;
}

__private_extern__ _CFPFactory *_CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
    _CFPFactory *factory = _CFPFactoryCommonCreate(allocator, factoryID);

    factory->_func = NULL;
    factory->_plugIn = plugIn;
    if (plugIn) {
        _CFPlugInAddFactory(plugIn, factory);
    }
    factory->_funcName = (funcName ? (CFStringRef)CFStringCreateCopy(allocator, funcName) : NULL);

    return factory;
}

__private_extern__ CFUUIDRef _CFPFactoryGetFactoryID(_CFPFactory *factory) {
    return factory->_uuid;
}

__private_extern__ CFPlugInRef _CFPFactoryGetPlugIn(_CFPFactory *factory) {
    return factory->_plugIn;
}

__private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactory *factory, CFUUIDRef typeID) {
    void *result = NULL;
    if (factory->_enabled) {
        if (factory->_func == NULL) {
            factory->_func = (CFPlugInFactoryFunction)CFBundleGetFunctionPointerForName(factory->_plugIn, factory->_funcName);
            if (factory->_func == NULL) {
                CFLog(__kCFLogPlugIn, CFSTR("Cannot find function pointer %@ for factory %@ in %@"), factory->_funcName, factory->_uuid, factory->_plugIn);
            }
#if BINARY_SUPPORT_CFM
            else {
                // return values from CFBundleGetFunctionPointerForName will always be dyld, but
                // we must force-fault them because pointers to glue code do not fault correctly
                factory->_func = (void *)((uint32_t)(factory->_func) | 0x1);
            }
#endif /* BINARY_SUPPORT_CFM */
        }
        if (factory->_func) {
            // UPPGOOP
            FAULT_CALLBACK((void **)&(factory->_func));
            result = (void *)INVOKE_CALLBACK2(factory->_func, allocator, typeID);
        }
    } else {
        CFLog(__kCFLogPlugIn, CFSTR("Factory %@ is disabled"), factory->_uuid);
    }
    return result;
}

__private_extern__ void _CFPFactoryDisable(_CFPFactory *factory) {
    factory->_enabled = false;
    if (factory->_instanceCount == 0) {
        _CFPFactoryDeallocate(factory);
    }
}

__private_extern__ Boolean _CFPFactoryIsEnabled(_CFPFactory *factory) {
    return factory->_enabled;
}

__private_extern__ void _CFPFactoryFlushFunctionCache(_CFPFactory *factory) {
    /* MF:!!! Assert that this factory belongs to a plugIn. */
    /* This is called by the factory's plugIn when the plugIn unloads its code. */
    factory->_func = NULL;
}

__private_extern__ void _CFPFactoryAddType(_CFPFactory *factory, CFUUIDRef typeID) {
    CFMutableArrayRef array;
    
    /* Add the type to the factory's type list */
    CFArrayAppendValue(factory->_types, typeID);

    /* Add the factory to the type's array of factories */
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByTypeID == NULL) {
        // Create this from default allocator
        _factoriesByTypeID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
    if (array == NULL) {
        CFArrayCallBacks _factoryArrayCallbacks = {0, NULL, NULL, NULL, NULL};
        // Create this from default allocator
        array = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &_factoryArrayCallbacks);
        CFDictionarySetValue(_factoriesByTypeID, typeID, array);
        CFRelease(array);
    }
    CFArrayAppendValue(array, factory);
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}

__private_extern__ void _CFPFactoryRemoveType(_CFPFactory *factory, CFUUIDRef typeID) {
    /* Remove it from the factory's type list */
    SInt32 idx;

    idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID);
    if (idx >=0) {
        CFArrayRemoveValueAtIndex(factory->_types, idx);
    }

    /* Remove the factory from the type's list of factories */
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByTypeID != NULL) {
        CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
        if (array != NULL) {
            idx = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), factory);
            if (idx >=0) {
                CFArrayRemoveValueAtIndex(array, idx);
                if (CFArrayGetCount(array) == 0) {
                    CFDictionaryRemoveValue(_factoriesByTypeID, typeID);
                }
            }
        }
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}

__private_extern__ Boolean _CFPFactorySupportsType(_CFPFactory *factory, CFUUIDRef typeID) {
    SInt32 idx;

    idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID);
    return ((idx >= 0) ? true : false);
}

__private_extern__ CFArrayRef _CFPFactoryFindForType(CFUUIDRef typeID) {
    CFArrayRef result = NULL;

    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByTypeID != NULL) {
        result = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);

    return result;
}

/* These methods are called by CFPlugInInstance when an instance is created or destroyed.  If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */
__private_extern__ void _CFPFactoryAddInstance(_CFPFactory *factory) {
    /* MF:!!! Assert that factory is enabled. */
    factory->_instanceCount++;
    if (factory->_plugIn) {
        _CFPlugInAddPlugInInstance(factory->_plugIn);
    }
}

__private_extern__ void _CFPFactoryRemoveInstance(_CFPFactory *factory) {
    /* MF:!!! Assert that _instanceCount > 0. */
    factory->_instanceCount--;
    if (factory->_plugIn) {
        _CFPlugInRemovePlugInInstance(factory->_plugIn);
    }
    if ((factory->_instanceCount == 0) && (!factory->_enabled)) {
        _CFPFactoryDeallocate(factory);
    }
}
